From 2208346bff099670f2ab8608f2f774caa76d867e Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 16 九月 2025 14:12:06 +0800
Subject: [PATCH] 标准作业指导

---
 src/pages/index.vue                         |   10 
 src/pages.json                              |    7 
 src/pages/equipmentManagement/sop/index.vue | 1380 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1,397 insertions(+), 0 deletions(-)

diff --git a/src/pages.json b/src/pages.json
index 8eda358..cccffcb 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -371,6 +371,13 @@
         "navigationBarTitleText": "鏅鸿兘娲惧崟",
         "navigationStyle": "custom"
       }
+    },
+    {
+      "path": "pages/equipmentManagement/sop/index",
+      "style": {
+        "navigationBarTitleText": "鏍囧噯浣滀笟鎸囧",
+        "navigationStyle": "custom"
+      }
     }
   ],
   "subPackages": [
diff --git a/src/pages/equipmentManagement/sop/index.vue b/src/pages/equipmentManagement/sop/index.vue
new file mode 100644
index 0000000..c577d3b
--- /dev/null
+++ b/src/pages/equipmentManagement/sop/index.vue
@@ -0,0 +1,1380 @@
+<template>
+  <view class="sales-account">
+    <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+    <PageHeader title="鏍囧噯浣滀笟鎸囧" @back="goBack" />
+    
+    <!-- 浠诲姟淇℃伅鍗$墖 -->
+    <view class="task-info-card">
+      <view class="task-header">
+        <view class="task-left">
+          <view class="task-icon">
+            <up-icon name="file-text" size="20" color="#ffffff"></up-icon>
+          </view>
+          <view class="task-details">
+            <text class="task-title">{{ currentTask.deviceName }}</text>
+            <text class="task-subtitle">{{ currentTask.taskType }} - {{ currentTask.priority }}</text>
+          </view>
+        </view>
+        <view class="task-status">
+          <u-tag :type="getStatusType(currentTask.status)" size="small">
+            {{ getStatusText(currentTask.status) }}
+          </u-tag>
+        </view>
+      </view>
+      
+      <view class="task-meta">
+        <view class="meta-item">
+          <text class="meta-label">璁惧缂栧彿:</text>
+          <text class="meta-value">{{ currentTask.deviceCode }}</text>
+        </view>
+        <view class="meta-item">
+          <text class="meta-label">鏁呴殰鎻忚堪:</text>
+          <text class="meta-value">{{ currentTask.faultDescription }}</text>
+        </view>
+        <view class="meta-item">
+          <text class="meta-label">棰勮宸ユ椂:</text>
+          <text class="meta-value">{{ currentTask.estimatedHours }}灏忔椂</text>
+        </view>
+      </view>
+    </view>
+    
+    <!-- 鍔熻兘瀵艰埅 -->
+    <view class="nav-tabs">
+      <view 
+        v-for="(tab, index) in tabs" 
+        :key="index"
+        class="nav-tab"
+        :class="{ active: activeTab === tab.key }"
+        @click="switchTab(tab.key)"
+      >
+        <up-icon :name="tab.icon" size="18" :color="activeTab === tab.key ? '#2979ff' : '#666'"></up-icon>
+        <text class="tab-text" :class="{ active: activeTab === tab.key }">{{ tab.label }}</text>
+      </view>
+    </view>
+    
+    <!-- SOP鏍囧噯浣滀笟绋嬪簭 -->
+    <view v-if="activeTab === 'sop'" class="content-section">
+      <view class="section-header">
+        <text class="section-title">鏍囧噯浣滀笟绋嬪簭</text>
+        <view class="progress-info">
+          <text class="progress-text">{{ completedSteps }}/{{ sopSteps.length }}</text>
+          <up-icon name="checkmark-circle" size="16" color="#4caf50" v-if="completedSteps === sopSteps.length"></up-icon>
+        </view>
+      </view>
+      
+      <view class="sop-steps">
+        <view 
+          v-for="(step, index) in sopSteps" 
+          :key="step.id"
+          class="sop-step"
+          :class="{ completed: step.completed, current: currentStepIndex === index }"
+        >
+          <view class="step-header" @click="toggleStep(index)">
+            <view class="step-number">
+              <text v-if="!step.completed" class="step-num">{{ index + 1 }}</text>
+              <up-icon v-else name="checkmark" size="14" color="#ffffff"></up-icon>
+            </view>
+            <view class="step-content">
+              <text class="step-title">{{ step.title }}</text>
+              <text class="step-duration">棰勮{{ step.duration }}鍒嗛挓</text>
+            </view>
+            <view class="step-toggle">
+              <up-icon 
+                :name="step.expanded ? 'arrow-up' : 'arrow-down'" 
+                size="16" 
+                color="#999"
+              ></up-icon>
+            </view>
+          </view>
+          
+          <view v-if="step.expanded" class="step-details">
+            <view class="step-description">
+              <text class="desc-text">{{ step.description }}</text>
+            </view>
+            
+            <view v-if="step.warnings.length > 0" class="step-warnings">
+              <text class="warning-title">鈿狅笍 娉ㄦ剰浜嬮」</text>
+              <view v-for="warning in step.warnings" :key="warning" class="warning-item">
+                <text class="warning-text">鈥� {{ warning }}</text>
+              </view>
+            </view>
+            
+            <view v-if="step.tools.length > 0" class="step-tools">
+              <text class="tools-title">馃敡 鎵�闇�宸ュ叿</text>
+              <view class="tools-list">
+                <u-tag 
+                  v-for="tool in step.tools" 
+                  :key="tool"
+                  type="info"
+                  size="mini"
+                  class="tool-tag"
+                >
+                  {{ tool }}
+                </u-tag>
+              </view>
+            </view>
+            
+            <view class="step-actions">
+              <u-button 
+                v-if="!step.completed"
+                type="success"
+                size="small"
+                @click="completeStep(index)"
+              >
+                瀹屾垚姝ゆ楠�
+              </u-button>
+              <u-button 
+                v-else
+                type="info"
+                size="small"
+                plain
+                @click="uncompleteStep(index)"
+              >
+                鍙栨秷瀹屾垚
+              </u-button>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+    
+    <!-- 閰嶄欢娓呭崟 -->
+    <view v-if="activeTab === 'parts'" class="content-section">
+      <view class="section-header">
+        <text class="section-title">閰嶄欢娓呭崟</text>
+        <view class="parts-summary">
+          <text class="summary-text">鍏眥{ partsList.length }}椤归厤浠�</text>
+        </view>
+      </view>
+      
+      <view class="parts-list">
+        <view v-for="part in partsList" :key="part.id" class="part-item">
+          <view class="part-header">
+            <view class="part-info">
+              <text class="part-name">{{ part.name }}</text>
+              <text class="part-spec">{{ part.specification }}</text>
+            </view>
+            <view class="part-status">
+              <u-tag 
+                :type="part.available ? 'success' : 'error'"
+                size="mini"
+              >
+                {{ part.available ? '搴撳瓨鍏呰冻' : '搴撳瓨涓嶈冻' }}
+              </u-tag>
+            </view>
+          </view>
+          
+          <view class="part-details">
+            <view class="detail-row">
+              <text class="detail-label">閰嶄欢缂栧彿:</text>
+              <text class="detail-value">{{ part.partNumber }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">闇�瑕佹暟閲�:</text>
+              <text class="detail-value">{{ part.requiredQuantity }}{{ part.unit }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">搴撳瓨鏁伴噺:</text>
+              <text class="detail-value" :class="{ danger: !part.available }">
+                {{ part.stockQuantity }}{{ part.unit }}
+              </text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">瀛樻斁浣嶇疆:</text>
+              <text class="detail-value">{{ part.location }}</text>
+            </view>
+          </view>
+          
+          <view class="part-actions">
+            <u-button 
+              type="primary"
+              size="small"
+              plain
+              @click="requestPart(part)"
+              :disabled="part.available"
+            >
+              鐢宠閰嶄欢
+            </u-button>
+            <u-button 
+              type="info"
+              size="small"
+              plain
+              @click="viewPartDetail(part)"
+            >
+              鏌ョ湅璇︽儏
+            </u-button>
+          </view>
+        </view>
+      </view>
+    </view>
+    
+    <!-- 瀹夊叏鎻愮ず -->
+    <view v-if="activeTab === 'safety'" class="content-section">
+      <view class="section-header">
+        <text class="section-title">瀹夊叏鎻愮ず</text>
+        <view class="safety-level">
+          <u-tag :type="getSafetyLevelType(safetyInfo.level)" size="small">
+            {{ safetyInfo.level }}
+          </u-tag>
+        </view>
+      </view>
+      
+      <!-- 瀹夊叏绛夌骇璇存槑 -->
+      <view class="safety-overview">
+        <view class="safety-icon">
+          <up-icon name="warning" size="24" color="#ff6b35"></up-icon>
+        </view>
+        <view class="safety-content">
+          <text class="safety-title">{{ safetyInfo.title }}</text>
+          <text class="safety-desc">{{ safetyInfo.description }}</text>
+        </view>
+      </view>
+      
+      <!-- 涓汉闃叉姢璁惧 -->
+      <view class="safety-section">
+        <text class="safety-section-title">馃洝锔� 涓汉闃叉姢璁惧</text>
+        <view class="ppe-list">
+          <view v-for="ppe in safetyInfo.ppe" :key="ppe.name" class="ppe-item">
+            <view class="ppe-icon">
+              <text class="ppe-emoji">{{ ppe.icon }}</text>
+            </view>
+            <view class="ppe-info">
+              <text class="ppe-name">{{ ppe.name }}</text>
+              <text class="ppe-desc">{{ ppe.description }}</text>
+            </view>
+            <view class="ppe-status">
+              <up-icon 
+                :name="ppe.checked ? 'checkmark-circle' : 'close-circle'" 
+                :color="ppe.checked ? '#4caf50' : '#ccc'"
+                size="20"
+                @click="togglePPE(ppe)"
+              ></up-icon>
+            </view>
+          </view>
+        </view>
+      </view>
+      
+      <!-- 瀹夊叏娉ㄦ剰浜嬮」 -->
+      <view class="safety-section">
+        <text class="safety-section-title">鈿狅笍 瀹夊叏娉ㄦ剰浜嬮」</text>
+        <view class="safety-warnings">
+          <view v-for="(warning, index) in safetyInfo.warnings" :key="index" class="safety-warning">
+            <view class="warning-icon">
+              <up-icon name="info-circle" size="16" color="#ff6b35"></up-icon>
+            </view>
+            <text class="warning-content">{{ warning }}</text>
+          </view>
+        </view>
+      </view>
+      
+      <!-- 搴旀�ュ鐞� -->
+      <view class="safety-section">
+        <text class="safety-section-title">馃毃 搴旀�ュ鐞�</text>
+        <view class="emergency-procedures">
+          <view v-for="(procedure, index) in safetyInfo.emergencyProcedures" :key="index" class="emergency-item">
+            <view class="emergency-header">
+              <text class="emergency-title">{{ procedure.situation }}</text>
+            </view>
+            <view class="emergency-steps">
+              <view v-for="(step, stepIndex) in procedure.steps" :key="stepIndex" class="emergency-step">
+                <text class="step-number">{{ stepIndex + 1 }}.</text>
+                <text class="step-content">{{ step }}</text>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+      
+      <!-- 瀹夊叏纭 -->
+      <view class="safety-confirmation">
+        <view class="confirmation-header">
+          <up-icon name="checkmark-circle" size="20" color="#4caf50"></up-icon>
+          <text class="confirmation-title">瀹夊叏纭</text>
+        </view>
+        <view class="confirmation-content">
+          <text class="confirmation-text">鎴戝凡浠旂粏闃呰骞剁悊瑙d互涓婂畨鍏ㄦ彁绀猴紝灏嗕弗鏍兼寜鐓у畨鍏ㄨ绋嬭繘琛屼綔涓�</text>
+        </view>
+        <view class="confirmation-actions">
+          <u-button 
+            type="success"
+            @click="confirmSafety"
+            :disabled="safetyConfirmed"
+          >
+            {{ safetyConfirmed ? '宸茬‘璁�' : '纭骞跺紑濮嬩綔涓�' }}
+          </u-button>
+        </view>
+      </view>
+    </view>
+    
+    <!-- 搴曢儴鎿嶄綔鎸夐挳 -->
+    <view class="bottom-actions">
+      <u-button 
+        type="primary"
+        size="large"
+        @click="startWork"
+        :disabled="!canStartWork"
+      >
+        寮�濮嬩綔涓�
+      </u-button>
+      <u-button 
+        type="info"
+        size="large"
+        plain
+        @click="saveProgress"
+      >
+        淇濆瓨杩涘害
+      </u-button>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref, computed, onMounted } from 'vue'
+import { onShow } from '@dcloudio/uni-app'
+import PageHeader from '@/components/PageHeader.vue'
+
+const showToast = (message) => {
+  uni.showToast({
+    title: message,
+    icon: 'none'
+  })
+}
+
+// 褰撳墠浠诲姟淇℃伅
+const currentTask = ref({
+  id: 1,
+  deviceName: '鏁版帶杞﹀簥CK6140',
+  deviceCode: 'CNC-001',
+  taskType: '璁惧缁翠慨',
+  priority: '绱ф��',
+  status: 'in_progress',
+  faultDescription: '涓昏酱寮傚搷锛屽垏鍓婄簿搴︿笅闄�',
+  estimatedHours: 4,
+  assignedTechnician: '鏉庡笀鍌�',
+  startTime: '2024-01-15 09:00:00'
+})
+
+// 瀵艰埅鏍囩
+const tabs = ref([
+  { key: 'sop', label: 'SOP', icon: 'list' },
+  { key: 'parts', label: '閰嶄欢', icon: 'grid' },
+  { key: 'safety', label: '瀹夊叏', icon: 'info' }
+])
+
+const activeTab = ref('sop')
+
+// SOP姝ラ鏁版嵁
+const sopSteps = ref([
+  {
+    id: 1,
+    title: '瀹夊叏鍑嗗涓庤澶囨柇鐢�',
+    description: '纭繚璁惧瀹屽叏鏂數锛屾寕涓婂畨鍏ㄦ爣璇嗙墝锛岀┛鎴村ソ涓汉闃叉姢璁惧锛屾鏌ュ伐浣滅幆澧冨畨鍏ㄣ��',
+    duration: 10,
+    completed: false,
+    expanded: false,
+    warnings: [
+      '蹇呴』纭璁惧瀹屽叏鏂數鍚庢墠鑳借繘琛屽悗缁搷浣�',
+      '鎸備笂"姝e湪缁翠慨锛岀姝㈡搷浣�"鐨勫畨鍏ㄦ爣璇嗙墝',
+      '妫�鏌ュ懆鍥存槸鍚︽湁鍏朵粬浜哄憳锛岀‘淇濆畨鍏ㄨ窛绂�'
+    ],
+    tools: ['涓囩敤琛�', '瀹夊叏鏍囪瘑鐗�', '涓汉闃叉姢璁惧']
+  },
+  {
+    id: 2,
+    title: '鎷嗗嵏涓昏酱闃叉姢缃�',
+    description: '浣跨敤涓撶敤宸ュ叿灏忓績鎷嗗嵏涓昏酱闃叉姢缃╋紝娉ㄦ剰淇濇姢缃╃殑瀹屾暣鎬э紝閬垮厤鎹熷潖瀵嗗皝浠躲��',
+    duration: 15,
+    completed: false,
+    expanded: false,
+    warnings: [
+      '鎷嗗嵏鏃舵敞鎰忛槻鎶ょ僵閲嶉噺锛岄伩鍏嶆帀钀界牳浼�',
+      '瀵嗗皝浠跺鏄撹�佸寲锛屾媶鍗告椂瑕佹牸澶栧皬蹇�',
+      '璁板綍鎷嗗嵏椤哄簭锛屼究浜庡悗缁畨瑁�'
+    ],
+    tools: ['鍐呭叚瑙掓壋鎵�', '姗¤兌閿�', '瀵嗗皝鑳�']
+  },
+  {
+    id: 3,
+    title: '妫�鏌ヤ富杞磋酱鎵跨姸鎬�',
+    description: '浠旂粏妫�鏌ヤ富杞磋酱鎵跨殑纾ㄦ崯鎯呭喌锛屾祴閲忚酱鎵块棿闅欙紝妫�鏌ユ鼎婊戞补鐘舵�佸拰杞存壙搴х殑閰嶅悎鎯呭喌銆�',
+    duration: 25,
+    completed: false,
+    expanded: false,
+    warnings: [
+      '杞存壙妫�鏌ユ椂閬垮厤鐢ㄥ姏杩囧ぇ锛岄槻姝㈣繘涓�姝ユ崯鍧�',
+      '娉ㄦ剰瑙傚療杞存壙琛ㄩ潰鏄惁鏈夎绾规垨寮傚父纾ㄦ崯',
+      '娴嬮噺鏁版嵁瑕佸噯纭褰曪紝浣滀负鏇存崲渚濇嵁'
+    ],
+    tools: ['娓告爣鍗″昂', '鍗冨垎灏�', '鍐呯闀�', '娑︽粦娌规娴嬩华']
+  },
+  {
+    id: 4,
+    title: '鏇存崲鎹熷潖杞存壙',
+    description: '浣跨敤涓撶敤鎷夋嫈鍣ㄦ媶鍗告崯鍧忚酱鎵匡紝娓呮磥杞存壙搴э紝瀹夎鏂拌酱鎵挎椂纭繚閰嶅悎绮惧害銆�',
+    duration: 45,
+    completed: false,
+    expanded: false,
+    warnings: [
+      '杞存壙鎷嗗嵏鏃跺繀椤讳娇鐢ㄤ笓鐢ㄥ伐鍏凤紝閬垮厤鎹熷潖杞撮',
+      '鏂拌酱鎵垮畨瑁呭墠瑕佹鏌ュ瀷鍙疯鏍兼槸鍚︽纭�',
+      '瀹夎鏃惰鍧囧寑鐢ㄥ姏锛岀‘淇濊酱鎵垮畬鍏ㄥ氨浣�'
+    ],
+    tools: ['杞存壙鎷夋嫈鍣�', '杞存壙鍔犵儹鍣�', '涓撶敤瀹夎宸ュ叿', '娑︽粦鑴�']
+  },
+  {
+    id: 5,
+    title: '璋冩暣涓昏酱闂撮殭',
+    description: '鏍规嵁鎶�鏈姹傝皟鏁翠富杞磋酱鍚戝拰寰勫悜闂撮殭锛岀‘淇濅富杞磋繍杞钩绋筹紝绮惧害绗﹀悎鏍囧噯銆�',
+    duration: 30,
+    completed: false,
+    expanded: false,
+    warnings: [
+      '闂撮殭璋冩暣瑕佷弗鏍兼寜鐓ф妧鏈爣鍑嗘墽琛�',
+      '璋冩暣杩囩▼涓澶氭娴嬮噺纭',
+      '璋冩暣瀹屾垚鍚庤杩涜璇曡繍杞楠�'
+    ],
+    tools: ['鐧惧垎琛�', '濉炲昂', '鎵姏鎵虫墜']
+  },
+  {
+    id: 6,
+    title: '瀹夎闃叉姢缃╁苟娴嬭瘯',
+    description: '鎸夌収鎷嗗嵏鐨勯�嗗簭瀹夎闃叉姢缃╋紝鍔犳敞娑︽粦娌癸紝杩涜浣庨�熻瘯杩愯浆锛屾鏌ヨ繍杞姸鎬併��',
+    duration: 20,
+    completed: false,
+    expanded: false,
+    warnings: [
+      '瀹夎鏃惰纭繚鎵�鏈夊瘑灏佷欢姝g‘灏变綅',
+      '娑︽粦娌瑰姞娉ㄩ噺瑕佺鍚堣瀹氳姹�',
+      '璇曡繍杞椂瑕佸瘑鍒囪瀵熻澶囩姸鎬�'
+    ],
+    tools: ['娑︽粦娌�', '瀵嗗皝鑳�', '娓呮磥甯�']
+  }
+])
+
+const currentStepIndex = ref(0)
+
+// 閰嶄欢娓呭崟鏁版嵁
+const partsList = ref([
+  {
+    id: 1,
+    name: '涓昏酱杞存壙',
+    specification: 'NSK 7020C',
+    partNumber: 'BRG-7020C-001',
+    requiredQuantity: 2,
+    stockQuantity: 5,
+    unit: '涓�',
+    available: true,
+    location: '浠撳簱A鍖�-03璐ф灦',
+    supplier: '鏃ユ湰NSK鍏徃',
+    price: 1250.00
+  },
+  {
+    id: 2,
+    name: '瀵嗗皝鍦�',
+    specification: 'O鍨嬪湀 蠁45脳3',
+    partNumber: 'SEAL-045-003',
+    requiredQuantity: 4,
+    stockQuantity: 2,
+    unit: '涓�',
+    available: false,
+    location: '浠撳簱B鍖�-12璐ф灦',
+    supplier: '寰峰浗璐规柉鎵�',
+    price: 25.50
+  },
+  {
+    id: 3,
+    name: '娑︽粦鑴�',
+    specification: '楂樻俯杞存壙娑︽粦鑴� 2#',
+    partNumber: 'LUB-HT-002',
+    requiredQuantity: 1,
+    stockQuantity: 8,
+    unit: '鏀�',
+    available: true,
+    location: '浠撳簱C鍖�-05璐ф灦',
+    supplier: '缇庡瓪鐭虫补',
+    price: 180.00
+  },
+  {
+    id: 4,
+    name: '铻烘爴',
+    specification: 'M8脳25 鍐呭叚瑙掕灪鏍�',
+    partNumber: 'BOLT-M8-025',
+    requiredQuantity: 8,
+    stockQuantity: 50,
+    unit: '涓�',
+    available: true,
+    location: '浠撳簱A鍖�-01璐ф灦',
+    supplier: '鏍囧噯浠跺巶',
+    price: 2.50
+  },
+  {
+    id: 5,
+    name: '鍨墖',
+    specification: '璋冩暣鍨墖 蠁40脳0.1',
+    partNumber: 'SHIM-040-01',
+    requiredQuantity: 6,
+    stockQuantity: 0,
+    unit: '鐗�',
+    available: false,
+    location: '浠撳簱A鍖�-08璐ф灦',
+    supplier: '绮惧瘑鍔犲伐鍘�',
+    price: 15.00
+  }
+])
+
+// 瀹夊叏淇℃伅鏁版嵁
+const safetyInfo = ref({
+  level: '楂橀闄�',
+  title: '鏈烘璁惧缁翠慨瀹夊叏瑙勭▼',
+  description: '鏈缁翠慨娑夊強閲嶅瀷鏈烘璁惧锛屽瓨鍦ㄦ満姊颁激瀹炽�佺數鍑荤瓑椋庨櫓锛岃涓ユ牸閬靛畧瀹夊叏鎿嶄綔瑙勭▼銆�',
+  ppe: [
+    {
+      name: '瀹夊叏甯�',
+      icon: '鉀戯笍',
+      description: '闃叉澶撮儴鍙楀埌鎾炲嚮浼ゅ',
+      checked: false
+    },
+    {
+      name: '瀹夊叏鐪奸暅',
+      icon: '馃ソ',
+      description: '闃叉閲戝睘灞戦婧呬激鐪�',
+      checked: false
+    },
+    {
+      name: '闃叉姢鎵嬪',
+      icon: '馃Г',
+      description: '闃叉鎵嬮儴鍓蹭激鍜岀儷浼�',
+      checked: false
+    },
+    {
+      name: '瀹夊叏闉�',
+      icon: '馃憿',
+      description: '闃叉瓒抽儴琚噸鐗╃牳浼�',
+      checked: false
+    },
+    {
+      name: '宸ヤ綔鏈�',
+      icon: '馃',
+      description: '闃叉琛g墿琚満姊板嵎鍏�',
+      checked: false
+    }
+  ],
+  warnings: [
+    '缁翠慨鍓嶅繀椤荤‘璁よ澶囧畬鍏ㄦ柇鐢碉紝骞舵寕涓婂畨鍏ㄦ爣璇嗙墝',
+    '浣跨敤宸ュ叿鍓嶈妫�鏌ュ伐鍏风姸鎬侊紝纭繚瀹屽ソ鏃犳崯',
+    '鎷嗗嵏閲嶅瀷閮ㄤ欢鏃惰浣跨敤璧烽噸璁惧锛屼笉寰楀緬鎵嬫搷浣�',
+    '宸ヤ綔鍖哄煙瑕佷繚鎸佹暣娲侊紝鍙婃椂娓呯悊娌规薄鍜屾潅鐗�',
+    '鍙戠幇寮傚父鎯呭喌瑕佺珛鍗冲仠姝綔涓氾紝鎶ュ憡鐜板満璐熻矗浜�',
+    '涓ョ鍦ㄧ柌鍔崇姸鎬佷笅杩涜绮惧瘑鎿嶄綔',
+    '澶氫汉鍗忎綔鏃惰鏄庣‘鍒嗗伐锛屽姞寮烘矡閫氬崗璋�'
+  ],
+  emergencyProcedures: [
+    {
+      situation: '浜哄憳鍙椾激',
+      steps: [
+        '绔嬪嵆鍋滄鎵�鏈変綔涓氭椿鍔�',
+        '璇勪及浼ゆ儏涓ラ噸绋嬪害',
+        '杞讳激杩涜鐜板満鎬ユ晳澶勭悊',
+        '閲嶄激绔嬪嵆鎷ㄦ墦120鎬ユ晳鐢佃瘽',
+        '閫氱煡瀹夊叏绠$悊浜哄憳鍜岄」鐩礋璐d汉',
+        '淇濇姢鐜板満锛岄厤鍚堜簨鏁呰皟鏌�'
+      ]
+    },
+    {
+      situation: '璁惧鏁呴殰',
+      steps: [
+        '绔嬪嵆鎸変笅鎬ュ仠鎸夐挳',
+        '鍒囨柇璁惧鐢垫簮',
+        '鐤忔暎鍛ㄥ洿浜哄憳鍒板畨鍏ㄥ尯鍩�',
+        '閫氱煡璁惧绠$悊浜哄憳',
+        '璁板綍鏁呴殰鐜拌薄鍜屾椂闂�',
+        '绛夊緟涓撲笟浜哄憳澶勭悊'
+      ]
+    },
+    {
+      situation: '鐏伨浜嬫晠',
+      steps: [
+        '绔嬪嵆鍒囨柇鐢垫簮',
+        '浣跨敤閫傚綋鐨勭伃鐏櫒鏉�',
+        '鐤忔暎鐜板満浜哄憳',
+        '鎷ㄦ墦119鐏鐢佃瘽',
+        '閫氱煡娑堥槻瀹夊叏绠$悊浜哄憳',
+        '閰嶅悎娑堥槻閮ㄩ棬鏁戞彺'
+      ]
+    }
+  ]
+})
+
+const safetyConfirmed = ref(false)
+
+// 璁$畻灞炴��
+const completedSteps = computed(() => {
+  return sopSteps.value.filter(step => step.completed).length
+})
+
+const canStartWork = computed(() => {
+  return safetyConfirmed.value && completedSteps.value > 0
+})
+
+// 杩斿洖涓婁竴椤�
+const goBack = () => {
+  uni.navigateBack()
+}
+
+// 鑾峰彇浠诲姟鐘舵�佺被鍨�
+const getStatusType = (status) => {
+  const statusMap = {
+    'pending': 'warning',
+    'in_progress': 'primary',
+    'completed': 'success',
+    'paused': 'info'
+  }
+  return statusMap[status] || 'info'
+}
+
+// 鑾峰彇浠诲姟鐘舵�佹枃鏈�
+const getStatusText = (status) => {
+  const statusMap = {
+    'pending': '寰呭紑濮�',
+    'in_progress': '杩涜涓�',
+    'completed': '宸插畬鎴�',
+    'paused': '宸叉殏鍋�'
+  }
+  return statusMap[status] || '鏈煡'
+}
+
+// 鍒囨崲鏍囩
+const switchTab = (tabKey) => {
+  activeTab.value = tabKey
+}
+
+// 鍒囨崲姝ラ灞曞紑鐘舵��
+const toggleStep = (index) => {
+  sopSteps.value[index].expanded = !sopSteps.value[index].expanded
+}
+
+// 瀹屾垚姝ラ
+const completeStep = (index) => {
+  sopSteps.value[index].completed = true
+  showToast('姝ラ宸插畬鎴�')
+  
+  // 鑷姩灞曞紑涓嬩竴姝�
+  if (index < sopSteps.value.length - 1) {
+    currentStepIndex.value = index + 1
+    sopSteps.value[index + 1].expanded = true
+  }
+}
+
+// 鍙栨秷瀹屾垚姝ラ
+const uncompleteStep = (index) => {
+  sopSteps.value[index].completed = false
+  showToast('宸插彇娑堝畬鎴愮姸鎬�')
+}
+
+// 鐢宠閰嶄欢
+const requestPart = (part) => {
+  uni.showModal({
+    title: '鐢宠閰嶄欢',
+    content: `纭鐢宠閰嶄欢"${part.name}"锛焋,
+    confirmText: '纭',
+    cancelText: '鍙栨秷',
+    success: (res) => {
+      if (res.confirm) {
+        showToast('閰嶄欢鐢宠宸叉彁浜�')
+        // 杩欓噷鍙互璋冪敤API鎻愪氦鐢宠
+      }
+    }
+  })
+}
+
+// 鏌ョ湅閰嶄欢璇︽儏
+const viewPartDetail = (part) => {
+  uni.showModal({
+    title: part.name,
+    content: `閰嶄欢缂栧彿: ${part.partNumber}\n瑙勬牸: ${part.specification}\n渚涘簲鍟�: ${part.supplier}\n鍗曚环: 楼${part.price}`,
+    showCancel: false,
+    confirmText: '鐭ラ亾浜�'
+  })
+}
+
+// 鑾峰彇瀹夊叏绛夌骇绫诲瀷
+const getSafetyLevelType = (level) => {
+  const levelMap = {
+    '浣庨闄�': 'success',
+    '涓闄�': 'warning',
+    '楂橀闄�': 'error'
+  }
+  return levelMap[level] || 'info'
+}
+
+// 鍒囨崲PPE鐘舵��
+const togglePPE = (ppe) => {
+  ppe.checked = !ppe.checked
+  if (ppe.checked) {
+    showToast(`宸茬‘璁や僵鎴�${ppe.name}`)
+  }
+}
+
+// 纭瀹夊叏
+const confirmSafety = () => {
+  const uncheckedPPE = safetyInfo.value.ppe.filter(ppe => !ppe.checked)
+  if (uncheckedPPE.length > 0) {
+    showToast('璇风‘璁ゅ凡浣╂埓鎵�鏈変釜浜洪槻鎶よ澶�')
+    return
+  }
+  
+  safetyConfirmed.value = true
+  showToast('瀹夊叏纭瀹屾垚锛屽彲浠ュ紑濮嬩綔涓�')
+}
+
+// 寮�濮嬩綔涓�
+const startWork = () => {
+  if (!safetyConfirmed.value) {
+    showToast('璇峰厛瀹屾垚瀹夊叏纭')
+    return
+  }
+  
+  if (completedSteps.value === 0) {
+    showToast('璇疯嚦灏戝畬鎴愪竴涓猄OP姝ラ')
+    return
+  }
+  
+  uni.showModal({
+    title: '寮�濮嬩綔涓�',
+    content: '纭寮�濮嬫寮忎綔涓氾紵',
+    confirmText: '寮�濮�',
+    cancelText: '鍙栨秷',
+    success: (res) => {
+      if (res.confirm) {
+        currentTask.value.status = 'in_progress'
+        showToast('浣滀笟宸插紑濮嬶紝璇锋寜鐓OP鎵ц')
+      }
+    }
+  })
+}
+
+// 淇濆瓨杩涘害
+const saveProgress = () => {
+  const progress = {
+    taskId: currentTask.value.id,
+    completedSteps: completedSteps.value,
+    safetyConfirmed: safetyConfirmed.value,
+    timestamp: new Date().toISOString()
+  }
+  
+  // 杩欓噷鍙互璋冪敤API淇濆瓨杩涘害
+  showToast('杩涘害宸蹭繚瀛�')
+  console.log('淇濆瓨鐨勮繘搴�:', progress)
+}
+
+onMounted(() => {
+  // 椤甸潰鍔犺浇鏃剁殑鍒濆鍖栭�昏緫
+  // 鍙互鏍规嵁浠诲姟ID鍔犺浇瀵瑰簲鐨凷OP銆侀厤浠舵竻鍗曞拰瀹夊叏鎻愮ず
+})
+
+onShow(() => {
+  // 椤甸潰鏄剧ず鏃剁殑閫昏緫
+})
+</script>
+
+<style scoped lang="scss">
+@import '@/styles/sales-common.scss';
+
+// 鏍囧噯浣滀笟鎸囧鐗规湁鏍峰紡
+.sales-account {
+  padding-bottom: 100px;
+}
+
+// 浠诲姟淇℃伅鍗$墖
+.task-info-card {
+  margin: 20px;
+  background: #ffffff;
+  border-radius: 12px;
+  padding: 16px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+}
+
+.task-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.task-left {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+
+.task-icon {
+  width: 40px;
+  height: 40px;
+  background: #2979ff;
+  border-radius: 8px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.task-details {
+  display: flex;
+  flex-direction: column;
+  gap: 4px;
+}
+
+.task-title {
+  font-size: 16px;
+  font-weight: 500;
+  color: #333;
+}
+
+.task-subtitle {
+  font-size: 12px;
+  color: #666;
+}
+
+.task-meta {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.meta-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.meta-label {
+  font-size: 12px;
+  color: #777;
+  min-width: 70px;
+}
+
+.meta-value {
+  font-size: 12px;
+  color: #333;
+  flex: 1;
+  text-align: right;
+}
+
+// 瀵艰埅鏍囩
+.nav-tabs {
+  display: flex;
+  background: #ffffff;
+  margin: 0 20px;
+  border-radius: 12px;
+  padding: 4px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+}
+
+.nav-tab {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 4px;
+  padding: 12px 8px;
+  border-radius: 8px;
+  transition: all 0.3s ease;
+  
+  &.active {
+    background: #f3f7ff;
+  }
+}
+
+.tab-text {
+  font-size: 12px;
+  color: #666;
+  
+  &.active {
+    color: #2979ff;
+    font-weight: 500;
+  }
+}
+
+// 鍐呭鍖哄煙
+.content-section {
+  margin: 20px;
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+}
+
+.section-title {
+  font-size: 16px;
+  font-weight: 500;
+  color: #333;
+}
+
+.progress-info {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+}
+
+.progress-text {
+  font-size: 12px;
+  color: #666;
+}
+
+// SOP姝ラ鏍峰紡
+.sop-steps {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+
+.sop-step {
+  background: #ffffff;
+  border-radius: 12px;
+  border: 1px solid #f0f0f0;
+  overflow: hidden;
+  transition: all 0.3s ease;
+  
+  &.completed {
+    border-color: #4caf50;
+    background: #f8fff8;
+  }
+  
+  &.current {
+    border-color: #2979ff;
+    box-shadow: 0 2px 8px rgba(41, 121, 255, 0.1);
+  }
+}
+
+.step-header {
+  display: flex;
+  align-items: center;
+  padding: 16px;
+  cursor: pointer;
+}
+
+.step-number {
+  width: 28px;
+  height: 28px;
+  border-radius: 50%;
+  background: #f5f5f5;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 12px;
+  
+  .sop-step.completed & {
+    background: #4caf50;
+  }
+}
+
+.step-num {
+  font-size: 12px;
+  font-weight: 500;
+  color: #666;
+  
+  .sop-step.completed & {
+    color: #ffffff;
+  }
+}
+
+.step-content {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  gap: 4px;
+}
+
+.step-title {
+  font-size: 14px;
+  font-weight: 500;
+  color: #333;
+}
+
+.step-duration {
+  font-size: 12px;
+  color: #666;
+}
+
+.step-details {
+  padding: 0 16px 16px 16px;
+  border-top: 1px solid #f0f0f0;
+}
+
+.step-description {
+  margin: 16px 0;
+}
+
+.desc-text {
+  font-size: 13px;
+  color: #555;
+  line-height: 1.5;
+}
+
+.step-warnings {
+  margin: 16px 0;
+  padding: 12px;
+  background: #fff3e0;
+  border-radius: 8px;
+  border-left: 4px solid #ff9800;
+}
+
+.warning-title {
+  font-size: 13px;
+  font-weight: 500;
+  color: #e65100;
+  margin-bottom: 8px;
+}
+
+.warning-item {
+  margin-bottom: 4px;
+}
+
+.warning-text {
+  font-size: 12px;
+  color: #bf360c;
+  line-height: 1.4;
+}
+
+.step-tools {
+  margin: 16px 0;
+}
+
+.tools-title {
+  font-size: 13px;
+  font-weight: 500;
+  color: #333;
+  margin-bottom: 8px;
+}
+
+.tools-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 6px;
+}
+
+.tool-tag {
+  margin: 0;
+}
+
+.step-actions {
+  margin-top: 16px;
+  display: flex;
+  gap: 8px;
+}
+
+// 閰嶄欢娓呭崟鏍峰紡
+.parts-summary {
+  display: flex;
+  align-items: center;
+}
+
+.summary-text {
+  font-size: 12px;
+  color: #666;
+}
+
+.parts-list {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+
+.part-item {
+  background: #ffffff;
+  border-radius: 12px;
+  padding: 16px;
+  border: 1px solid #f0f0f0;
+}
+
+.part-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 12px;
+}
+
+.part-info {
+  flex: 1;
+}
+
+.part-name {
+  font-size: 14px;
+  font-weight: 500;
+  color: #333;
+  display: block;
+  margin-bottom: 4px;
+}
+
+.part-spec {
+  font-size: 12px;
+  color: #666;
+}
+
+.part-details {
+  display: flex;
+  flex-direction: column;
+  gap: 6px;
+  margin-bottom: 12px;
+}
+
+.detail-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.detail-label {
+  font-size: 12px;
+  color: #777;
+  min-width: 70px;
+}
+
+.detail-value {
+  font-size: 12px;
+  color: #333;
+  
+  &.danger {
+    color: #f44336;
+    font-weight: 500;
+  }
+}
+
+.part-actions {
+  display: flex;
+  gap: 8px;
+}
+
+// 瀹夊叏鎻愮ず鏍峰紡
+.safety-level {
+  display: flex;
+  align-items: center;
+}
+
+.safety-overview {
+  display: flex;
+  align-items: flex-start;
+  gap: 12px;
+  padding: 16px;
+  background: #fff3e0;
+  border-radius: 12px;
+  margin-bottom: 20px;
+  border-left: 4px solid #ff6b35;
+}
+
+.safety-icon {
+  margin-top: 2px;
+}
+
+.safety-content {
+  flex: 1;
+}
+
+.safety-title {
+  font-size: 14px;
+  font-weight: 500;
+  color: #e65100;
+  display: block;
+  margin-bottom: 4px;
+}
+
+.safety-desc {
+  font-size: 12px;
+  color: #bf360c;
+  line-height: 1.4;
+}
+
+.safety-section {
+  margin-bottom: 20px;
+  background: #ffffff;
+  border-radius: 12px;
+  padding: 16px;
+  border: 1px solid #f0f0f0;
+}
+
+.safety-section-title {
+  font-size: 14px;
+  font-weight: 500;
+  color: #333;
+  margin-bottom: 12px;
+}
+
+// PPE鍒楄〃
+.ppe-list {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+
+.ppe-item {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  padding: 12px;
+  background: #f8f9fa;
+  border-radius: 8px;
+}
+
+.ppe-icon {
+  width: 32px;
+  height: 32px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.ppe-emoji {
+  font-size: 20px;
+}
+
+.ppe-info {
+  flex: 1;
+}
+
+.ppe-name {
+  font-size: 13px;
+  font-weight: 500;
+  color: #333;
+  display: block;
+  margin-bottom: 2px;
+}
+
+.ppe-desc {
+  font-size: 11px;
+  color: #666;
+}
+
+// 瀹夊叏璀﹀憡
+.safety-warnings {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.safety-warning {
+  display: flex;
+  align-items: flex-start;
+  gap: 8px;
+  padding: 8px 0;
+}
+
+.warning-icon {
+  margin-top: 2px;
+}
+
+.warning-content {
+  flex: 1;
+  font-size: 12px;
+  color: #555;
+  line-height: 1.4;
+}
+
+// 搴旀�ュ鐞�
+.emergency-procedures {
+  display: flex;
+  flex-direction: column;
+  gap: 16px;
+}
+
+.emergency-item {
+  border: 1px solid #ffcdd2;
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+.emergency-header {
+  background: #ffebee;
+  padding: 12px 16px;
+  border-bottom: 1px solid #ffcdd2;
+}
+
+.emergency-title {
+  font-size: 13px;
+  font-weight: 500;
+  color: #c62828;
+}
+
+.emergency-steps {
+  padding: 12px 16px;
+}
+
+.emergency-step {
+  display: flex;
+  align-items: flex-start;
+  gap: 8px;
+  margin-bottom: 8px;
+  
+  &:last-child {
+    margin-bottom: 0;
+  }
+}
+
+.step-number {
+  font-size: 12px;
+  font-weight: 500;
+  color: #d32f2f;
+  min-width: 16px;
+}
+
+.step-content {
+  font-size: 12px;
+  color: #555;
+  line-height: 1.4;
+}
+
+// 瀹夊叏纭
+.safety-confirmation {
+  background: #e8f5e8;
+  border-radius: 12px;
+  padding: 16px;
+  border: 1px solid #c8e6c9;
+}
+
+.confirmation-header {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  margin-bottom: 8px;
+}
+
+.confirmation-title {
+  font-size: 14px;
+  font-weight: 500;
+  color: #2e7d32;
+}
+
+.confirmation-content {
+  margin-bottom: 16px;
+}
+
+.confirmation-text {
+  font-size: 12px;
+  color: #388e3c;
+  line-height: 1.4;
+}
+
+.confirmation-actions {
+  display: flex;
+  justify-content: center;
+}
+
+// 搴曢儴鎿嶄綔鎸夐挳
+.bottom-actions {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: #ffffff;
+  padding: 16px 20px;
+  border-top: 1px solid #f0f0f0;
+  display: flex;
+  gap: 12px;
+  z-index: 100;
+}
+
+.bottom-actions .u-button {
+  flex: 1;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/index.vue b/src/pages/index.vue
index 05398bd..e931c3f 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -275,6 +275,11 @@
 		icon: 'flash',
 		label: '鏅鸿兘娲惧崟',
 		bgColor: '#ff6b35'
+	},
+	{
+		icon: 'file-text',
+		label: '浣滀笟鎸囧',
+		bgColor: '#4caf50'
 	}
 ]);
 
@@ -377,6 +382,11 @@
 				url: '/pages/equipmentManagement/smartDispatch/index'
 			});
 			break;
+		case '浣滀笟鎸囧':
+			uni.navigateTo({
+				url: '/pages/equipmentManagement/sop/index'
+			});
+			break;
 		default:
 			uni.showToast({
 				title: `鐐瑰嚮浜�${item.label}`,

--
Gitblit v1.9.3