| CLAUDE.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| pages/QC/SJ/Add.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| pages/QC/SJ/List.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| pages/QC/SJ/detail.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
CLAUDE.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,122 @@ # CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a **uni-app** mobile application project for Quality Control (QC) and Warehouse management in a Manufacturing Execution System (MES). The application is built for PDA devices and supports quality inspection processes and warehouse operations. - **Framework**: uni-app (Vue 2.x based) - **App Name**: GS-MES-AP (å¹¿æ·±ç§æ MES Application) - **Target Platform**: Android mobile/PDA devices - **UI Framework**: uView UI library ## Build and Development Commands This is a uni-app project that builds through HBuilderX IDE or uni-app CLI. The build output is generated in the `unpackage/` directory: - **Development Build**: Use HBuilderX IDE or `npm run dev:app-plus` for development - **Production Build**: APK files are generated in `unpackage/release/apk/` - **Cache**: Build cache and temporary files are stored in `unpackage/cache/` - **Testing**: Use HBuilderX IDE's built-in testing tools or deploy to PDA devices for testing **Note**: This project does not have traditional npm scripts. Development and building are primarily done through HBuilderX IDE. ## Architecture Overview ### Core Structure - **Entry Point**: `main.js` - Contains Vue prototypes, global mixins, and API configuration - **State Management**: `store/index.js` - Vuex store with server configuration and minimal state - **Routing**: `pages.json` - uni-app page configuration with tabBar navigation - **Global Config**: `manifest.json` - App configuration including permissions and build settings ### Key Directories - `pages/BasePages/` - Core app pages (login, main menu, user profile) - `pages/QC/` - Quality Control modules (æ¥ææ£éª LLJ, å·¡æ£ XJ, 馿£ SJ, å ¥åºæ£ RKJ) - `pages/Warehouse/` - Warehouse operations (inventory, purchasing, allocation) - `components/` - Reusable UI components and third-party integrations - `static/` - Static assets (images, audio files, CSS) - `uni_modules/` - uni-app plugin modules including uView UI ### API Architecture - **Base API**: Configured in Vuex store with environment-specific URLs - **Request Methods**: Custom Vue prototypes (`$post`, `$get`, `$uni_request`) with loading states - **Authentication**: User login state managed globally via `$loginInfo` - **Error Handling**: Centralized error handling with toast messages ### Main Features 1. **Quality Control (QC)**: - æ¥ææ£éª (LLJ) - Incoming Material Inspection - å·¡æ£ (XJ) - Patrol Inspection - 馿£ (SJ) - First Article Inspection - å ¥åºæ£ (RKJ) - Warehouse Inspection 2. **Warehouse Operations**: - Purchase inventory management - Material allocation and transfers - Barcode printing and scanning 3. **Common Functions**: - Barcode/QR code scanning - Photo capture and upload - Bluetooth printing integration - Offline data synchronization ### Navigation Structure - **Tab Bar**: 3 main tabs (é¦é¡µ/Home, æ¶æ¯ä¸å¿/Message Center, æç/Profile) - **Menu System**: Dynamic menu loading based on user permissions via `$getUserMenu()` - **Page Flow**: List â Detail â Form pattern for most workflows ## Development Guidelines ### Server Configuration The app connects to different servers based on environment: - Development: `http://localhost:10054` or `http://192.168.1.104:10056/api` - Check `store/index.js` for current active server endpoints ### Global Utilities - `$showMessage()` - Display toast notifications - `$showDialog()` - Show confirmation dialogs - `$camera()` - Camera/photo selection functionality - `$getDate()` - Date formatting utilities - `$getUrlParams()` - URL parameter parsing ### Component Dependencies - **uView UI**: Primary UI component library - **Custom Components**: Scanner, printer utilities in `components/kk-printer/` - **Third-party**: Charts (u-charts), maps (amap), markdown parsing ### File Upload System Image uploads use base64 encoding via `$fileUpload()` method, sending to `/Base/saveImage` endpoint. ### Authentication System - User authentication is managed through `$loginInfo` object in `main.js` - Login state persists using `uni.getStorageSync()` and `uni.setStorageSync()` - Global mixin `globalMixin.js` provides `checkUserAuth()` for automatic login verification - Users are redirected to `/pages/BasePages/login` if not authenticated ### Request Architecture - **$post()** and **$get()**: Standard API requests with automatic loading indicators - **$uni_request()**: Core request method with error handling and status checking - **$toERP()**: External ERP system integration requests - **$postSyncPost()**: Promise-based synchronous POST requests - All requests automatically handle loading states, error messages, and network failures ### Hardware Integration - **Camera**: Native camera access via `$camera()` with image compression options - **Barcode Scanner**: QR/barcode scanning capabilities for PDA devices - **Bluetooth Printing**: Printer integration through `components/kk-printer/` - **Device Permissions**: Configured in `manifest.json` for camera, storage, network, and Bluetooth access ### Page Architecture Patterns - **List Pages**: Pagination with pull-to-refresh and infinite scroll - **Detail Pages**: Read-only view with navigation to edit forms - **Add/Edit Forms**: Input validation and submission with photo upload capabilities - **Scan Pages**: Barcode scanning with immediate data processing ### Environment Configuration Current server endpoints are configured in `store/index.js`: - **Development**: `http://localhost:5184/api` - **Internal Network**: `http://192.168.11.251:10054` - **Testing**: `http://192.168.1.104:10056/api` or `10057/api` - Switch between environments by updating `serverAPI` in the Vuex store pages/QC/SJ/Add.vue
@@ -53,12 +53,8 @@ <view class="info-value highlight">{{ formData.daa008 }}</view> </view> <view v-if="formData.remarks" class="info-block"> <view class="info-label">ä¸åæ ¼æè¿°ï¼</view> <view class="info-value">{{ formData.remarks }}</view> </view> <view v-if="formData.comments" class="info-block"> <view class="info-label">夿³¨ï¼</view> <view class="info-value">{{ formData.comments }}</view> <view class="info-value">{{ formData.remarks }}</view> </view> </view> @@ -137,9 +133,8 @@ <button v-if="!isUpdate && !formData.statusUser && !isShowTable" class="secondary-btn" @click="removeXJ"> å é¤åæ® </button> <button v-if="!isUpdate && !isShowTable" class="secondary-btn" @click="saveRemarks">æ·»å ä¸åæ ¼æè¿°</button> <button v-if="!isUpdate && !isShowTable" class="secondary-btn" @click="saveComments">æ·»å 夿³¨</button> <button v-if="!isUpdate && !isShowTable" class="primary-btn" @click="submit">å®¡æ ¸åæ®</button> <button v-if="!isUpdate && !isShowTable" class="secondary-btn" @click="saveRemarks">æ·»å 夿³¨</button> <button v-if="!isUpdate && !isShowTable && formData.fSubmit != 1" class="primary-btn" @click="submit">å®¡æ ¸åæ®</button> <button v-if="isShowTable" class="secondary-btn" @click="getTable">è·åæ£éªé¡¹ç®</button> <button v-if="isShowTable && isUpdate" class="primary-btn" @click="saveTable">çææ£éªé¡¹ç®</button> </view> @@ -147,28 +142,14 @@ <!-- å¼¹çª --> <view v-if="remarksPopup" class="overlay"> <view class="popup"> <h3>ä¿®æ¹ä¸åæ ¼æè¿°</h3> <form> <view class="form-group"> <label class="form-label">ä¸åæ ¼æè¿°:</label> <input v-model="remarks" class="form-input" type="text"/> </view> <button class="updateBut" @click="editRemarks">ä¿®æ¹</button> <button @click="remarksPopup = !remarksPopup">åæ¶</button> </form> </view> </view> <view v-if="commentsPopup" class="overlay"> <view class="popup"> <h3>ä¿®æ¹å¤æ³¨</h3> <form> <view class="form-group"> <label class="form-label">夿³¨:</label> <input v-model="comments" class="form-input" type="text"/> <textarea v-model="remarks" class="form-input form-textarea" placeholder="请è¾å ¥å¤æ³¨ä¿¡æ¯..."></textarea> </view> <button class="updateBut" @click="editComments">ä¿®æ¹</button> <button @click="commentsPopup = !commentsPopup">åæ¶</button> <button class="updateBut" @click="editRemarks">ä¿®æ¹</button> <button @click="remarksPopup = !remarksPopup">åæ¶</button> </form> </view> </view> @@ -191,6 +172,7 @@ comments: "", statusUser: "", itemId: "", fSubmit: 0, }, DAA020List: [], @@ -300,17 +282,26 @@ }).then(res => { //2024-11-28 kyy æ ¡éªåæ ¼æäº¤å¢å æç¤º console.log("宿´ååºæ°æ®:", res); console.log("Status Codeçå¼:", res.statusCode); if (res.statusCode === 200) { console.log("è¿åçæ°æ®:", res.data); // æ£æ¥å¤ç§æåæ¡ä»¶ if (res.statusCode === 200 || res.status === 0 || res.data === true || res.data.tbBillList === true) { this.$showMessage("æåæäº¤æ£éª"); // 使ç¨setTimeoutå¨7ç§åéèæ¶æ¯ // æäº¤æåå跳转å°åè¡¨é¡µé¢ setTimeout(() => { this.hideCustomMessage(); }, 7000); // 7000毫ç§çäº7ç§ uni.navigateTo({ url: '/pages/QC/SJ/List' }); }, 1500); // 1.5ç§å跳转ï¼è®©ç¨æ·çå°æåæç¤º } else { this.$showMessage(res.data.message); this.$showMessage(res.data.message || res.message || "æäº¤å¤±è´¥"); } }).catch(err => { console.log("æäº¤åºé:", err); this.$showMessage("æäº¤å¤±è´¥ï¼è¯·éè¯"); }) }, @@ -426,7 +417,7 @@ this.$post({ url: "/SJ/SetQSItems", data: { itemId: this.formData.itemNo itemNo: this.formData.itemNo } }).then(res => { if (res.data.tbBillList.length > 0) { @@ -459,7 +450,7 @@ this.$post({ url: "/SJ/SetQSItems", data: { itemId: this.formData.itemNo itemNo: this.formData.itemNo } }).then(res => { if (res.data.tbBillList.length > 0) { @@ -1001,8 +992,9 @@ padding: 20px; border: 1px solid #ccc; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); width: 68vw; height: 25vh; width: 85vw; min-height: 35vh; max-height: 60vh; border-radius: 8px; } @@ -1035,6 +1027,13 @@ border-radius: 4px; font-size: 14px; box-sizing: border-box; } .popup .form-textarea { min-height: 120px; resize: vertical; font-family: inherit; line-height: 1.5; } .popup-buttons { @@ -1155,6 +1154,18 @@ width: 6px; height: 6px; } /* ç§»å¨ç«¯å¼¹åºæ¡ä¼å */ .popup { width: 95vw; min-height: 40vh; max-height: 70vh; padding: 15px; } .popup .form-textarea { min-height: 100px; } } /* å¹³æ¿è®¾å¤æ ·å¼ */ pages/QC/SJ/List.vue
@@ -35,9 +35,15 @@ <view v-if="item.urgent == 1" class="badge urgent">æ¥æ</view> <view v-if="item.isFirst == 1" class="badge normal">馿¬¡</view> <view class="card-title">æ£éªåå·: {{ item.billNo }}</view> <view :class="{'status-pending': current === 0, 'status-assigned': current === 0 && item.statusUser, 'status-pass': current === 1 && item.result === 'åæ ¼', 'status-fail': current === 1 && item.result === 'ä¸åæ ¼'}" <view :class="{ 'status-pending': !item.result && current === 0, 'status-assigned': current === 0 && item.statusUser && !item.result, 'status-pass': item.result === 'åæ ¼', 'status-fail': item.result === 'ä¸åæ ¼', 'status-submitted': !item.result && current === 1 }" class="status"> {{ current === 0 ? (item.statusUser ? 'å·²åé ' : 'æªæäº¤') : (item.result ? item.result : 'å·²æäº¤') }} {{ current === 0 ? (item.result ? item.result : 'æªæäº¤') : (item.result ? item.result : 'å·²æäº¤') }} </view> </view> @@ -460,7 +466,12 @@ } .status-fail { background: linear-gradient(135deg, #e74c3c, #c0392b); background: linear-gradient(135deg, #3498db, #2980b9); color: white; } .status-submitted { background: linear-gradient(135deg, #95a5a6, #7f8c8d); color: white; } pages/QC/SJ/detail.vue
@@ -76,7 +76,7 @@ <view class="info-value">{{ formData.result }}</view> </view> <view v-if="formData.remarks" class="info-item"> <view class="info-label">ä¸åæ ¼æè¿°</view> <view class="info-label">夿³¨</view> <view class="info-value danger">{{ formData.remarks }}</view> </view> </view> @@ -104,7 +104,7 @@ </button> <button class="btn upload-btn" @click="saveRemarks"> <uni-icons color="#fff" size="16" type="compose"></uni-icons> ä¸åæ ¼æè¿° 夿³¨ </button> </view> </view> @@ -118,7 +118,7 @@ </button> <button class="btn upload-btn" @click="saveRemarks"> <uni-icons color="#fff" size="16" type="compose"></uni-icons> ä¸åæ ¼æè¿° 夿³¨ </button> </view> <view class="input-wrapper" style="margin-top: 15px;"> @@ -181,13 +181,13 @@ </view> </view> <!-- å¼¹åºå± - ä¸åæ ¼æè¿° --> <!-- å¼¹åºå± - 夿³¨ --> <view v-if="remarksPopup" class="overlay"> <view class="popup"> <h3>ä¿®æ¹ä¸åæ ¼æè¿°</h3> <h3>ä¿®æ¹å¤æ³¨</h3> <form> <view class="form-group"> <label class="form-label">ä¸åæ ¼æè¿°:</label> <label class="form-label">夿³¨:</label> <input v-model="remarks" class="form-input" type="text"/> </view> <view class="popup-buttons">