¶Ô±ÈÐÂÎļþ |
| | |
| | | # 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 based mobile application for quality control (QC) and warehouse management in a MES (Manufacturing Execution System) environment. The app is specifically designed for PDA devices and supports both Android and iOS platforms. |
| | | |
| | | **App Details:** |
| | | - Name: GS-MES-AP (å¹¿æ·±ç§æ MES Application) |
| | | - Framework: uni-app with Vue 2 |
| | | - Version: 1.1.1.4 |
| | | - Company: å¹¿æ·±ç§æ (Guangshen Technology) |
| | | |
| | | ## Architecture |
| | | |
| | | ### Core Structure |
| | | - **Frontend Framework**: Vue 2 with uni-app cross-platform framework |
| | | - **State Management**: Vuex store for application state |
| | | - **Routing**: uni-app page-based routing defined in `pages.json` |
| | | - **Entry Point**: `main.js` - contains global configurations, prototypes, and app initialization |
| | | |
| | | ### Key Directories |
| | | - `pages/` - All application pages organized by functionality: |
| | | - `BasePages/` - Core app pages (login, main, user, messages) |
| | | - `QC/` - Quality control modules (XJ-å·¡æ£, SJ-馿£, RKJ-å
¥åºæ£, LLJ-æ¥ææ£) |
| | | - `Warehouse/` - Warehouse management (inventory, purchases, returns) |
| | | - `Test/` - Testing and development pages |
| | | - `Allocation/` - Transfer operations (in/out) |
| | | - `components/` - Reusable UI components and third-party components |
| | | - `static/` - Static assets (images, CSS, audio files) |
| | | - `store/` - Vuex state management |
| | | - `common/` - Shared utilities and mixins |
| | | - `utils/` - Utility functions |
| | | |
| | | ### Main Functionality Areas |
| | | 1. **Quality Control (QC)**: |
| | | - å·¡æ£ (XJ) - Patrol Inspection |
| | | - 馿£ (SJ) - First Article Inspection |
| | | - å
¥åºæ£ (RKJ) - Incoming Inspection |
| | | - æ¥ææ£ (LLJ) - Material Inspection |
| | | |
| | | 2. **Warehouse Management**: |
| | | - Purchase inventory management |
| | | - Material receipt and returns |
| | | - Location changes and transfers |
| | | - Barcode printing and scanning |
| | | |
| | | 3. **User Management**: |
| | | - Login/logout functionality |
| | | - User profile and settings |
| | | - Message center for notifications |
| | | |
| | | ## Development Environment |
| | | |
| | | This is a uni-app project with no traditional package.json build scripts. Development and building should be done through: |
| | | |
| | | 1. **HBuilderX IDE** (recommended uni-app development environment) |
| | | 2. **uni-app CLI** if using command line |
| | | |
| | | ### Build Commands |
| | | Since this is a uni-app project without npm scripts, use: |
| | | - Development: Open project in HBuilderX and use built-in dev server |
| | | - Build for production: Use HBuilderX build tools or uni-app CLI |
| | | - No traditional lint/test commands found in the codebase |
| | | |
| | | ### Key Configuration Files |
| | | - `manifest.json` - App configuration, permissions, and platform settings |
| | | - `pages.json` - Page routing and navigation configuration |
| | | - `uni.scss` - Global SCSS variables |
| | | - `App.vue` - Root component with global styles |
| | | |
| | | ### Development Workflow |
| | | 1. **Project Setup**: Open the project in HBuilderX IDE |
| | | 2. **Development**: Use HBuilderX's built-in development server for hot reload |
| | | 3. **Building**: Use HBuilderX's build tools to generate platform-specific builds |
| | | 4. **Testing**: Manual testing on real devices or emulators (no automated test suite) |
| | | |
| | | ## API and Data Flow |
| | | |
| | | ### Server Configuration |
| | | Server endpoints are configured in `store/index.js`: |
| | | - Local development: `http://localhost:10054/api` |
| | | - Internal network: `http://192.168.11.251:10054` |
| | | - Current active API: `http://localhost:10054/api` (configured in `serverAPI`) |
| | | |
| | | ### Network Environment Switching |
| | | The app supports switching between internal and external network environments via the `networkFlag` state in the Vuex store. |
| | | |
| | | ### Request Methods |
| | | Global request methods available on Vue prototype: |
| | | - `this.$get()` - GET requests with loading indicators |
| | | - `this.$post()` - POST requests with loading indicators |
| | | - `this.$postSyncPost()` - Synchronous POST requests |
| | | - `this.$toERP()` - ERP system requests |
| | | - `this.$uni_request()` - Core request wrapper |
| | | - `this.$uni_requestNew()` - Alternative request method |
| | | - `this.$sendPostRequest()` - Wrapper for ERP POST requests |
| | | |
| | | ### Global Utility Methods |
| | | Additional utility methods available on Vue prototype: |
| | | - `this.$camera()` - Camera and image selection functionality |
| | | - `this.$fileUpload()` - File upload with base64 encoding |
| | | - `this.$getDate()` - Date formatting utility |
| | | - `this.$getUrlParams()` - URL parameter extraction |
| | | - `this.$showMessage()` - Toast notification display |
| | | - `this.$showDialog()` - Modal dialog display |
| | | - `this.$setTitle()` - Navigation title setting |
| | | - `this.$getUserMenu()` - User menu retrieval |
| | | |
| | | ### Authentication |
| | | User authentication managed through: |
| | | - Login info stored in `this.$loginInfo` prototype |
| | | - User data persisted in uni.storage |
| | | - Forced login required (`forcedLogin: true`) |
| | | - Global authentication check via `globalMixin.js` (currently commented out) |
| | | - Session management with `this.$login()` and `this.$logout()` methods |
| | | |
| | | ## Mobile-Specific Features |
| | | |
| | | ### Hardware Integration |
| | | - **Camera**: Photo capture for QC inspections (configured in `manifest.json`) |
| | | - **Barcode Scanner**: For inventory and QC operations (Barcode module enabled) |
| | | - **Printer**: Bluetooth printing for labels and barcodes (via `kk-printer` component) |
| | | - **Audio**: Sound notifications for OK/NG status (located in `static/audio/`) |
| | | |
| | | ### Device Permissions |
| | | Configured in `manifest.json` for Android: |
| | | - Camera access for photo capture |
| | | - Storage access for file operations |
| | | - Network access for API communications |
| | | - Bluetooth for printer connectivity |
| | | |
| | | ### Platform Support |
| | | - Android permissions configured in `manifest.json` |
| | | - iOS configuration included |
| | | - Cross-platform compatibility via uni-app |
| | | |
| | | ## Common Patterns |
| | | |
| | | ### Page Navigation |
| | | Pages use uni-app navigation with parameters passed via URL query strings. Use `this.$getUrlParams(url)` to extract parameters. |
| | | |
| | | ### Data Validation |
| | | QC modules include image upload functionality for inspection records with base64 encoding. |
| | | |
| | | ### State Management |
| | | Vuex store maintains server configuration and app state. Network settings can be switched between internal/external environments. |
| | | |
| | | ### Error Handling |
| | | Global error handling through unified request methods with toast notifications for user feedback. |
| | | |
| | | ### Component Organization |
| | | - **Third-party Components**: Located in `components/` directory |
| | | - `kk-printer` - Bluetooth printer integration |
| | | - `uni-*` - Official uni-app UI components |
| | | - `mpvue-*` - Vue-based utility components |
| | | - **Custom Components**: Project-specific components in `components/` |
| | | - `page-head` and `page-foot` - Layout components |
| | | - `product.vue` - Product display component |
| | | |
| | | ### Code Style and Conventions |
| | | - Vue 2 syntax with Options API |
| | | - Chinese comments and variable names for business logic |
| | | - Prototype-based method attachment for global utilities |
| | | - Base64 encoding for image uploads |
| | | - Toast notifications for user feedback |
| | | - Modal dialogs for confirmations |
| | | |
| | | ### File Structure Conventions |
| | | - QC pages follow pattern: `List.vue` â `Add.vue` â `detail.vue` â `ImageItem.vue` |
| | | - Each QC module (XJ, SJ, RKJ, LLJ) has identical structure |
| | | - Warehouse operations follow similar patterns |
| | | - Test pages in `Test/` directory for development |
| | |
| | | "backgroundColor": "#fbf9fe" |
| | | }, |
| | | "pages": [ |
| | | |
| | | |
| | | //pagesæ°ç»ä¸ç¬¬ä¸é¡¹è¡¨ç¤ºåºç¨å¯å¨é¡µï¼åèï¼https://uniapp.dcloud.io/collocation/pages |
| | | { |
| | | "path": "pages/BasePages/login", |
| | |
| | | "navigationBarTitleText": "å
¥åºæ£" |
| | | } |
| | | }, |
| | | |
| | | |
| | | { |
| | | "path": "pages/QC/RKJ/Add", |
| | | "style": { |
| | |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/PurchaseInventory/PurchaseInventory", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "éè´å
¥åº" |
| | | "path": "pages/Warehouse/PurchaseInventory/PurchaseInventory", |
| | | "style": { |
| | | "navigationBarTitleText": "éè´å
¥åº" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/PurchaseInventory/Cgrk", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "éè´å
¥åºå" |
| | | "path": "pages/Warehouse/PurchaseInventory/Cgrk", |
| | | "style": { |
| | | "navigationBarTitleText": "éè´å
¥åºå" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/PurchaseInventory/Add", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "éè´å
¥åºåæç»" |
| | | "path": "pages/Warehouse/PurchaseInventory/Add", |
| | | "style": { |
| | | "navigationBarTitleText": "éè´å
¥åºåæç»" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Test/scanTest", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "æ«ç æµè¯" |
| | | "path": "pages/Test/scanTest", |
| | | "style": { |
| | | "navigationBarTitleText": "æ«ç æµè¯" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/PurchaseReturn/Cgth", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "éè´éè´§" |
| | | "path": "pages/Warehouse/PurchaseReturn/Cgth", |
| | | "style": { |
| | | "navigationBarTitleText": "éè´éè´§" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/PurchaseReturn/Add", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "æ·»å éè´éæå" |
| | | "path": "pages/Warehouse/PurchaseReturn/Add", |
| | | "style": { |
| | | "navigationBarTitleText": "æ·»å éè´éæå" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/PurchaseReturn/PurchaseReturn", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "éè´éææ«ç " |
| | | "path": "pages/Warehouse/PurchaseReturn/PurchaseReturn", |
| | | "style": { |
| | | "navigationBarTitleText": "éè´éææ«ç " |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/BasePages/information", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "ä¿¡æ¯è¯¦æ
" |
| | | "path": "pages/BasePages/information", |
| | | "style": { |
| | | "navigationBarTitleText": "ä¿¡æ¯è¯¦æ
" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/OpeningReceipt/OpeningReceipt", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "æåå
¥åºæ«ç " |
| | | "path": "pages/Warehouse/OpeningReceipt/OpeningReceipt", |
| | | "style": { |
| | | "navigationBarTitleText": "æåå
¥åºæ«ç " |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Allocation/In", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "è°æ¨å
¥åº" |
| | | "path": "pages/Allocation/In", |
| | | "style": { |
| | | "navigationBarTitleText": "è°æ¨å
¥åº" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Allocation/Out", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "è°æ¨åºåº" |
| | | "path": "pages/Allocation/Out", |
| | | "style": { |
| | | "navigationBarTitleText": "è°æ¨åºåº" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/ChangeOfLocation/ChangeOfLocation", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "åºä½åæ´" |
| | | "path": "pages/Warehouse/ChangeOfLocation/ChangeOfLocation", |
| | | "style": { |
| | | "navigationBarTitleText": "åºä½åæ´" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Test/testPrint", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "æå°æµè¯" |
| | | "path": "pages/Test/testPrint", |
| | | "style": { |
| | | "navigationBarTitleText": "æå°æµè¯" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/BarcodePrint/BarcodePrint", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "æåæ¡ç æå°" |
| | | "path": "pages/BarcodePrint/BarcodePrint", |
| | | "style": { |
| | | "navigationBarTitleText": "æåæ¡ç æå°" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/MaterialReceipt/MaterialReceipt", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "ç©ææ¥æ¶" |
| | | "path": "pages/Warehouse/MaterialReceipt/MaterialReceipt", |
| | | "style": { |
| | | "navigationBarTitleText": "ç©ææ¥æ¶" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/ProductionPick/ProductionPick", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "çäº§é¢æ" |
| | | "path": "pages/Warehouse/ProductionPick/ProductionPick", |
| | | "style": { |
| | | "navigationBarTitleText": "çäº§é¢æ" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/ProductionPick/List", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "çäº§é¢æå" |
| | | "path": "pages/Warehouse/ProductionPick/List", |
| | | "style": { |
| | | "navigationBarTitleText": "çäº§é¢æå" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/Warehouse/ProductionPick/Add", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "çäº§é¢æå" |
| | | "path": "pages/Warehouse/ProductionPick/Add", |
| | | "style": { |
| | | "navigationBarTitleText": "çäº§é¢æå" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/BasePages/treated", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "å¾
å¤ç" |
| | | } |
| | | }, |
| | | { |
| | | "path": "pages/Device/Spotcheck", |
| | | "style": { |
| | | "navigationBarTitleText": "设å¤ç¹æ£", |
| | | "enablePullDownRefresh": false |
| | | } |
| | | } |
| | | |
| | | "path": "pages/BasePages/treated", |
| | | "style": { |
| | | "navigationBarTitleText": "å¾
å¤ç" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/QC/OQC/List", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "OQCæ£éª" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/QC/OQC/ScanCode", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "OQCæ£éª" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/QC/OQC/Add", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/QC/OQC/ImageItem", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "å¾çæ¥ç" |
| | | } |
| | | }, |
| | | { |
| | | "path" : "pages/QC/OQC/detail", |
| | | "style" : |
| | | { |
| | | "navigationBarTitleText" : "æ£éªè¯¦æ
" |
| | | } |
| | | } |
| | | // { |
| | | // "path": "pages/Device/Spotcheck", |
| | | // "style": { |
| | | // "navigationBarTitleText": "设å¤ç¹æ£", |
| | | // "enablePullDownRefresh": false |
| | | // } |
| | | // } |
| | | |
| | | ] |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view class="page-container"> |
| | | <!-- 表åå®¹å¨ --> |
| | | <view class="form-card"> |
| | | <form :modelValue="formData"> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ£éªåå·:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.releaseNo" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">ç©æç¼ç :</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.itemNo" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">ç©æåç§°:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.itemName" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">ç©æè§æ ¼:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.itemModel" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">订åç¼å·:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.saleOrderNo" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">鿣æ°é:</label> |
| | | <input class="form-input" disabled="true" type="number" v-model="formData.planQty" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">å建æ¶é´:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.createDate" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">å建人:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.createUser" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">ä¸è¯æè¿°:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.remeke" /> |
| | | </view> |
| | | </form> |
| | | </view> |
| | | |
| | | <!-- æ£éªé¡¹ç®å¡ç --> |
| | | <view class="inspection-card"> |
| | | <view class="card-header"> |
| | | <view class="header-icon">ð</view> |
| | | <text class="header-title">æ£éªé¡¹ç®</text> |
| | | <view class="header-badge">{{ tableData.length }}</view> |
| | | </view> |
| | | |
| | | <view class="inspection-list" v-if="tableData.length > 0"> |
| | | <view v-for="(item, index) in tableData" :key="index" class="inspection-item" |
| | | :class="{ 'item-completed': item.fcheckResu === 'åæ ¼', 'item-failed': item.fcheckResu === 'ä¸åæ ¼' }"> |
| | | |
| | | <!-- å·¦ä¾§ç¶ææç¤ºå¨ --> |
| | | <view class="status-indicator" |
| | | :class="{ 'status-pass': item.fcheckResu === 'åæ ¼', 'status-fail': item.fcheckResu === 'ä¸åæ ¼', 'status-pending': item.fcheckResu === 'æªæ£éª' }"> |
| | | </view> |
| | | |
| | | <!-- 主è¦å
容åºå --> |
| | | <view class="item-content"> |
| | | <view class="item-header"> |
| | | <view class="item-title">{{ item.fcheckItem }}</view> |
| | | <view class="status-badge" |
| | | :class="{ 'badge-pass': item.fcheckResu === 'åæ ¼', 'badge-fail': item.fcheckResu === 'ä¸åæ ¼', 'badge-pending': item.fcheckResu === 'æªæ£éª' }"> |
| | | <text class="status-icon">{{ item.fcheckResu === 'åæ ¼' ? 'â' : item.fcheckResu === 'ä¸åæ ¼' ? 'â' : 'â' }}</text> |
| | | <text class="status-text">{{ item.fcheckResu }}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="item-description" v-if="item.fcheckItemDesc"> |
| | | <text class="description-text">{{ item.fcheckItemDesc }}</text> |
| | | </view> |
| | | |
| | | <view class="item-footer"> |
| | | <view class="progress-info"> |
| | | <text class="progress-label">æ£éªè¿åº¦:</text> |
| | | <view class="progress-bar"> |
| | | <view class="progress-fill" |
| | | :style="{ width: (item.fenterQty / item.checkQyt * 100) + '%' }" |
| | | :class="{ 'progress-complete': item.fenterQty >= item.checkQyt, 'progress-incomplete': item.fenterQty < item.checkQyt }"> |
| | | </view> |
| | | </view> |
| | | <text class="progress-text">{{ item.fenterQty }}/{{ item.checkQyt }}</text> |
| | | </view> |
| | | |
| | | <view class="action-button" @click="toDetail(item)" |
| | | :class="{ 'btn-complete': item.fenterQty >= item.checkQyt, 'btn-incomplete': item.fenterQty < item.checkQyt }"> |
| | | <text class="btn-text">{{ item.fenterQty >= item.checkQyt ? 'æ¥ç详æ
' : 'å¼å§æ£éª' }}</text> |
| | | <text class="btn-icon">â</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- ç©ºç¶æ --> |
| | | <view v-else class="empty-state"> |
| | | <view class="empty-icon">ð</view> |
| | | <text class="empty-text">ææ æ£éªé¡¹ç®</text> |
| | | <text class="empty-desc">请å
çææ£éªé¡¹ç®</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æä½æé®åºå --> |
| | | <view class="action-buttons"> |
| | | <button class="btn btn-primary" @click="submitInspection">æäº¤</button> |
| | | <button class="secondary-btn" @click="uploadImages">ä¸ä¼ /æ¥çå¾ç</button> |
| | | <button class="btn btn-secondary" @click="addDefectDescription">æ·»å ä¸åæ ¼æè¿°</button> |
| | | </view> |
| | | |
| | | |
| | | <!-- ä¸åæ ¼æè¿°å¼¹åºå± --> |
| | | <view v-if="remarksPopup" class="overlay active"> |
| | | <view class="popup" :class="{ 'popup-scale': isPopupAnimated }" @animationend="isPopupAnimated = false"> |
| | | <view class="popup-header"> |
| | | <h3 class="popup-title">ä¿®æ¹ä¸åæ ¼æè¿°</h3> |
| | | <view class="close-btn" @click="remarksPopup = !remarksPopup">Ã</view> |
| | | </view> |
| | | <form> |
| | | <view class="form-group"> |
| | | <label class="form-label">ä¸åæ ¼æè¿°:</label> |
| | | <input class="form-input" type="text" v-model="remarks" /> |
| | | </view> |
| | | <view class="button-group popup-buttons"> |
| | | <button :class="['action-btn', 'btn-danger']" @click="editRemarks"> |
| | | ä¿®æ¹ |
| | | </button> |
| | | <button :class="['action-btn', 'btn-light']" @click="remarksPopup = !remarksPopup"> |
| | | åæ¶ |
| | | </button> |
| | | </view> |
| | | </form> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | formData: {}, |
| | | tableData: [], |
| | | remarks: "", |
| | | remarksPopup: false, |
| | | isPopupAnimated: false, |
| | | } |
| | | }, |
| | | onLoad(options) { |
| | | //optionsä¸å
å«äºurlé带çåæ° |
| | | let params = options; |
| | | |
| | | if (params["id"]) { |
| | | this.formData.id = params["id"]; |
| | | this.init(); |
| | | } |
| | | }, |
| | | methods: { |
| | | init() { |
| | | let userName = this.$loginInfo.account; |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/getPage", |
| | | data: { |
| | | id: this.formData.id, |
| | | createUser: userName, |
| | | pageIndex: 1, |
| | | limit: 1, |
| | | } |
| | | }).then(res => { |
| | | let data = res.data[0]; |
| | | if (data) { |
| | | this.formData = data; |
| | | this.getDetail5(); |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | getDetail5() { |
| | | let userName = this.$loginInfo.account; |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/GetDetail5", |
| | | data: { |
| | | id: this.formData.id, |
| | | createUser: userName, |
| | | releaseNo: this.formData.releaseNo, |
| | | } |
| | | }).then(res => { |
| | | let data = res.data; |
| | | this.tableData = data; |
| | | }); |
| | | }, |
| | | uploadImages() { |
| | | // ä¸ä¼ /æ¥çå¾ççé»è¾ |
| | | uni.navigateTo({ |
| | | url: 'ImageItem?id=' + this.formData.releaseNo |
| | | }); |
| | | }, |
| | | addDefectDescription() { |
| | | // ç¡®ä¿è¡¨åæ°æ®åå¨ |
| | | if (!this.formData) return; |
| | | |
| | | this.remarksPopup = !this.remarksPopup; |
| | | this.remarks = this.formData.remeke || ''; |
| | | this.isPopupAnimated = true; |
| | | }, |
| | | toDetail(item) { |
| | | |
| | | uni.navigateTo({ |
| | | url: 'detail?mainId=' + item.id + '&releaseNo=' + this.formData |
| | | .releaseNo |
| | | }); |
| | | |
| | | }, |
| | | submitInspection() { |
| | | // æ£éªæäº¤çé»è¾ |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/IqcQaSubmit", |
| | | data: { |
| | | userNo: this.$loginInfo.account, |
| | | releaseNo: this.formData.releaseNo |
| | | } |
| | | }).then(res => { |
| | | if (res.status == 0) { |
| | | |
| | | uni.showToast({ |
| | | title: res.message.toString(), |
| | | icon: 'success', |
| | | duration: 2000 |
| | | }) |
| | | // 妿æé¡µé¢è·³è½¬ï¼éè¦ç¨å®æ¶å¨å»¶è¿ |
| | | setTimeout(() => { |
| | | uni.navigateTo({ |
| | | url: 'List' |
| | | }); |
| | | }, 2000); // ä¿æä¸ duration ç¸åçæ¶é¿ |
| | | |
| | | } else { |
| | | uni.showModal({ |
| | | title: "æç¤º", |
| | | content: res.message.toString(), |
| | | confirmText: "ç¡®å®", |
| | | showCancel: false, |
| | | success: (res) => { |
| | | |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | editRemarks() { |
| | | if (this.remarks && this.formData.id) { |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/saveRemarksGid", |
| | | data: { |
| | | gid: this.formData.id, |
| | | remarks: this.remarks, |
| | | releaseNo: this.formData.releaseNo, |
| | | } |
| | | }).then(res => { |
| | | if (res.data.tbBillList > 0) { |
| | | this.formData.remarks = this.remarks; |
| | | this.remarksPopup = false; |
| | | this.$showMessage("ä¿åæå"); |
| | | this.init(); |
| | | } else { |
| | | this.$showMessage("ä¿å失败"); |
| | | } |
| | | }).catch(() => { |
| | | this.$showMessage("ä¿å失败ï¼è¯·éè¯"); |
| | | }); |
| | | } else if (!this.formData.id) { |
| | | this.$showMessage("请å
çææ£éªå"); |
| | | } else { |
| | | this.$showMessage("请è¾å
¥ä¸åæ ¼æè¿°"); |
| | | } |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .page-container { |
| | | padding: 20px; |
| | | background-color: #f5f5f5; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | /* 表åå¡ç */ |
| | | .form-card { |
| | | background-color: #fff; |
| | | border-radius: 12px; |
| | | padding: 20px; |
| | | margin-bottom: 20px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | /* 表åç» */ |
| | | .form-group { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .form-group:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | /* æ ç¾æ ·å¼ */ |
| | | .form-label { |
| | | width: 120px; |
| | | color: #333; |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | /* è¾å
¥æ¡æ ·å¼ */ |
| | | .form-input { |
| | | flex: 1; |
| | | height: 40px; |
| | | padding: 0 10px; |
| | | border: 1px solid #e0e0e0; |
| | | border-radius: 8px; |
| | | background-color: #f8f8f8; |
| | | color: #666; |
| | | font-size: 14px; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .form-input:disabled { |
| | | background-color: #e9e9e9; |
| | | } |
| | | |
| | | .form-input:focus { |
| | | border-color: #007AFF; |
| | | outline: none; |
| | | } |
| | | |
| | | /* æä½æé®åºå */ |
| | | .action-buttons { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | gap: 15px; |
| | | padding: 15px 0; |
| | | } |
| | | |
| | | .btn { |
| | | flex: 1; |
| | | height: 45px; |
| | | border-radius: 8px; |
| | | border: none; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | transition: background-color 0.3s ease; |
| | | } |
| | | |
| | | .btn-primary { |
| | | background-color: #007AFF; |
| | | } |
| | | |
| | | .btn-primary:hover { |
| | | background-color: #0056CC; |
| | | } |
| | | |
| | | .secondary-btn { |
| | | background-color: #8E8E93; |
| | | } |
| | | |
| | | .secondary-btn:hover { |
| | | background-color: #6D6D70; |
| | | } |
| | | |
| | | .btn-secondary { |
| | | background-color: #8E8E93; |
| | | } |
| | | |
| | | .btn-secondary:hover { |
| | | background-color: #6D6D70; |
| | | } |
| | | |
| | | /* æ£éªé¡¹ç®å¡ç */ |
| | | .inspection-card { |
| | | background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%); |
| | | border-radius: 16px; |
| | | padding: 0; |
| | | margin-bottom: 24px; |
| | | box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08); |
| | | border: 1px solid #e2e8f0; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | /* å¡çå¤´é¨ */ |
| | | .card-header { |
| | | background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%); |
| | | padding: 20px 24px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | position: relative; |
| | | } |
| | | |
| | | .card-header::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: linear-gradient(45deg, rgba(255,255,255,0.1) 0%, transparent 100%); |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .header-icon { |
| | | font-size: 24px; |
| | | margin-right: 12px; |
| | | } |
| | | |
| | | .header-title { |
| | | color: white; |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | flex: 1; |
| | | } |
| | | |
| | | .header-badge { |
| | | background: rgba(255, 255, 255, 0.2); |
| | | color: white; |
| | | padding: 6px 12px; |
| | | border-radius: 20px; |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | backdrop-filter: blur(10px); |
| | | } |
| | | |
| | | /* æ£éªå表 */ |
| | | .inspection-list { |
| | | padding: 24px; |
| | | } |
| | | |
| | | .inspection-item { |
| | | background: white; |
| | | border-radius: 12px; |
| | | margin-bottom: 16px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); |
| | | border: 1px solid #e2e8f0; |
| | | overflow: hidden; |
| | | transition: all 0.3s ease; |
| | | position: relative; |
| | | } |
| | | |
| | | .inspection-item:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); |
| | | } |
| | | |
| | | .inspection-item:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .inspection-item.item-completed { |
| | | border-left: 4px solid #10b981; |
| | | background: linear-gradient(135deg, #ffffff 0%, #f0fdf4 100%); |
| | | } |
| | | |
| | | .inspection-item.item-failed { |
| | | border-left: 4px solid #ef4444; |
| | | background: linear-gradient(135deg, #ffffff 0%, #fef2f2 100%); |
| | | } |
| | | |
| | | /* ç¶ææç¤ºå¨ */ |
| | | .status-indicator { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | bottom: 0; |
| | | width: 4px; |
| | | background: #e2e8f0; |
| | | } |
| | | |
| | | .status-indicator.status-pass { |
| | | background: linear-gradient(180deg, #10b981 0%, #059669 100%); |
| | | } |
| | | |
| | | .status-indicator.status-fail { |
| | | background: linear-gradient(180deg, #ef4444 0%, #dc2626 100%); |
| | | } |
| | | |
| | | .status-indicator.status-pending { |
| | | background: linear-gradient(180deg, #f59e0b 0%, #d97706 100%); |
| | | } |
| | | |
| | | /* 项ç®å
容 */ |
| | | .item-content { |
| | | padding: 20px 24px; |
| | | margin-left: 4px; |
| | | } |
| | | |
| | | .item-header { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .item-title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #1e293b; |
| | | flex: 1; |
| | | } |
| | | |
| | | .status-badge { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 6px 12px; |
| | | border-radius: 20px; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .status-badge.badge-pass { |
| | | background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%); |
| | | color: #166534; |
| | | border: 1px solid #86efac; |
| | | } |
| | | |
| | | .status-badge.badge-fail { |
| | | background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%); |
| | | color: #991b1b; |
| | | border: 1px solid #fca5a5; |
| | | } |
| | | |
| | | .status-badge.badge-pending { |
| | | background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); |
| | | color: #92400e; |
| | | border: 1px solid #fcd34d; |
| | | } |
| | | |
| | | .status-icon { |
| | | margin-right: 6px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | /* é¡¹ç®æè¿° */ |
| | | .item-description { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .description-text { |
| | | color: #64748b; |
| | | font-size: 14px; |
| | | line-height: 1.5; |
| | | background: #f8fafc; |
| | | padding: 12px 16px; |
| | | border-radius: 8px; |
| | | border-left: 3px solid #e2e8f0; |
| | | } |
| | | |
| | | /* 项ç®åºé¨ */ |
| | | .item-footer { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | gap: 16px; |
| | | } |
| | | |
| | | .progress-info { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 12px; |
| | | flex: 1; |
| | | } |
| | | |
| | | .progress-label { |
| | | font-size: 14px; |
| | | color: #64748b; |
| | | font-weight: 500; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .progress-bar { |
| | | flex: 1; |
| | | height: 8px; |
| | | background: #e2e8f0; |
| | | border-radius: 4px; |
| | | overflow: hidden; |
| | | position: relative; |
| | | } |
| | | |
| | | .progress-fill { |
| | | height: 100%; |
| | | border-radius: 4px; |
| | | transition: all 0.3s ease; |
| | | position: relative; |
| | | } |
| | | |
| | | .progress-fill.progress-complete { |
| | | background: linear-gradient(90deg, #10b981 0%, #059669 100%); |
| | | } |
| | | |
| | | .progress-fill.progress-incomplete { |
| | | background: linear-gradient(90deg, #f59e0b 0%, #d97706 100%); |
| | | } |
| | | |
| | | .progress-text { |
| | | font-size: 14px; |
| | | color: #374151; |
| | | font-weight: 600; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | /* æä½æé® */ |
| | | .action-button { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | padding: 10px 16px; |
| | | border-radius: 8px; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .action-button.btn-complete { |
| | | background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%); |
| | | color: #1e40af; |
| | | border: 1px solid #93c5fd; |
| | | } |
| | | |
| | | .action-button.btn-complete:hover { |
| | | background: linear-gradient(135deg, #bfdbfe 0%, #93c5fd 100%); |
| | | transform: translateX(4px); |
| | | } |
| | | |
| | | .action-button.btn-incomplete { |
| | | background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); |
| | | color: #92400e; |
| | | border: 1px solid #fcd34d; |
| | | } |
| | | |
| | | .action-button.btn-incomplete:hover { |
| | | background: linear-gradient(135deg, #fde68a 0%, #fcd34d 100%); |
| | | transform: translateX(4px); |
| | | } |
| | | |
| | | .btn-text { |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .btn-icon { |
| | | font-size: 16px; |
| | | transition: transform 0.3s ease; |
| | | } |
| | | |
| | | .action-button:hover .btn-icon { |
| | | transform: translateX(4px); |
| | | } |
| | | |
| | | /* ç©ºç¶æ */ |
| | | .empty-state { |
| | | padding: 60px 24px; |
| | | text-align: center; |
| | | background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); |
| | | } |
| | | |
| | | .empty-icon { |
| | | font-size: 48px; |
| | | margin-bottom: 16px; |
| | | opacity: 0.6; |
| | | } |
| | | |
| | | .empty-text { |
| | | font-size: 18px; |
| | | color: #64748b; |
| | | font-weight: 500; |
| | | margin-bottom: 8px; |
| | | display: block; |
| | | } |
| | | |
| | | .empty-desc { |
| | | font-size: 14px; |
| | | color: #94a3b8; |
| | | display: block; |
| | | } |
| | | |
| | | /* ååºå¼è®¾è®¡ */ |
| | | @media (max-width: 768px) { |
| | | .inspection-card { |
| | | margin: 0 -8px 24px -8px; |
| | | border-radius: 12px; |
| | | } |
| | | |
| | | .card-header { |
| | | padding: 16px 20px; |
| | | } |
| | | |
| | | .header-title { |
| | | font-size: 16px; |
| | | } |
| | | |
| | | .inspection-list { |
| | | padding: 16px 20px; |
| | | } |
| | | |
| | | .item-content { |
| | | padding: 16px 20px; |
| | | } |
| | | |
| | | .item-header { |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .item-footer { |
| | | flex-direction: column; |
| | | align-items: stretch; |
| | | gap: 12px; |
| | | } |
| | | |
| | | .progress-info { |
| | | flex-direction: column; |
| | | align-items: stretch; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .action-button { |
| | | justify-content: center; |
| | | } |
| | | } |
| | | |
| | | /* è¾å
¥æ¡ä¸æ¾ç¤ºçå·¥å
·æç¤º */ |
| | | .value-with-tooltip { |
| | | position: relative; |
| | | } |
| | | |
| | | .value-with-tooltip .tooltip { |
| | | position: absolute; |
| | | top: -30px; |
| | | left: 0; |
| | | background-color: rgba(0, 0, 0, 0.6); |
| | | color: #fff; |
| | | font-size: 12px; |
| | | padding: 5px; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | /* å¼¹åºå±æ ·å¼ */ |
| | | .overlay { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: rgba(0, 0, 0, 0.5); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | z-index: 1000; |
| | | opacity: 0; |
| | | transition: opacity 0.3s ease; |
| | | } |
| | | |
| | | .overlay.active { |
| | | opacity: 1; |
| | | } |
| | | |
| | | .popup { |
| | | background-color: #fff; |
| | | border-radius: 12px; |
| | | width: 90%; |
| | | max-width: 500px; |
| | | padding: 20px; |
| | | transform: scale(0.8); |
| | | transition: transform 0.3s ease; |
| | | } |
| | | |
| | | .popup-scale { |
| | | transform: scale(1); |
| | | } |
| | | |
| | | .popup-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .popup-title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #333; |
| | | } |
| | | |
| | | .close-btn { |
| | | font-size: 20px; |
| | | color: #333; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .button-group { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .action-btn { |
| | | width: 48%; |
| | | padding: 10px; |
| | | border-radius: 8px; |
| | | border: none; |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .btn-danger { |
| | | background-color: #dc3545; |
| | | color: #fff; |
| | | } |
| | | |
| | | .btn-light { |
| | | background-color: #f8f8f8; |
| | | color: #333; |
| | | } |
| | | |
| | | .btn-danger:hover { |
| | | background-color: #c82333; |
| | | } |
| | | |
| | | .btn-light:hover { |
| | | background-color: #e9e9e9; |
| | | } |
| | | |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <!-- #ifdef APP --> |
| | | <scroll-view class="page-scroll-view"> |
| | | <!-- #endif --> |
| | | <view> |
| | | <view class="uni-common-mt"> |
| | | <view class="uni-list list-pd" style="padding: 15px;"> |
| | | <view class="uni-flex" style="margin-bottom: 10px;"> |
| | | <view class="uni-list-cell-left">ç¹å»å¯é¢è§é好çå¾ç</view> |
| | | <view style="margin-left: auto;"> |
| | | <view class="click-t">å
±æ{{ qsImage.length }}å¼ å¾ç</view> |
| | | </view> |
| | | </view> |
| | | <view class="uni-flex" style="flex-wrap: wrap;"> |
| | | <view v-for="(image,index) in qsImage" :key="index" class="uni-uploader__input-box" |
| | | style="position: relative; border: 0;"> |
| | | <image :src="image.img" :data-src="image.img" |
| | | @tap="previewImage(index)"></image> |
| | | <image src="/static/plus.png" class="image-remove" @click="removeImage(index,image.id)"></image> |
| | | </view> |
| | | <image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="plus-button"> |
| | | <button type="primary" class="upImg" @click="save">ä¸ä¼ å¾ç</button> |
| | | </view> |
| | | </view> |
| | | <!-- #ifdef APP --> |
| | | </scroll-view> |
| | | <!-- #endif --> |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | import {pathToBase64, base64ToPath} from '../../../js_sdk/mmmm-image-tools/index' |
| | | |
| | | var sourceTypeArray = [ |
| | | ['camera'], |
| | | ['album'], |
| | | ['camera', 'album'] |
| | | ] |
| | | var sizeTypeArray = [ |
| | | ['compressed'], |
| | | ['original'], |
| | | ['compressed', 'original'] |
| | | ] |
| | | export default { |
| | | data() { |
| | | return { |
| | | title: 'choose/previewImage', |
| | | sourceTypeIndex: 2, |
| | | sourceType: ['æç
§', 'ç¸å', 'æç
§æç¸å'], |
| | | sizeTypeIndex: 2, |
| | | sizeType: ['å缩', 'åå¾', 'å缩æåå¾'], |
| | | countIndex: 8, |
| | | count: [1, 2, 3, 4, 5, 6, 7, 8, 9], |
| | | isCrop: false, |
| | | cropPercent: 80, |
| | | cropWidth: 100, |
| | | cropHeight: 100, |
| | | cropResize: false, |
| | | qsImage: [], |
| | | fid: 0, |
| | | qsType : 5, |
| | | } |
| | | }, |
| | | onLoad(options) { |
| | | //optionsä¸å
å«äºurlé带çåæ° |
| | | |
| | | let params = options; |
| | | |
| | | if (params["id"]) { |
| | | this.fid = params["id"]; |
| | | //getQaItemXj02 |
| | | this.init(); |
| | | } |
| | | }, |
| | | onUnload() { |
| | | this.qsImage = []; |
| | | this.sourceTypeIndex = 2 |
| | | this.sourceType = ['æç
§', 'ç¸å', 'æç
§æç¸å'] |
| | | this.sizeTypeIndex = 2 |
| | | this.sizeType = ['å缩', 'åå¾', 'å缩æåå¾'] |
| | | this.countIndex = 8 |
| | | }, |
| | | methods: { |
| | | removeImage(index, id) { |
| | | this.qsImage.splice(index, 1); |
| | | if (id) { |
| | | this.$post({ |
| | | url: "/Base/removeImage", |
| | | data: { |
| | | id: id |
| | | } |
| | | }).then(res => { |
| | | }); |
| | | } |
| | | }, |
| | | chooseImage() { |
| | | if (this.qsImage.length >= 9) { |
| | | uni.showToast({ |
| | | position: "bottom", |
| | | title: "å·²ç»æ9å¼ å¾çäºï¼è¯·å é¤é¨åå¾çä¹åéæ°éæ©" |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | uni.chooseImage({ |
| | | sourceType: sourceTypeArray[this.sourceTypeIndex], |
| | | sizeType: sizeTypeArray[this.sizeTypeIndex], |
| | | crop: this.isCrop ? { |
| | | "quality": this.cropPercent, |
| | | "width": this.cropWidth, |
| | | "height": this.cropHeight, |
| | | "resize": this.cropResize |
| | | } : null, |
| | | count: this.qsImage.length + this.count[this.countIndex] > 9 ? 9 - this.qsImage.length : this.count[this.countIndex], |
| | | success: (res) => { |
| | | let url = res.tempFilePaths[0]; |
| | | pathToBase64(url) |
| | | .then(base64 => { |
| | | // æ¾å°æåä¸ä¸ªææ çä½ç½® |
| | | let lastSlashIndex = url.lastIndexOf("/"); |
| | | // æåæä»¶å |
| | | let fileName = url.substring(lastSlashIndex + 1); |
| | | let entity = {}; |
| | | entity.img = base64; |
| | | entity.Picturename = fileName; |
| | | entity.fid = this.fid; |
| | | entity.qsType = this.qsType; |
| | | entity.base64Date = base64.split(',')[1]; |
| | | |
| | | this.qsImage.push(entity); |
| | | }) |
| | | .catch(error => { |
| | | console.error(error) |
| | | }) |
| | | }, |
| | | fail: (err) => { |
| | | console.log("err: ", JSON.stringify(err)); |
| | | } |
| | | }); |
| | | }, |
| | | previewImage(index) { |
| | | // uni.previewImage({ |
| | | // current: index, // 设置å½åæ¾ç¤ºå¾çç龿¥ |
| | | // urls: this.qsImage.map(s=>s.img), // éè¦é¢è§çå¾ç龿¥å表 |
| | | // loop: false, // æ¯å¦å¼å¯å¾çè½®æï¼é»è®¤ä¸º false |
| | | // indicator: 'default',// å¾çæç¤ºå¨ç±»åï¼å¯éå¼ä¸º "default"ã"number"ã"pointer"ï¼é»è®¤ä¸º "default" |
| | | // }); |
| | | }, |
| | | init() { |
| | | this.$post({ |
| | | url: "/Base/getLljAllImgByFid", |
| | | data: { |
| | | id: this.fid, |
| | | qsType: this.qsType |
| | | } |
| | | }).then(res => { |
| | | let tableData = res.data.tbBillList; |
| | | this.qsImage = tableData; |
| | | this.qsImage.forEach(s => { |
| | | s.img = 'data:image/png;base64,' + s.base64Date; |
| | | }); |
| | | }); |
| | | }, |
| | | save() { |
| | | this.$post({ |
| | | url: "/Base/saveImage", |
| | | data: { |
| | | entity: this.qsImage |
| | | } |
| | | }).then(res => { |
| | | this.init(); |
| | | this.$showMessage("ä¿åæå"); |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .click-t { |
| | | color: darkgray; |
| | | } |
| | | |
| | | .list-pd { |
| | | margin-top: 25px; |
| | | } |
| | | |
| | | .uni-uploader__input-box { |
| | | margin: 5px; |
| | | border: 1px solid #D9D9D9; |
| | | } |
| | | |
| | | .image-remove { |
| | | transform: rotate(45deg); |
| | | width: 25px; |
| | | height: 25px; |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | border-radius: 13px; |
| | | background-color: #FF0000; |
| | | } |
| | | |
| | | .uni-common-mt { |
| | | background-color: #ffffff; |
| | | /* 红è²èæ¯ */ |
| | | } |
| | | |
| | | .plus-button { |
| | | position: fixed; |
| | | left: 0; |
| | | bottom: 0; |
| | | width: 100%; |
| | | background-color: #ffffff; /* èæ¯é¢è² */ |
| | | /* padding: 10px; */ |
| | | box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1); /* æ·»å åºé¨é´å½±ææ */ |
| | | z-index: 999; /* ç¡®ä¿æé®ä½äºé¡¶å± */ |
| | | } |
| | | |
| | | .uni-flex { |
| | | max-height: calc(100vh - 240px); /* å±å¹é«åº¦åå»ä¸ä¼ æé®é«åº¦ */ |
| | | overflow-y: auto; /* å½å
容è¶
åºé«åº¦æ¶åºç°åç´æ»å¨æ¡ */ |
| | | } |
| | | .upImg{ |
| | | |
| | | background-color: #3498db; |
| | | color: white; |
| | | |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view class="page-container"> |
| | | <!-- å·æ°æç¤ºæ¡ --> |
| | | <view class="success-toast" :class="{ 'show': tipShow }"> |
| | | <view class="toast-icon">â</view> |
| | | <text class="toast-text">å·æ°æå</text> |
| | | </view> |
| | | |
| | | <!-- 头é¨åºå --> |
| | | <view class="header-section"> |
| | | <!-- 页颿 é¢ --> |
| | | <view class="page-header"> |
| | | <view class="header-content"> |
| | | <view class="title-section"> |
| | | <text class="page-title">OQCæ£éªå</text> |
| | | <text class="page-subtitle">è´¨éæ£éªç®¡ç</text> |
| | | </view> |
| | | <view class="stats-badge"> |
| | | <text class="stats-number">{{ totalCount }}</text> |
| | | <text class="stats-label">æ»è®¡</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æç´¢æ --> |
| | | <!-- <view class="search-section"> --> |
| | | <!-- <view class="search-container"> |
| | | <view class="search-input-wrapper"> |
| | | <uni-icons type="search" size="18" color="#94a3b8"></uni-icons> |
| | | <input class="search-input" type="text" v-model="searchValue" |
| | | @confirm="getInputValue" placeholder="æç´¢æ£éªåå·ãç©æç¼ç ..." /> |
| | | <view v-if="searchValue" class="clear-btn" @tap="clearSearch"> |
| | | <uni-icons type="clear" size="16" color="#94a3b8"></uni-icons> |
| | | </view> |
| | | </view> |
| | | <view class="filter-btn" @tap="toggleFilter"> |
| | | <uni-icons type="tune" size="18" color="#4f46e5"></uni-icons> |
| | | </view> |
| | | </view> --> |
| | | |
| | | <!-- çéå¨ --> |
| | | <!-- <view v-if="showFilter" class="filter-panel"> |
| | | <picker mode="selector" :range="searchOptions" v-model="selectedOption" @change="onPickerChange"> |
| | | <view class="filter-option"> |
| | | <text class="filter-label">ç鿡件</text> |
| | | <text class="filter-value">{{ searchOptions[selectedOption] }}</text> |
| | | <uni-icons type="arrowdown" size="14" color="#64748b"></uni-icons> |
| | | </view> |
| | | </picker> |
| | | </view> --> |
| | | <!-- </view> --> |
| | | |
| | | <!-- éé¡¹å¡ --> |
| | | <view class="tab-section"> |
| | | <view class="custom-tabs"> |
| | | <view v-for="(item, index) in items" :key="index" |
| | | class="tab-item" :class="{ 'active': current === index }" |
| | | @tap="onClickItem({ currentIndex: index })"> |
| | | <text class="tab-text">{{ item }}</text> |
| | | <view class="tab-indicator" v-if="current === index"></view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- å
容åºå --> |
| | | <view class="content-container"> |
| | | <view v-show="current === 0"> |
| | | <!-- å è½½ç¶æ --> |
| | | <view v-if="isLoading" class="loading-state"> |
| | | <view class="loading-spinner"></view> |
| | | <text class="loading-text">å è½½ä¸...</text> |
| | | </view> |
| | | |
| | | <!-- ç©ºç¶æ --> |
| | | <view v-else-if="data.length === 0" class="empty-state"> |
| | | <view class="empty-icon">ð</view> |
| | | <text class="empty-title">ææ æ£éªå</text> |
| | | <text class="empty-desc">ç¹å»å³ä¸è§æé®å建æ°çæ£éªå</text> |
| | | </view> |
| | | |
| | | <!-- æ£éªåå表 --> |
| | | <view v-else class="inspection-list"> |
| | | <view v-for="item in data" :key="item.id || item.releaseNo" |
| | | class="inspection-card" @tap="navigateToDetail(item)"> |
| | | |
| | | <!-- å¡çå¤´é¨ --> |
| | | <view class="card-header"> |
| | | <view class="header-left"> |
| | | <view class="inspection-number"> |
| | | <text class="number-label">æ£éªåå·</text> |
| | | <text class="number-value">{{ item.releaseNo }}</text> |
| | | </view> |
| | | <view class="material-info"> |
| | | <text class="material-code">{{ item.itemNo }}</text> |
| | | <text class="material-name">{{ item.itemName || 'æªç¥ç©æ' }}</text> |
| | | </view> |
| | | </view> |
| | | <view class="header-right"> |
| | | <view class="status-badge" |
| | | :class="{ |
| | | 'status-submitted': item.fsubmit == 1, |
| | | 'status-pending': item.fsubmit != 1 |
| | | }"> |
| | | <view class="status-dot"></view> |
| | | <text class="status-text">{{ item.fsubmit == 1 ? 'å·²æäº¤' : 'å¾
æäº¤' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æ£éªç»æåºå --> |
| | | <view class="inspection-result"> |
| | | <view class="result-item"> |
| | | <view class="result-icon" |
| | | :class="{ |
| | | 'icon-pass': item.fcheckResu === 'åæ ¼', |
| | | 'icon-fail': item.fcheckResu === 'ä¸åæ ¼', |
| | | 'icon-pending': !item.fcheckResu || item.fcheckResu === 'æªæ£éª' |
| | | }"> |
| | | <text class="result-symbol">{{ |
| | | item.fcheckResu === 'åæ ¼' ? 'â' : |
| | | item.fcheckResu === 'ä¸åæ ¼' ? 'â' : 'â' |
| | | }}</text> |
| | | </view> |
| | | <view class="result-content"> |
| | | <text class="result-label">æ£éªç»æ</text> |
| | | <text class="result-value" |
| | | :class="{ |
| | | 'value-pass': item.fcheckResu === 'åæ ¼', |
| | | 'value-fail': item.fcheckResu === 'ä¸åæ ¼', |
| | | 'value-pending': !item.fcheckResu || item.fcheckResu === 'æªæ£éª' |
| | | }"> |
| | | {{ item.fcheckResu || 'æªæ£éª' }} |
| | | </text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="inspector-info"> |
| | | <text class="inspector-label">æ£éªäºº</text> |
| | | <text class="inspector-name">{{ item.modify1By || 'å¾
åé
' }}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 详ç»ä¿¡æ¯ --> |
| | | <view class="card-details"> |
| | | <view class="detail-grid"> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">å建æ¶é´</text> |
| | | <text class="detail-value">{{ item.createDate }}</text> |
| | | </view> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">æ°é</text> |
| | | <text class="detail-value">{{ item.planQty }}</text> |
| | | </view> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">å建人</text> |
| | | <text class="detail-value">{{ item.createUser }}</text> |
| | | </view> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">éæ£äºº</text> |
| | | <text class="detail-value">{{ item.fcheckUser || '-' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æä½æç¤ºå¨ --> |
| | | <view class="action-indicator"> |
| | | <uni-icons type="arrowright" size="16" color="#94a3b8"></uni-icons> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <!-- 第äºä¸ªé项å¡å
容 - å·²æ£éª --> |
| | | <view v-show="current === 1"> |
| | | <!-- å è½½ç¶æ --> |
| | | <view v-if="isLoading" class="loading-state"> |
| | | <view class="loading-spinner"></view> |
| | | <text class="loading-text">å è½½ä¸...</text> |
| | | </view> |
| | | |
| | | <!-- ç©ºç¶æ --> |
| | | <view v-else-if="data.length === 0" class="empty-state"> |
| | | <view class="empty-icon">â
</view> |
| | | <text class="empty-title">ææ å·²æ£éªåæ®</text> |
| | | <text class="empty-desc">宿æ£éªç忮尿¾ç¤ºå¨è¿é</text> |
| | | </view> |
| | | |
| | | <!-- æ£éªåå表 --> |
| | | <view v-else class="inspection-list"> |
| | | <view v-for="item in data" :key="item.id || item.releaseNo" |
| | | class="inspection-card completed" @tap="navigateToDetail(item)"> |
| | | |
| | | <!-- å¡çå¤´é¨ --> |
| | | <view class="card-header"> |
| | | <view class="header-left"> |
| | | <view class="inspection-number"> |
| | | <text class="number-label">æ£éªåå·</text> |
| | | <text class="number-value">{{ item.releaseNo }}</text> |
| | | </view> |
| | | <view class="material-info"> |
| | | <text class="material-code">{{ item.itemNo }}</text> |
| | | <text class="material-name">{{ item.itemName || 'æªç¥ç©æ' }}</text> |
| | | </view> |
| | | </view> |
| | | <view class="header-right"> |
| | | <view class="status-badge status-completed"> |
| | | <view class="status-dot"></view> |
| | | <text class="status-text">已宿</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æ£éªç»æåºå --> |
| | | <view class="inspection-result"> |
| | | <view class="result-item"> |
| | | <view class="result-icon" |
| | | :class="{ |
| | | 'icon-pass': item.fcheckResu === 'åæ ¼', |
| | | 'icon-fail': item.fcheckResu === 'ä¸åæ ¼' |
| | | }"> |
| | | <text class="result-symbol">{{ |
| | | item.fcheckResu === 'åæ ¼' ? 'â' : 'â' |
| | | }}</text> |
| | | </view> |
| | | <view class="result-content"> |
| | | <text class="result-label">æç»ç»æ</text> |
| | | <text class="result-value" |
| | | :class="{ |
| | | 'value-pass': item.fcheckResu === 'åæ ¼', |
| | | 'value-fail': item.fcheckResu === 'ä¸åæ ¼' |
| | | }"> |
| | | {{ item.fcheckResu }} |
| | | </text> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="inspector-info"> |
| | | <text class="inspector-label">æ£éªäºº</text> |
| | | <text class="inspector-name">{{ item.modify1By }}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 详ç»ä¿¡æ¯ --> |
| | | <view class="card-details"> |
| | | <view class="detail-grid"> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">æ£éªæ¶é´</text> |
| | | <text class="detail-value">{{ item.modify1Date }}</text> |
| | | </view> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">æ°é</text> |
| | | <text class="detail-value">{{ item.planQty }}</text> |
| | | </view> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">å建人</text> |
| | | <text class="detail-value">{{ item.createUser }}</text> |
| | | </view> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">éæ£äºº</text> |
| | | <text class="detail-value">{{ item.fcheckUser || '-' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æä½æç¤ºå¨ --> |
| | | <view class="action-indicator"> |
| | | <uni-icons type="arrowright" size="16" color="#94a3b8"></uni-icons> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æµ®å¨æä½æé® --> |
| | | <view class="fab-container"> |
| | | <view class="fab-button" @tap="handleFabClick"> |
| | | <uni-icons type="plus" size="24" color="#ffffff"></uni-icons> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | components: {}, |
| | | data() { |
| | | return { |
| | | items: ['æªæ£éª', 'å·²æ£éª'], |
| | | current: 0, |
| | | data: [], |
| | | pageIndex: 1, |
| | | limit: 20, |
| | | totalPage: 0, |
| | | totalCount: 0, |
| | | noData: false, |
| | | isLoading: false, |
| | | tipShow: false, |
| | | searchOptions: ['ç©æç¼å·', 'è§æ ¼', 'ç©æåç§°', 'ä¾åºå', 'éæ£äºº', 'æ£éªåå·'], |
| | | selectedOption: 0, |
| | | searchValue: '', |
| | | copiedText: '', |
| | | headerHeight: 0, |
| | | showFilter: false, // æ§å¶çé颿¿æ¾ç¤º |
| | | }; |
| | | }, |
| | | onLoad() { |
| | | this.init(); |
| | | }, |
| | | onShow() { |
| | | // 页颿¾ç¤ºæ¶å·æ°æ°æ® |
| | | this.pageIndex = 1; |
| | | this.loadData(); |
| | | }, |
| | | methods: { |
| | | onPickerChange(e) { |
| | | this.selectedOption = e.detail.value; |
| | | }, |
| | | getInputValue() { |
| | | this.pageIndex = 1; // æç´¢æ¶é置页ç |
| | | this.loadData(); // è°ç¨ç»ä¸çæ°æ®å è½½æ¹æ³ |
| | | }, |
| | | loadData() { |
| | | let result = "æªå®æ"; |
| | | if (this.current === 1) { |
| | | result = "已宿"; |
| | | } |
| | | |
| | | if (this.isLoading) return; |
| | | |
| | | this.isLoading = true; |
| | | |
| | | let userName = this.$loginInfo.account; |
| | | let url = "/MesOqcItemsDetect02/getPage"; // é»è®¤è°ç¨getPage |
| | | let requestData = { |
| | | pageIndex: this.pageIndex, |
| | | limit: this.limit, |
| | | createUser: userName, |
| | | result: result |
| | | }; |
| | | |
| | | console.log("请æ±åæ°:", requestData); |
| | | console.log("å½åé项å¡:", this.current); |
| | | console.log("resultç¶æ:", result); |
| | | |
| | | // 夿æç´¢æ¡æ¯å¦æå¼ |
| | | if (this.searchValue != null && this.searchValue.trim() !== '') { |
| | | // æ ¹æ®éæ©çæç´¢é项设置æç´¢æ¡ä»¶ |
| | | switch (this.selectedOption) { |
| | | case 0: |
| | | requestData.ItemNo = this.searchValue; |
| | | break; |
| | | case 1: |
| | | requestData.SalesOrder = this.searchValue; |
| | | break; |
| | | case 2: |
| | | requestData.ItemName = this.searchValue; |
| | | break; |
| | | case 3: |
| | | requestData.SuppNameContains = this.searchValue; |
| | | break; |
| | | case 4: |
| | | requestData.SongJ = this.searchValue; |
| | | break; |
| | | case 5: |
| | | requestData.SongNo = this.searchValue; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | this.$post({ |
| | | url: url, |
| | | data: requestData |
| | | }).then(res => { |
| | | console.log("APIè¿å宿´æ°æ®:", JSON.stringify(res, null, 2)); |
| | | console.log("resç»æ:", res); |
| | | console.log("res.data:", res.data); |
| | | console.log("res.totalCount:", res.totalCount); |
| | | |
| | | // æ ¹æ®ååºæ ¼å¼.jsonï¼æ£ç¡®çæ°æ®ç»ææ¯ï¼ |
| | | // res.data æ¯æ°ç»ï¼res.totalCount æ¯æ»æ° |
| | | let dataList = null; |
| | | let totalCount = 0; |
| | | |
| | | if (res.data && Array.isArray(res.data)) { |
| | | // æ£ç¡®çæ°æ®ç»æï¼dataæ¯æ°ç» |
| | | dataList = res.data; |
| | | totalCount = res.totalCount || 0; |
| | | } else if (res.tbBillList) { |
| | | // å¤ç¨ç»æï¼å
¼å®¹å
¶ä»æ¥å£ï¼ |
| | | dataList = res.tbBillList; |
| | | totalCount = res.totalCount || 0; |
| | | } else { |
| | | console.error("æ æ³è§£æçæ°æ®ç»æ:", res); |
| | | console.error("ææçåæ®µ data (æ°ç») ä¸åå¨"); |
| | | this.$showMessage("æ°æ®æ ¼å¼é误ï¼è¯·èç³»ææ¯æ¯æ"); |
| | | this.isLoading = false; |
| | | return; |
| | | } |
| | | |
| | | console.log("è§£æåçdataList:", dataList); |
| | | console.log("dataListé¿åº¦:", dataList ? dataList.length : 0); |
| | | |
| | | if (this.pageIndex === 1) { |
| | | this.data = dataList || []; |
| | | } else { |
| | | if (dataList && dataList.length > 0) { |
| | | this.data = [...this.data, ...dataList]; |
| | | } |
| | | } |
| | | |
| | | console.log("å¤çåçdata:", this.data); |
| | | console.log("dataé¿åº¦:", this.data.length); |
| | | |
| | | this.totalCount = totalCount; |
| | | this.totalPage = Math.ceil(this.totalCount / this.limit); |
| | | |
| | | this.noData = this.pageIndex >= this.totalPage; |
| | | this.isLoading = false; |
| | | }).catch((error) => { |
| | | console.error("API请æ±å¤±è´¥:", error); |
| | | this.isLoading = false; |
| | | this.searchValue = ''; |
| | | this.$showMessage("请æ±å¤±è´¥ï¼è¯·éè¯"); |
| | | }); |
| | | }, |
| | | init() { |
| | | this.loadData(); // ç»ä¸è°ç¨loadDataæ¹æ³ |
| | | }, |
| | | handleFabClick() { |
| | | uni.navigateTo({ |
| | | url: 'ScanCode' |
| | | }); |
| | | }, |
| | | onClickItem(index) { |
| | | if (this.current !== index.currentIndex) { |
| | | this.current = index.currentIndex; |
| | | this.data = []; |
| | | this.pageIndex = 1; |
| | | this.loadData(); // é项å¡åæ¢æ¶è°ç¨loadData |
| | | } |
| | | }, |
| | | copyText(text) { |
| | | uni.setClipboardData({ |
| | | data: text, |
| | | success: () => { |
| | | this.copiedText = text; |
| | | this.tipShow = true; |
| | | setTimeout(() => { |
| | | this.tipShow = false; |
| | | }, 1000); |
| | | } |
| | | }); |
| | | }, |
| | | // æ°å¢æ¹æ³ |
| | | navigateToDetail(item) { |
| | | uni.navigateTo({ |
| | | url: 'Add?id=' + item.id |
| | | }); |
| | | }, |
| | | toggleFilter() { |
| | | this.showFilter = !this.showFilter; |
| | | }, |
| | | clearSearch() { |
| | | this.searchValue = ''; |
| | | this.pageIndex = 1; |
| | | this.loadData(); |
| | | } |
| | | }, |
| | | onPullDownRefresh() { |
| | | this.pageIndex = 1; |
| | | this.loadData(); |
| | | this.tipShow = true; |
| | | uni.stopPullDownRefresh(); |
| | | |
| | | setTimeout(() => { |
| | | this.tipShow = false; |
| | | }, 1000); |
| | | }, |
| | | onReachBottom() { |
| | | if (this.noData || this.isLoading) return; |
| | | this.pageIndex++; |
| | | this.loadData(); // 䏿å è½½æ¶è°ç¨loadData |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style> |
| | | /* 页é¢å®¹å¨ */ |
| | | .page-container { |
| | | min-height: 100vh; |
| | | background: #f5f5f5; |
| | | padding: 0; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | /* æåæç¤ºæ¡ */ |
| | | .success-toast { |
| | | position: fixed; |
| | | top: 20px; |
| | | left: 50%; |
| | | transform: translateX(-50%) translateY(-100px); |
| | | background: #28a745; |
| | | color: white; |
| | | padding: 8px 16px; |
| | | border-radius: 6px; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 6px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); |
| | | z-index: 1000; |
| | | opacity: 0; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .success-toast.show { |
| | | opacity: 1; |
| | | transform: translateX(-50%) translateY(0); |
| | | } |
| | | |
| | | .toast-icon { |
| | | font-size: 14px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .toast-text { |
| | | font-size: 14px; |
| | | } |
| | | |
| | | /* 头é¨åºå */ |
| | | .header-section { |
| | | background: white; |
| | | padding: 16px; |
| | | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | /* 页颿 é¢ */ |
| | | .page-header { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .header-content { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .title-section { |
| | | flex: 1; |
| | | } |
| | | |
| | | .page-title { |
| | | font-size: 20px; |
| | | font-weight: 600; |
| | | color: #333; |
| | | margin-bottom: 2px; |
| | | display: block; |
| | | } |
| | | |
| | | .page-subtitle { |
| | | font-size: 13px; |
| | | color: #666; |
| | | display: block; |
| | | } |
| | | |
| | | .stats-badge { |
| | | background: #007AFF; |
| | | color: white; |
| | | padding: 8px 12px; |
| | | border-radius: 8px; |
| | | text-align: center; |
| | | min-width: 60px; |
| | | } |
| | | |
| | | .stats-number { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | display: block; |
| | | line-height: 1; |
| | | } |
| | | |
| | | .stats-label { |
| | | font-size: 11px; |
| | | display: block; |
| | | margin-top: 2px; |
| | | } |
| | | |
| | | /* æç´¢åºå */ |
| | | .search-section { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .search-container { |
| | | display: flex; |
| | | gap: 8px; |
| | | align-items: center; |
| | | } |
| | | |
| | | .search-input-wrapper { |
| | | flex: 1; |
| | | position: relative; |
| | | display: flex; |
| | | align-items: center; |
| | | background: #f8f8f8; |
| | | border: 1px solid #ddd; |
| | | border-radius: 8px; |
| | | padding: 0 12px; |
| | | } |
| | | |
| | | .search-input-wrapper:focus-within { |
| | | border-color: #007AFF; |
| | | background: white; |
| | | } |
| | | |
| | | .search-input { |
| | | flex: 1; |
| | | height: 40px; |
| | | border: none; |
| | | background: transparent; |
| | | font-size: 14px; |
| | | color: #333; |
| | | margin-left: 8px; |
| | | outline: none; |
| | | } |
| | | |
| | | .search-input::placeholder { |
| | | color: #999; |
| | | } |
| | | |
| | | .clear-btn { |
| | | padding: 4px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .filter-btn { |
| | | width: 40px; |
| | | height: 40px; |
| | | background: #f0f0f0; |
| | | border: 1px solid #ddd; |
| | | border-radius: 8px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .filter-btn:active { |
| | | background: #e0e0e0; |
| | | } |
| | | |
| | | /* çé颿¿ */ |
| | | .filter-panel { |
| | | margin-top: 8px; |
| | | background: white; |
| | | border: 1px solid #ddd; |
| | | border-radius: 8px; |
| | | padding: 12px; |
| | | } |
| | | |
| | | .filter-option { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 8px 0; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .filter-label { |
| | | font-size: 14px; |
| | | color: #666; |
| | | } |
| | | |
| | | .filter-value { |
| | | font-size: 14px; |
| | | color: #333; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* éé¡¹å¡ */ |
| | | .tab-section { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .custom-tabs { |
| | | display: flex; |
| | | background: #f0f0f0; |
| | | border-radius: 8px; |
| | | padding: 2px; |
| | | } |
| | | |
| | | .tab-item { |
| | | flex: 1; |
| | | position: relative; |
| | | padding: 10px 16px; |
| | | text-align: center; |
| | | cursor: pointer; |
| | | border-radius: 6px; |
| | | } |
| | | |
| | | .tab-item.active { |
| | | background: white; |
| | | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .tab-text { |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | color: #666; |
| | | } |
| | | |
| | | .tab-item.active .tab-text { |
| | | color: #007AFF; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | /* å
容åºå */ |
| | | .content-container { |
| | | flex: 1; |
| | | padding: 20px 16px; |
| | | } |
| | | |
| | | /* å è½½ç¶æ */ |
| | | .loading-state { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 60px 20px; |
| | | } |
| | | |
| | | .loading-spinner { |
| | | width: 40px; |
| | | height: 40px; |
| | | border: 3px solid #e2e8f0; |
| | | border-top: 3px solid #4f46e5; |
| | | border-radius: 50%; |
| | | animation: spin 1s linear infinite; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | @keyframes spin { |
| | | 0% { transform: rotate(0deg); } |
| | | 100% { transform: rotate(360deg); } |
| | | } |
| | | |
| | | .loading-text { |
| | | font-size: 14px; |
| | | color: #64748b; |
| | | } |
| | | |
| | | /* ç©ºç¶æ */ |
| | | .empty-state { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 80px 20px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .empty-icon { |
| | | font-size: 64px; |
| | | margin-bottom: 20px; |
| | | opacity: 0.6; |
| | | } |
| | | |
| | | .empty-title { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #374151; |
| | | margin-bottom: 8px; |
| | | display: block; |
| | | } |
| | | |
| | | .empty-desc { |
| | | font-size: 14px; |
| | | color: #9ca3af; |
| | | display: block; |
| | | } |
| | | |
| | | /* æ£éªåå表 */ |
| | | .inspection-list { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 12px; |
| | | } |
| | | |
| | | .inspection-card { |
| | | background: white; |
| | | border-radius: 8px; |
| | | padding: 16px; |
| | | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); |
| | | border: 1px solid #e0e0e0; |
| | | cursor: pointer; |
| | | position: relative; |
| | | } |
| | | |
| | | .inspection-card:active { |
| | | background: #f8f8f8; |
| | | } |
| | | |
| | | /* å¡çå¤´é¨ */ |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: flex-start; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .header-left { |
| | | flex: 1; |
| | | } |
| | | |
| | | .inspection-number { |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .number-label { |
| | | font-size: 12px; |
| | | color: #64748b; |
| | | display: block; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .number-value { |
| | | font-size: 16px; |
| | | font-weight: 700; |
| | | color: #1e293b; |
| | | display: block; |
| | | } |
| | | |
| | | .material-info { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 2px; |
| | | } |
| | | |
| | | .material-code { |
| | | font-size: 13px; |
| | | color: #4f46e5; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .material-name { |
| | | font-size: 12px; |
| | | color: #64748b; |
| | | max-width: 200px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .header-right { |
| | | margin-left: 16px; |
| | | } |
| | | |
| | | /* ç¶æå¾½ç« */ |
| | | .status-badge { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 4px; |
| | | padding: 4px 8px; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .status-badge.status-submitted { |
| | | background: #e8f5e8; |
| | | color: #2e7d32; |
| | | border: 1px solid #c8e6c9; |
| | | } |
| | | |
| | | .status-badge.status-pending { |
| | | background: #fff3e0; |
| | | color: #f57c00; |
| | | border: 1px solid #ffcc02; |
| | | } |
| | | |
| | | .status-badge.status-completed { |
| | | background: #e8f5e8; |
| | | color: #2e7d32; |
| | | border: 1px solid #c8e6c9; |
| | | } |
| | | |
| | | .status-dot { |
| | | width: 6px; |
| | | height: 6px; |
| | | border-radius: 50%; |
| | | background: currentColor; |
| | | } |
| | | |
| | | .status-text { |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* æ£éªç»æåºå */ |
| | | .inspection-result { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 12px; |
| | | padding: 8px; |
| | | background: #f8f8f8; |
| | | border-radius: 6px; |
| | | } |
| | | |
| | | .result-item { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | flex: 1; |
| | | } |
| | | |
| | | .result-icon { |
| | | width: 24px; |
| | | height: 24px; |
| | | border-radius: 50%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-weight: bold; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .result-icon.icon-pass { |
| | | background: #28a745; |
| | | color: white; |
| | | } |
| | | |
| | | .result-icon.icon-fail { |
| | | background: #dc3545; |
| | | color: white; |
| | | } |
| | | |
| | | .result-icon.icon-pending { |
| | | background: #ffc107; |
| | | color: white; |
| | | } |
| | | |
| | | .result-content { |
| | | flex: 1; |
| | | } |
| | | |
| | | .result-label { |
| | | font-size: 12px; |
| | | color: #666; |
| | | display: block; |
| | | margin-bottom: 2px; |
| | | } |
| | | |
| | | .result-value { |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | display: block; |
| | | } |
| | | |
| | | .result-value.value-pass { |
| | | color: #28a745; |
| | | } |
| | | |
| | | .result-value.value-fail { |
| | | color: #dc3545; |
| | | } |
| | | |
| | | .result-value.value-pending { |
| | | color: #ffc107; |
| | | } |
| | | |
| | | .inspector-info { |
| | | text-align: right; |
| | | } |
| | | |
| | | .inspector-label { |
| | | font-size: 12px; |
| | | color: #666; |
| | | display: block; |
| | | margin-bottom: 2px; |
| | | } |
| | | |
| | | .inspector-name { |
| | | font-size: 13px; |
| | | font-weight: 500; |
| | | color: #333; |
| | | display: block; |
| | | } |
| | | |
| | | /* 详ç»ä¿¡æ¯ */ |
| | | .card-details { |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .detail-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(2, 1fr); |
| | | gap: 8px; |
| | | } |
| | | |
| | | .detail-item { |
| | | background: #f8f8f8; |
| | | padding: 6px 8px; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .detail-label { |
| | | font-size: 11px; |
| | | color: #666; |
| | | display: block; |
| | | margin-bottom: 2px; |
| | | } |
| | | |
| | | .detail-value { |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | color: #333; |
| | | display: block; |
| | | } |
| | | |
| | | /* æä½æç¤ºå¨ */ |
| | | .action-indicator { |
| | | position: absolute; |
| | | top: 50%; |
| | | right: 12px; |
| | | transform: translateY(-50%); |
| | | opacity: 0.3; |
| | | } |
| | | |
| | | /* æµ®å¨æä½æé® */ |
| | | .fab-container { |
| | | position: fixed; |
| | | bottom: 20px; |
| | | right: 20px; |
| | | z-index: 1000; |
| | | } |
| | | |
| | | .fab-button { |
| | | width: 50px; |
| | | height: 50px; |
| | | background: #007AFF; |
| | | border-radius: 50%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .fab-button:active { |
| | | transform: scale(0.95); |
| | | } |
| | | |
| | | /* ååºå¼è®¾è®¡ */ |
| | | @media (max-width: 768px) { |
| | | .header-content { |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | gap: 12px; |
| | | } |
| | | |
| | | .stats-badge { |
| | | align-self: flex-end; |
| | | } |
| | | |
| | | .search-container { |
| | | flex-direction: column; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .filter-btn { |
| | | align-self: flex-end; |
| | | } |
| | | |
| | | .detail-grid { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | |
| | | .inspection-result { |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | gap: 12px; |
| | | } |
| | | |
| | | .inspector-info { |
| | | text-align: left; |
| | | width: 100%; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view class="container"> |
| | | <!-- 表ååºå --> |
| | | <view class="form-container card"> |
| | | <form :modelValue="formData"> |
| | | <view class="form-grid"> |
| | | <view class="form-group col-2"> |
| | | <label class="form-label">ç©ææ¡ç :</label> |
| | | <view class="input-with-scan"> |
| | | <input class="form-input scan-input" type="text" v-model="formData.ItemBarcode" |
| | | @confirm="addItemBarCode" |
| | | placeholder="è¾å
¥åç¦»å¼ææå车" /> |
| | | <view class="scan-button" @tap="startScan"> |
| | | <uni-icons type="scan" size="24" color="#007bff"></uni-icons> |
| | | <text class="scan-text">æ«ç </text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="form-group col-2"> |
| | | <label class="form-label">产ååç§°:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.itemName" /> |
| | | </view> |
| | | <view class="form-group col-2"> |
| | | <label class="form-label">产åç¼ç :</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.itemNo" /> |
| | | </view> |
| | | <view class="form-group col-2"> |
| | | <label class="form-label">订åç¼å·:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.taskNo" /> |
| | | </view> |
| | | <view class="form-group col-2"> |
| | | <label class="form-label">å·²æ«æ°é:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="quantity" /> |
| | | </view> |
| | | </view> |
| | | </form> |
| | | </view> |
| | | |
| | | <!-- å¾
æ£æ¡ç è¡¨æ ¼åºå --> |
| | | <view class="table-container card"> |
| | | <view class="table-header"> |
| | | <text class="section-title">å¾
æ£æ¡ç å表</text> |
| | | <view class="table-tip"> |
| | | <text class="tip-text">ð 左峿»å¨æ¥çæ´å¤ä¿¡æ¯</text> |
| | | </view> |
| | | </view> |
| | | <view class="table-wrapper"> |
| | | <scroll-view class="table-scroll" scroll-x="true" show-scrollbar="true"> |
| | | <uni-table ref="table" border emptyText="ææ æ´å¤æ°æ®" class="custom-table"> |
| | | <uni-tr class="table-header-row"> |
| | | <uni-th align="center" class="th" width="80">åºå·</uni-th> |
| | | <uni-th align="center" class="th" width="160">ç©ææ¡ç </uni-th> |
| | | <uni-th align="center" class="th" width="140">订åç¼å·</uni-th> |
| | | <uni-th align="center" class="th" width="140">产åç¼ç </uni-th> |
| | | <uni-th align="center" class="th" width="160">产ååç§°</uni-th> |
| | | <uni-th align="center" class="th" width="100">æ¡ç æ°é</uni-th> |
| | | <uni-th align="center" class="th" width="80">ã</uni-th> |
| | | </uni-tr> |
| | | <uni-tr v-for="(item, index) in tableData" :key="index" class="table-row"> |
| | | <uni-td align="center" width="80"> |
| | | <view class="description-text">{{ index + 1 }}</view> |
| | | </uni-td> |
| | | <uni-td align="center" width="160"> |
| | | <view class="cell-content">{{ item.itemBarcode }}</view> |
| | | </uni-td> |
| | | <uni-td align="center" width="140"> |
| | | <view class="cell-content">{{ item.taskNo || '-' }}</view> |
| | | </uni-td> |
| | | <uni-td align="center" width="140"> |
| | | <view class="cell-content">{{ item.itemNo }}</view> |
| | | </uni-td> |
| | | <uni-td align="center" width="160"> |
| | | <view class="cell-content" :title="item.itemName">{{ item.itemName }}</view> |
| | | </uni-td> |
| | | <uni-td align="center" width="100"> |
| | | <view class="cell-content quantity">{{ item.quantity }}</view> |
| | | </uni-td> |
| | | <uni-td align="center" width="80"> |
| | | <view class="cell-content">ã</view> |
| | | </uni-td> |
| | | </uni-tr> |
| | | </uni-table> |
| | | </scroll-view> |
| | | |
| | | <!-- å³åºå®æ¬æµ®å 餿é®å --> |
| | | <view class="fixed-delete-column"> |
| | | <view class="fixed-header"> |
| | | <text class="fixed-header-text">æä½</text> |
| | | </view> |
| | | <view class="fixed-content"> |
| | | <view v-for="(item, index) in tableData" :key="index" class="fixed-delete-item" |
| | | :class="{ 'even': index % 2 === 1 }"> |
| | | <view @click="deleteItem(index)" class="delete-icon"> |
| | | <uni-icons type="trash" size="24"></uni-icons> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æä½æé®åºå --> |
| | | <view class="action-buttons-container button-group"> |
| | | <view class="plus-button" :class="{ 'submitting': isSubmitting }" @tap="handleSubmit"> |
| | | <text>{{ isSubmitting ? 'æäº¤ä¸...' : 'çæOQCæ£éªå' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | formData: {}, |
| | | tableData: [], |
| | | quantity: 0, |
| | | isSubmitting: false, // 鲿¢éå¤æäº¤ |
| | | isProcessing: false, // 鲿¢éå¤å¤çæ¡ç |
| | | } |
| | | }, |
| | | methods: { |
| | | // å¯å¨æ«ç åè½ |
| | | startScan() { |
| | | // æ£æ¥æ¯å¦æ£å¨å¤çæ¡ç ï¼é²æ¢é夿«ç |
| | | if (this.isProcessing) { |
| | | this.$showMessage("æ£å¨å¤çæ¡ç ï¼è¯·ç¨å"); |
| | | return; |
| | | } |
| | | |
| | | uni.scanCode({ |
| | | scanType: ['barCode', 'qrCode'], // æ¯ææ¡ç åäºç»´ç |
| | | success: (res) => { |
| | | console.log('æ«ç æå:', res); |
| | | // å°æ«ç ç»æè®¾ç½®å°è¾å
¥æ¡ |
| | | this.formData.ItemBarcode = res.result; |
| | | // èªå¨å¤çæ«ç ç»æ |
| | | this.addItemBarCode(); |
| | | }, |
| | | fail: (err) => { |
| | | console.log('æ«ç 失败:', err); |
| | | if (err.errMsg && err.errMsg.indexOf('cancel') === -1) { |
| | | this.$showMessage("æ«ç 失败ï¼è¯·éè¯"); |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | addItemBarCode() { |
| | | // 鲿¢éå¤å¤ç |
| | | if (this.isProcessing) { |
| | | return; |
| | | } |
| | | |
| | | // æ ¡éªç©ææ¡ç æ¯å¦ä¸ºç©º |
| | | if (!this.formData.ItemBarcode || this.formData.ItemBarcode.trim() === '') { |
| | | this.$showMessage("请è¾å
¥ç©ææ¡ç "); |
| | | return; |
| | | } |
| | | |
| | | // æ£æ¥ç©ææ¡ç æ¯å¦å·²åå¨äº tableData ä¸ |
| | | const isDuplicate = this.tableData.some(item => item.itemBarcode === this.formData.ItemBarcode); |
| | | if (isDuplicate) { |
| | | this.$showMessage("è¯¥ç©ææ¡ç å·²åå¨ï¼è¯·æ£æ¥ï¼"); |
| | | return; |
| | | } |
| | | |
| | | // 设置å¤çç¶æ |
| | | this.isProcessing = true; |
| | | |
| | | // 妿éè¿äºä¸è¿°æ ¡éªï¼åé请æ±å¹¶æ´æ°æ°æ® |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/GetItemBarCode", |
| | | data: { |
| | | ItemCode: this.formData.ItemBarcode |
| | | } |
| | | }).then(res => { |
| | | let fr = res.data.tbBillList; |
| | | |
| | | // æ°æ®å®æ´æ§æ ¡éª |
| | | if (!fr) { |
| | | this.$showMessage("è·åæ¡ç ä¿¡æ¯å¤±è´¥ï¼è¯·éè¯"); |
| | | return; |
| | | } |
| | | |
| | | if (!fr.itemId || !fr.itemName || !fr.itemNo) { |
| | | this.$showMessage("æ¡ç ä¿¡æ¯ä¸å®æ´ï¼è¯·æ£æ¥æ¡ç "); |
| | | return; |
| | | } |
| | | |
| | | if (fr.quantity <= 0) { |
| | | this.$showMessage("æ¡ç æ°é为0ï¼è¯·ç¡®è®¤"); |
| | | return; |
| | | } |
| | | |
| | | //éè¦éªè¯ |
| | | //æ«çç çitemIdå¿
é¡»æ¯åtableDataä¸çitemIdç¸å å¿
é¡»çæ¡ä»¶ |
| | | //æ«çç çTaskNoä¹å¿
é¡»æ¯åtableDataä¸çTaskNoç¸å |
| | | //TaskNo为空çåªè½åTaskNo为空çä¸èµ·æ« |
| | | |
| | | // 妿tableDataä¸å·²ææ°æ®ï¼éè¦éªè¯itemIdåTaskNoçä¸è´æ§ |
| | | if (this.tableData.length > 0) { |
| | | const firstItem = this.tableData[0]; |
| | | |
| | | // éªè¯itemIdæ¯å¦ç¸åï¼å¿
é¡»æ¡ä»¶ï¼ |
| | | if (fr.itemId !== firstItem.itemId) { |
| | | this.$showMessage("ç©æç¼ç ä¸ä¸è´ï¼è¯·æ«æç¸åç©æçæ¡ç "); |
| | | return; |
| | | } |
| | | |
| | | // éªè¯TaskNoæ¯å¦ç¸å |
| | | if (fr.taskNo !== firstItem.taskNo) { |
| | | this.$showMessage("订åç¼å·ä¸ä¸è´ï¼è¯·æ«æç¸å订åçæ¡ç "); |
| | | return; |
| | | } |
| | | |
| | | // éªè¯ç©ºTaskNoçæ
åµï¼TaskNo为空çåªè½åTaskNo为空çä¸èµ·æ« |
| | | if ((fr.taskNo === '' || fr.taskNo === null || fr.taskNo === undefined) && |
| | | (firstItem.taskNo !== '' && firstItem.taskNo !== null && firstItem.taskNo !== undefined)) { |
| | | this.$showMessage("订åç¼å·ä¸å¹é
ï¼ç©ºè®¢åç¼å·åªè½ä¸ç©ºè®¢åç¼å·ä¸èµ·æ«æ"); |
| | | return; |
| | | } |
| | | |
| | | if ((fr.taskNo !== '' && fr.taskNo !== null && fr.taskNo !== undefined) && |
| | | (firstItem.taskNo === '' || firstItem.taskNo === null || firstItem.taskNo === undefined)) { |
| | | this.$showMessage("订åç¼å·ä¸å¹é
ï¼æè®¢åç¼å·çæ¡ç åªè½ä¸æè®¢åç¼å·çæ¡ç ä¸èµ·æ«æ"); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | this.formData = fr; |
| | | this.tableData.push(fr); // å°æ°æ°æ®æ·»å å°è¡¨æ ¼ |
| | | this.quantity = this.tableData.reduce(function(accumulator, current) { |
| | | return accumulator + current["quantity"]; |
| | | }, 0); |
| | | |
| | | // æ¸
空è¾å
¥æ¡ |
| | | this.formData.ItemBarcode = ''; |
| | | }).catch(error => { |
| | | this.$showMessage("è·åæ¡ç ä¿¡æ¯å¤±è´¥ï¼è¯·éè¯"); |
| | | }).finally(() => { |
| | | // éç½®å¤çç¶æ |
| | | this.isProcessing = false; |
| | | }); |
| | | }, |
| | | |
| | | // å 餿ä½ï¼å é¤ tableData 䏿å®ç´¢å¼çæ°æ® |
| | | deleteItem(index) { |
| | | this.tableData.splice(index, 1); // å é¤è¯¥è¡æ°æ® |
| | | this.quantity = this.tableData.reduce(function(accumulator, current) { |
| | | return accumulator + current["quantity"]; |
| | | }, 0); // æ´æ°æ¡ç æ°é |
| | | |
| | | if (this.tableData.length <= 0) { |
| | | this.formData = {}; |
| | | } |
| | | }, |
| | | |
| | | handleSubmit() { |
| | | console.log("handleSubmitæ¹æ³è¢«è°ç¨ï¼isSubmitting:", this.isSubmitting); |
| | | console.log("tableDataé¿åº¦:", this.tableData.length); |
| | | console.log("quantity:", this.quantity); |
| | | this.submit(); |
| | | }, |
| | | |
| | | submit() { |
| | | console.log("submitæ¹æ³è¢«è°ç¨"); |
| | | |
| | | // 鲿¢éå¤æäº¤ |
| | | if (this.isSubmitting) { |
| | | this.$showMessage("æ£å¨æäº¤ä¸ï¼è¯·å¿é夿ä½"); |
| | | return; |
| | | } |
| | | |
| | | // æ ¡éªç¨æ·ç»å½ç¶æ |
| | | if (!this.$loginInfo.account) { |
| | | this.$showMessage("ç¨æ·æªç»å½ï¼è¯·éæ°ç»å½"); |
| | | return; |
| | | } |
| | | |
| | | // æ ¡éªæ¡ç æ°éæ¯å¦ææ |
| | | if (this.quantity <= 0) { |
| | | this.$showMessage("æ¡ç æ°éå¿
须大äº0"); |
| | | return; |
| | | } |
| | | |
| | | // æ ¡éªæ¯å¦ææ°æ® |
| | | if (this.tableData.length === 0) { |
| | | this.$showMessage("è¯·æ«ææ¡ç "); |
| | | return; |
| | | } |
| | | |
| | | let userName = this.$loginInfo.account; |
| | | this.isSubmitting = true; // 设置æäº¤ç¶æ |
| | | |
| | | // åéè¯·æ± |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/ItemBarCodeSubmit", |
| | | data: { |
| | | itemBarCodeData: this.tableData, |
| | | CreateUser: userName |
| | | } |
| | | }).then(response => { |
| | | if(response.status == 0){ |
| | | // è¯·æ±æååæ¾ç¤ºéæ©æ¡ |
| | | uni.showModal({ |
| | | title: "æä½æå", |
| | | content: "å·²ç»æåçææ£éªå", |
| | | showCancel: true, |
| | | cancelText: "ç»§ç»æ«ç ", |
| | | confirmText: "è·³è½¬å°æ£éªå", |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | // ç¨æ·ç¹å»äº"è·³è½¬å°æ£éªå" |
| | | uni.navigateTo({ |
| | | url: '/pages/QC/OQC/Add?id=' + response.data |
| | | }); |
| | | } else if (res.cancel) { |
| | | // ç¨æ·ç¹å»äº"ç»§ç»æ«ç " |
| | | this.clearData(); |
| | | } |
| | | } |
| | | }); |
| | | }else{ |
| | | this.$showMessage(response.message); |
| | | } |
| | | |
| | | }).catch(error => { |
| | | // 请æ±å¤±è´¥æ¶çå¤ç |
| | | this.$showMessage("请æ±å¤±è´¥ï¼è¯·ç¨åéè¯"); |
| | | }).finally(() => { |
| | | // æ 论æåè¿æ¯å¤±è´¥é½éç½®æäº¤ç¶æ |
| | | this.isSubmitting = false; |
| | | }); |
| | | }, |
| | | |
| | | // æ¸
ç©ºè¡¨æ ¼åè¡¨åæ°æ® |
| | | clearData() { |
| | | this.tableData = []; |
| | | this.formData = {}; |
| | | this.quantity = 0; |
| | | this.isSubmitting = false; |
| | | this.isProcessing = false; |
| | | } |
| | | |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .container { |
| | | padding: 24rpx; |
| | | background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); |
| | | min-height: 100vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | /* å¡çéç¨æ ·å¼ */ |
| | | .card { |
| | | background: #ffffff; |
| | | border-radius: 12rpx; |
| | | box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08); |
| | | margin-bottom: 24rpx; |
| | | padding: 32rpx; |
| | | border: 1rpx solid #e9ecef; |
| | | } |
| | | |
| | | /* 表ååºå */ |
| | | .form-container { |
| | | .form-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(2, 1fr); |
| | | gap: 24rpx 16rpx; |
| | | } |
| | | |
| | | .form-group { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 16rpx; |
| | | |
| | | .form-label { |
| | | font-size: 28rpx; |
| | | color: #495057; |
| | | font-weight: 600; |
| | | padding-left: 4rpx; |
| | | position: relative; |
| | | |
| | | &::after { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | bottom: -4rpx; |
| | | width: 24rpx; |
| | | height: 3rpx; |
| | | background: #007bff; |
| | | border-radius: 2rpx; |
| | | } |
| | | } |
| | | |
| | | .form-input { |
| | | height: 92rpx; |
| | | padding: 0 24rpx; |
| | | border: 2rpx solid #dee2e6; |
| | | border-radius: 8rpx; |
| | | font-size: 28rpx; |
| | | color: #212529; |
| | | background: #ffffff; |
| | | transition: all 0.3s ease; |
| | | |
| | | &[disabled] { |
| | | background: #f8f9fa; |
| | | color: #6c757d; |
| | | border-color: #e9ecef; |
| | | } |
| | | |
| | | &:focus { |
| | | border-color: #007bff; |
| | | box-shadow: 0 0 0 4rpx rgba(0, 123, 255, 0.1); |
| | | outline: none; |
| | | } |
| | | |
| | | &::placeholder { |
| | | color: #adb5bd; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* è¡¨æ ¼ä¼å */ |
| | | .table-container { |
| | | .table-header { |
| | | margin-bottom: 24rpx; |
| | | padding-bottom: 16rpx; |
| | | border-bottom: 2rpx solid #e9ecef; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | |
| | | .section-title { |
| | | font-size: 32rpx; |
| | | color: #212529; |
| | | font-weight: 700; |
| | | position: relative; |
| | | padding-left: 24rpx; |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 4rpx; |
| | | height: 28rpx; |
| | | background: linear-gradient(135deg, #007bff, #0056b3); |
| | | border-radius: 2rpx; |
| | | } |
| | | } |
| | | |
| | | .table-tip { |
| | | .tip-text { |
| | | font-size: 22rpx; |
| | | color: #6c757d; |
| | | background: #f8f9fa; |
| | | padding: 8rpx 16rpx; |
| | | border-radius: 16rpx; |
| | | border: 1rpx solid #e9ecef; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-wrapper { |
| | | position: relative; |
| | | border-radius: 8rpx; |
| | | overflow: hidden; |
| | | border: 1rpx solid #dee2e6; |
| | | } |
| | | |
| | | .table-scroll { |
| | | width: calc(100% - 80rpx); /* åå»åºå®å宽度 */ |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .custom-table { |
| | | border: none; |
| | | min-width: 780rpx; |
| | | |
| | | .table-header-row { |
| | | background: linear-gradient(135deg, #f8f9fa, #e9ecef); |
| | | |
| | | .th { |
| | | font-size: 26rpx; |
| | | color: #495057; |
| | | font-weight: 600; |
| | | padding: 20rpx 12rpx; |
| | | background: transparent !important; |
| | | border-right: 1rpx solid #dee2e6; |
| | | white-space: nowrap; |
| | | min-width: 80rpx; |
| | | |
| | | &:last-child { |
| | | border-right: none; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-row { |
| | | transition: background-color 0.2s ease; |
| | | |
| | | &:nth-child(even) { |
| | | background: #f8f9fa; |
| | | } |
| | | |
| | | &:hover { |
| | | background: #e3f2fd; |
| | | } |
| | | |
| | | .uni-td { |
| | | padding: 16rpx 12rpx; |
| | | border-color: #dee2e6 !important; |
| | | border-right: 1rpx solid #dee2e6; |
| | | white-space: nowrap; |
| | | min-width: 80rpx; |
| | | |
| | | &:last-child { |
| | | border-right: none; |
| | | } |
| | | |
| | | .cell-content { |
| | | font-size: 24rpx; |
| | | color: #495057; |
| | | line-height: 1.4; |
| | | max-width: 100%; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | |
| | | &.quantity { |
| | | font-weight: 600; |
| | | color: #007bff; |
| | | background: linear-gradient(135deg, #e3f2fd, #bbdefb); |
| | | padding: 8rpx 16rpx; |
| | | border-radius: 12rpx; |
| | | display: inline-block; |
| | | min-width: 60rpx; |
| | | text-align: center; |
| | | } |
| | | } |
| | | |
| | | .description-text { |
| | | font-size: 24rpx; |
| | | color: #6c757d; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* å³åºå®æ¬æµ®å é¤å */ |
| | | .fixed-delete-column { |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | width: 80rpx; |
| | | background: #ffffff; |
| | | border-left: 1rpx solid #dee2e6; |
| | | box-shadow: -4rpx 0 8rpx rgba(0, 0, 0, 0.05); |
| | | z-index: 10; |
| | | |
| | | .fixed-header { |
| | | height: 60rpx; |
| | | background: linear-gradient(135deg, #f8f9fa, #e9ecef); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-bottom: 1rpx solid #dee2e6; |
| | | |
| | | .fixed-header-text { |
| | | font-size: 26rpx; |
| | | color: #495057; |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | |
| | | .fixed-content { |
| | | .fixed-delete-item { |
| | | height: 48rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-bottom: 1rpx solid #dee2e6; |
| | | transition: background-color 0.2s ease; |
| | | |
| | | &.even { |
| | | background: #f8f9fa; |
| | | } |
| | | |
| | | &:hover { |
| | | background: #e3f2fd; |
| | | } |
| | | |
| | | &:last-child { |
| | | border-bottom: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* å é¤å¾æ ä¼å */ |
| | | .delete-icon { |
| | | cursor: pointer; |
| | | color: #dc3545; |
| | | transition: all 0.3s ease; |
| | | padding: 12rpx; |
| | | border-radius: 50%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | min-width: 48rpx; |
| | | min-height: 48rpx; |
| | | |
| | | &:hover { |
| | | color: #c82333; |
| | | background: rgba(220, 53, 69, 0.1); |
| | | transform: scale(1.1); |
| | | } |
| | | |
| | | &:active { |
| | | transform: scale(0.95); |
| | | background: rgba(220, 53, 69, 0.2); |
| | | } |
| | | } |
| | | |
| | | /* æé®ä¼å */ |
| | | .action-buttons-container { |
| | | display: flex; |
| | | justify-content: center; |
| | | margin-top: 48rpx; |
| | | padding: 0 24rpx; |
| | | |
| | | .plus-button { |
| | | width: 100%; |
| | | max-width: 600rpx; |
| | | height: 96rpx; |
| | | background: linear-gradient(135deg, #007bff, #0056b3); |
| | | border-radius: 48rpx; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | color: #ffffff; |
| | | font-size: 32rpx; |
| | | font-weight: 600; |
| | | box-shadow: 0 8rpx 24rpx rgba(0, 123, 255, 0.3); |
| | | transition: all 0.3s ease; |
| | | border: none; |
| | | position: relative; |
| | | overflow: hidden; |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 0; |
| | | left: -100%; |
| | | width: 100%; |
| | | height: 100%; |
| | | background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); |
| | | transition: left 0.5s ease; |
| | | } |
| | | |
| | | &:active { |
| | | transform: scale(0.98); |
| | | box-shadow: 0 4rpx 12rpx rgba(0, 123, 255, 0.4); |
| | | |
| | | &::before { |
| | | left: 100%; |
| | | } |
| | | } |
| | | |
| | | &.submitting { |
| | | background: linear-gradient(135deg, #6c757d, #5a6268); |
| | | cursor: not-allowed; |
| | | |
| | | &::before { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* æ°éæ¾ç¤ºä¼å */ |
| | | .form-group { |
| | | &:nth-child(5) .form-input { |
| | | font-weight: 600; |
| | | color: #007bff; |
| | | background: linear-gradient(135deg, #e3f2fd, #bbdefb); |
| | | border: 2rpx solid #007bff; |
| | | text-align: center; |
| | | } |
| | | } |
| | | |
| | | /* æ«ç è¾å
¥æ¡æ ·å¼ */ |
| | | .input-with-scan { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 16rpx; |
| | | |
| | | .scan-input { |
| | | flex: 1; |
| | | } |
| | | |
| | | .scan-button { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 16rpx 20rpx; |
| | | background: linear-gradient(135deg, #e3f2fd, #bbdefb); |
| | | border: 2rpx solid #007bff; |
| | | border-radius: 8rpx; |
| | | min-width: 120rpx; |
| | | height: 92rpx; |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | background: linear-gradient(135deg, #bbdefb, #90caf9); |
| | | transform: translateY(-2rpx); |
| | | box-shadow: 0 4rpx 12rpx rgba(0, 123, 255, 0.2); |
| | | } |
| | | |
| | | &:active { |
| | | transform: translateY(0); |
| | | box-shadow: 0 2rpx 6rpx rgba(0, 123, 255, 0.3); |
| | | } |
| | | |
| | | .scan-text { |
| | | font-size: 22rpx; |
| | | color: #007bff; |
| | | font-weight: 600; |
| | | margin-top: 4rpx; |
| | | } |
| | | } |
| | | } |
| | | |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view class="page-container"> |
| | | <!-- æ£éªé¡¹ç®è¡¨åå¡ç --> |
| | | <view class="form-card"> |
| | | <view class="form-title"> |
| | | <view class="title-icon">ð</view> |
| | | <span>æ£éªé¡¹ç®è¯¦æ
</span> |
| | | </view> |
| | | <view class="form-container"> |
| | | <!-- åºæ¬ä¿¡æ¯æ¨¡å --> |
| | | <view class="form-section"> |
| | | <view class="section-title">åºæ¬ä¿¡æ¯</view> |
| | | <view class="form-grid"> |
| | | <view class="form-group"> |
| | | <label class="form-label">项ç®åç§°:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.fcheckItem" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">è§æ ¼è¦æ±:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.fspecRequ" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ£éªæ¹æ³:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.inspectionMethod" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ£éªå·¥å
·:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.fcheckTool" /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- ä¸ä¸ªæ¨¡åå¹¶åå®¹å¨ --> |
| | | <view class="three-modules-container"> |
| | | <!-- æ£éªåæ°æ¨¡å --> |
| | | <view class="module-item"> |
| | | <view class="module-header"> |
| | | <text class="module-title">æ£éªåæ°</text> |
| | | </view> |
| | | <view class="module-content"> |
| | | <view class="form-grid"> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ£éªæ°:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.checkQyt" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ£éªæ åç¼ç :</label> |
| | | <input class="form-input" disabled="true" type="text" |
| | | v-model="formData.sampleSizeNo" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ£éªæ°´å¹³:</label> |
| | | <input class="form-input" disabled="true" type="text" |
| | | v-model="formData.fcheckLevel" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ¥æ¶æ°´å¹³:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.facLevel" /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æ°å¼æ 忍¡å --> |
| | | <view class="module-item"> |
| | | <view class="module-header"> |
| | | <text class="module-title">æ°å¼æ å</text> |
| | | </view> |
| | | <view class="module-content"> |
| | | <view class="form-grid"> |
| | | <view class="form-group"> |
| | | <label class="form-label">ä¸é:</label> |
| | | <input class="form-input" disabled="true" type="text" |
| | | v-model="formData.fdownAllow" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ åå¼:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.fstand" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">ä¸é:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.fupAllow" /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- å¤å®æ 忍¡å --> |
| | | <view class="module-item"> |
| | | <view class="module-header"> |
| | | <text class="module-title">å¤å®æ å</text> |
| | | </view> |
| | | <view class="module-content"> |
| | | <view class="form-grid"> |
| | | <view class="form-group"> |
| | | <label class="form-label">ACæ°:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.facQty" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">REæ°:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.freQty" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">ä¸åæ ¼æ°:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.fngQty" /> |
| | | </view> |
| | | <view class="form-group"> |
| | | <label class="form-label">é¢è§ç»æ:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.fcheckResu" /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 夿³¨ä¿¡æ¯æ¨¡å --> |
| | | <!-- <view class="form-section"> |
| | | <view class="section-title">夿³¨ä¿¡æ¯</view> |
| | | <view class="form-grid"> |
| | | <view class="form-group"> |
| | | <label class="form-label">ä¸åæ ¼æè¿°:</label> |
| | | <input class="form-input" disabled="true" type="text" v-model="formData.remarks" /> |
| | | </view> |
| | | </view> |
| | | </view> --> |
| | | |
| | | <!-- æ£æµç»æåºå --> |
| | | <view class="form-section"> |
| | | <view class="section-title">æ£æµç»æ</view> |
| | | <view class="form-grid"> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ£æµç»æ:</label> |
| | | <input class="form-input" type="number" v-model="fcheckResuK" /> |
| | | </view> |
| | | |
| | | <!-- æç¤ºè¯ä½ä¸ºæ£æµç»æçæç¤º --> |
| | | <view class="form-group tip-group"> |
| | | <view class="tip-box"> |
| | | <view class="tip-icon">â ï¸</view> |
| | | <view class="tip-text">没ææå¤§å¼åæå°å¼æ¶å¡«å<span class="highlight">0ï¼æªéè¿æ£éªï¼</span>æ<span |
| | | class="highlight">1ï¼éè¿æ£éªï¼</span></view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <button :class="['action-btn', 'btn-primary', { 'btn-loading': isLoading }]" |
| | | v-if="tableData.length < formData.checkQyt" @click="submit" :disabled="isLoading"> |
| | | {{ isLoading ? 'ä¿åä¸...' : 'ä¿å' }} |
| | | </button> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æ£éªç»æè¡¨æ ¼å¡ç --> |
| | | <view class="table-card"> |
| | | <view class="table-title"> |
| | | <view class="title-icon">ð</view> |
| | | <span>æ£éªç»æå表</span> |
| | | </view> |
| | | <view class="list-container"> |
| | | <uni-table ref="table" border emptyText="ææ æ´å¤æ°æ®"> |
| | | <uni-tr> |
| | | <uni-th width="80" align="center" class="th">ç¼å·</uni-th> |
| | | <uni-th width="120" align="center" class="th">å¤å®æ è¯</uni-th> |
| | | <uni-th width="100" align="center" class="th">æ£éªç»æ</uni-th> |
| | | <uni-th width="120" align="center" class="th">æä½</uni-th> |
| | | </uni-tr> |
| | | <uni-tr v-for="(item, index) in tableData" :key="index" class="table-row" |
| | | :class="{ 'hover-effect': isHoveringRow === index }" @mouseenter="isHoveringRow = index" |
| | | @mouseleave="isHoveringRow = -1"> |
| | | <uni-td align="center"> |
| | | {{ index + 1 }} |
| | | </uni-td> |
| | | <uni-td align="center"> |
| | | <input class="form-input" disabled="true" type="text" v-model="item.fstand" /> |
| | | </uni-td> |
| | | <uni-td align="center"> |
| | | <span class="result-badge" |
| | | :class="{ 'pass': item.fcheckResu === 'OK', 'fail': item.fcheckResu === 'NG' }"> |
| | | {{ item.fcheckResu || 'æªæ£éª' }} |
| | | </span> |
| | | </uni-td> |
| | | <uni-td align="center"> |
| | | <view class="action-group"> |
| | | <button :class="['action-btn', 'btn-sm', 'btn-warn', { 'btn-disabled': isLoading }]" |
| | | v-if="isNumber" @click="toDetail(item)" :disabled="isLoading"> |
| | | {{ isLoading ? 'å¤çä¸...' : 'ä¿®æ¹' }} |
| | | </button> |
| | | <button :class="['action-btn', 'btn-sm', 'btn-warn', { 'btn-disabled': isLoading }]" |
| | | v-if="!isNumber" @click="numberEdit(item)" :disabled="isLoading"> |
| | | {{ isLoading ? 'å¤çä¸...' : editResult(item.fcheckResu) }} |
| | | </button> |
| | | </view> |
| | | </uni-td> |
| | | </uni-tr> |
| | | </uni-table> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æä½æé® --> |
| | | <view class="action-buttons"> |
| | | <view class="button-group"> |
| | | <button :class="['action-btn', 'btn-warn', { 'btn-disabled': isLoading }]" @click="saveRemarks" |
| | | :disabled="isLoading"> |
| | | {{ isLoading ? 'å¤çä¸...' : 'æ·»å ä¸åæ ¼æè¿°' }} |
| | | </button> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- ä¿®æ¹æ£éªç»æå¼¹åºå± --> |
| | | <view v-if="showPopup" class="overlay active"> |
| | | <view class="popup" :class="{ 'popup-scale': isPopupAnimated }" @animationend="isPopupAnimated = false"> |
| | | <view class="popup-header"> |
| | | <h3 class="popup-title">ä¿®æ¹æ£éªç»æ</h3> |
| | | <view class="close-btn" @click="showPopup = !showPopup">Ã</view> |
| | | </view> |
| | | <form :modelValue="editData"> |
| | | <view class="form-group"> |
| | | <label class="form-label">æ£éªç»æ:</label> |
| | | <input class="form-input" type="text" v-model="editData.fcheckResu" /> |
| | | </view> |
| | | <view class="button-group"> |
| | | <button :class="['action-btn', 'btn-warn', { 'btn-loading': isEditLoading }]" @click="eidt" |
| | | :disabled="isEditLoading"> |
| | | {{ isEditLoading ? 'ä¿®æ¹ä¸...' : 'ä¿®æ¹' }} |
| | | </button> |
| | | <button @click="showPopup = !showPopup"> |
| | | åæ¶ |
| | | </button> |
| | | </view> |
| | | </form> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- ä¿®æ¹ä¸åæ ¼æè¿°å¼¹åºå± --> |
| | | <view v-if="remarksPopup" class="overlay active"> |
| | | <view class="popup" :class="{ 'popup-scale': isPopupAnimated }" @animationend="isPopupAnimated = false"> |
| | | <view class="popup-header"> |
| | | <h3 class="popup-title">ä¿®æ¹ä¸åæ ¼æè¿°</h3> |
| | | <view class="close-btn" @click="remarksPopup = !remarksPopup">Ã</view> |
| | | </view> |
| | | <form> |
| | | <view class="form-group"> |
| | | <label class="form-label">ä¸åæ ¼æè¿°:</label> |
| | | <input class="form-input" type="text" v-model="remarks" /> |
| | | </view> |
| | | <view class="button-group"> |
| | | <button :class="['action-btn', 'btn-warn', { 'btn-loading': isRemarksLoading }]" |
| | | @click="editRemarks" :disabled="isRemarksLoading"> |
| | | {{ isRemarksLoading ? 'ä¿åä¸...' : 'ä¿®æ¹' }} |
| | | </button> |
| | | <button @click="remarksPopup = !remarksPopup"> |
| | | åæ¶ |
| | | </button> |
| | | </view> |
| | | </form> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | formData: {}, |
| | | releaseNo: "", |
| | | isNumber: false, |
| | | checkItem: "", |
| | | id: 0, |
| | | gid: 0, |
| | | billNo: "", |
| | | showPopup: false, |
| | | editData: {}, |
| | | tableData: [], |
| | | remarks: "", |
| | | remarksPopup: false, |
| | | fcheckResuK: "", |
| | | isLoading: false, |
| | | isEditLoading: false, |
| | | isRemarksLoading: false, |
| | | isHoveringRow: -1, |
| | | isPopupAnimated: false |
| | | }; |
| | | }, |
| | | methods: { |
| | | editResult(fcheckResu) { |
| | | if (fcheckResu == "OK") { |
| | | return "æ¹ä¸ºä¸åæ ¼"; |
| | | } else { |
| | | return "æ¹ä¸ºåæ ¼"; |
| | | } |
| | | }, |
| | | submit() { |
| | | this.isLoading = true; |
| | | let count = this.formData.checkQyt; |
| | | let fstand = "â"; |
| | | if (Number(this.formData.fupAllow) && Number(this.formData.fdownAllow)) { |
| | | if (!this.fcheckResuK) { |
| | | this.$showMessage("请è¾å
¥æ£éªå¼"); |
| | | this.isLoading = false; |
| | | return; |
| | | } |
| | | if ( |
| | | Number(this.fcheckResuK) >= Number(this.formData.fdownAllow) && |
| | | Number(this.fcheckResuK) <= Number(this.formData.fupAllow) |
| | | ) { |
| | | fstand = "â"; |
| | | } else { |
| | | fstand = "Ã"; |
| | | } |
| | | count = 1; |
| | | } else { |
| | | if (!this.fcheckResuK) { |
| | | this.formData.fcheckResu = 1; |
| | | } |
| | | if (this.fcheckResuK == 0 || this.fcheckResuK == 1) { |
| | | this.formData.isPass = this.fcheckResuK; |
| | | } else { |
| | | this.$showMessage("æ æ å弿¶ï¼æ£éªç»æåªè½ä¸º0æ1!"); |
| | | this.isLoading = false; |
| | | return; |
| | | } |
| | | count = count - this.tableData.length; |
| | | } |
| | | this.formData.updater = this.$loginInfo.account; |
| | | this.$post({ |
| | | url: "/LLJ/SetQSItemDetail", |
| | | data: { |
| | | mainId: this.formData.id, |
| | | releaseNo: this.formData.releaseNo, |
| | | fstand: fstand, |
| | | fcheckResu: this.fcheckResuK, |
| | | LastupdateBy: this.$loginInfo.account, |
| | | count: count |
| | | } |
| | | }).then((res) => { |
| | | this.formData.fcheckResu = null; |
| | | this.$showMessage("ä¿åæå"); |
| | | this.refreshResult(); |
| | | this.isLoading = false; |
| | | }).catch(() => { |
| | | this.$showMessage("ä¿å失败ï¼è¯·éè¯"); |
| | | this.isLoading = false; |
| | | }); |
| | | }, |
| | | refreshResult() { |
| | | this.isLoading = true; |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/getXjDetail02ById", |
| | | data: { |
| | | id: this.id |
| | | } |
| | | }).then((res) => { |
| | | this.formData = res.data.tbBillList.itemXj01; |
| | | this.tableData = res.data.tbBillList.itemXj02s; |
| | | |
| | | if (this.formData.fupAllow && this.formData.fdownAllow && this.formData.fstand) { |
| | | this.isNumber = true; |
| | | } else { |
| | | this.isNumber = false; |
| | | } |
| | | this.isLoading = false; |
| | | }).catch(() => { |
| | | this.$showMessage("è·åæ°æ®å¤±è´¥"); |
| | | this.isLoading = false; |
| | | }); |
| | | }, |
| | | toDetail(item) { |
| | | this.showPopup = true; |
| | | this.editData = { |
| | | ...item |
| | | }; |
| | | }, |
| | | eidt() { |
| | | this.isEditLoading = true; |
| | | if (!this.editData.fcheckResu) { |
| | | this.$showMessage("请è¾å
¥æ£éªç»æ"); |
| | | this.isEditLoading = false; |
| | | return; |
| | | } |
| | | if (this.formData.fcheckResu == this.editData.fcheckResu) { |
| | | this.$showMessage("ä¿®æ¹æå"); |
| | | this.showPopup = false; |
| | | this.isEditLoading = false; |
| | | return; |
| | | } |
| | | let fstand = "â"; |
| | | if (this.formData.fupAllow && this.formData.fdownAllow) { |
| | | if (!this.editData.fcheckResu) { |
| | | this.$showMessage("请è¾å
¥æ£éªå¼"); |
| | | this.isEditLoading = false; |
| | | return; |
| | | } |
| | | if ( |
| | | Number(this.editData.fcheckResu) >= Number(this.formData.fdownAllow) && |
| | | Number(this.editData.fcheckResu) <= Number(this.formData.fupAllow) |
| | | ) { |
| | | this.editData.isPass = 1; |
| | | fstand = "â"; |
| | | } else { |
| | | this.editData.isPass = 0; |
| | | fstand = "Ã"; |
| | | } |
| | | } else { |
| | | if (!this.editData.fcheckResu) { |
| | | this.editData.fcheckResu = 1; |
| | | } |
| | | if (this.editData.fcheckResu == 0 || this.editData.fcheckResu == 1) { |
| | | if (this.editData.fcheckResu == 0) { |
| | | fstand = "Ã"; |
| | | } |
| | | } else { |
| | | this.$showMessage("æ æ å弿¶ï¼æ£éªç»æåªè½ä¸º0æ1!"); |
| | | this.isEditLoading = false; |
| | | return; |
| | | } |
| | | } |
| | | this.editData.updater = this.$loginInfo.account; |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/UpdateQSItemDetail", |
| | | data: { |
| | | id: this.editData.id, |
| | | mainId: this.formData.id, |
| | | releaseNo: this.formData.releaseNo, |
| | | fstand: fstand, |
| | | fcheckResu: this.editData.fcheckResu, |
| | | lastupdateBy: this.$loginInfo.account |
| | | } |
| | | }).then((res) => { |
| | | this.showPopup = false; |
| | | this.$showMessage("ä¿®æ¹æå"); |
| | | this.refreshResult(); |
| | | this.isEditLoading = false; |
| | | }).catch(() => { |
| | | this.$showMessage("ä¿®æ¹å¤±è´¥ï¼è¯·éè¯"); |
| | | this.isEditLoading = false; |
| | | }); |
| | | }, |
| | | numberEdit(item) { |
| | | this.isLoading = true; |
| | | let fstand = "â"; |
| | | let fcheckResu = "OK"; |
| | | if (item.fcheckResu == "OK") { |
| | | fstand = "Ã"; |
| | | fcheckResu = "NG"; |
| | | } |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/UpdateQSItemDetail", |
| | | data: { |
| | | id: item.id, |
| | | mainId: this.formData.id, |
| | | releaseNo: this.formData.releaseNo, |
| | | fstand: fstand, |
| | | fcheckResu: fcheckResu, |
| | | lastupdateBy: this.$loginInfo.account |
| | | } |
| | | }).then((res) => { |
| | | this.$showMessage("ä¿®æ¹æå"); |
| | | this.refreshResult(); |
| | | this.isLoading = false; |
| | | }).catch(() => { |
| | | this.$showMessage("ä¿®æ¹å¤±è´¥ï¼è¯·éè¯"); |
| | | this.isLoading = false; |
| | | }); |
| | | }, |
| | | saveRemarks() { |
| | | this.remarksPopup = true; |
| | | this.remarks = this.formData.remarks || ""; |
| | | }, |
| | | editRemarks() { |
| | | this.isRemarksLoading = true; |
| | | if (this.remarks) { |
| | | this.$post({ |
| | | url: "/MesOqcItemsDetect02/saveRemarksPid", |
| | | data: { |
| | | pid: this.formData.id, |
| | | remarks: this.remarks |
| | | } |
| | | }).then((res) => { |
| | | if (res.data.tbBillList > 0) { |
| | | this.formData.remarks = this.remarks; |
| | | this.remarksPopup = false; |
| | | this.$showMessage("ä¿åæå"); |
| | | } else { |
| | | this.$showMessage("ä¿å失败"); |
| | | } |
| | | this.isRemarksLoading = false; |
| | | }).catch(() => { |
| | | this.$showMessage("ä¿å失败ï¼è¯·éè¯"); |
| | | this.isRemarksLoading = false; |
| | | }); |
| | | } else { |
| | | this.$showMessage("请è¾å
¥ä¸åæ ¼æè¿°"); |
| | | this.isRemarksLoading = false; |
| | | } |
| | | } |
| | | }, |
| | | onLoad(options) { |
| | | let params = options; |
| | | this.id = params["mainId"]; |
| | | this.releaseNo = params["releaseNo"]; |
| | | this.refreshResult(); |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style> |
| | | /* 页é¢å®¹å¨ */ |
| | | .page-container { |
| | | padding: 20px; |
| | | background-color: #f5f5f5; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | /* 表åå¡ç */ |
| | | .form-card { |
| | | background-color: #fff; |
| | | border-radius: 12px; |
| | | padding: 20px; |
| | | margin-bottom: 20px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | /* è¡¨åæ é¢ */ |
| | | .form-title { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 18px; |
| | | color: #333; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .title-icon { |
| | | font-size: 22px; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | /* 表åå®¹å¨ */ |
| | | .form-container { |
| | | padding-top: 10px; |
| | | } |
| | | |
| | | /* è¡¨åæ¨¡åæ é¢ */ |
| | | .form-section { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .section-title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #333; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | /* è¡¨æ ¼å¸å± */ |
| | | .form-grid { |
| | | display: grid; |
| | | grid-template-columns: 1fr 1fr; |
| | | gap: 15px; |
| | | } |
| | | |
| | | /* 表å项 */ |
| | | .form-group { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .form-label { |
| | | width: 130px; |
| | | color: #333; |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .form-input { |
| | | flex: 1; |
| | | height: 40px; |
| | | padding: 0 10px; |
| | | border: 1px solid #e0e0e0; |
| | | border-radius: 8px; |
| | | background-color: #f8f8f8; |
| | | color: #666; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .form-input:disabled { |
| | | background-color: #e9e9e9; |
| | | } |
| | | |
| | | .form-input:focus { |
| | | border-color: #007AFF; |
| | | outline: none; |
| | | } |
| | | |
| | | /* æ£éªç»æåºå */ |
| | | .tip-group { |
| | | margin-top: 15px; |
| | | } |
| | | |
| | | .tip-box { |
| | | display: flex; |
| | | align-items: center; |
| | | background-color: #fff5d1; |
| | | padding: 10px; |
| | | border-radius: 8px; |
| | | border: 1px solid #f0e0a7; |
| | | } |
| | | |
| | | .tip-icon { |
| | | font-size: 20px; |
| | | color: #f39c12; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .tip-text { |
| | | font-size: 14px; |
| | | color: #333; |
| | | } |
| | | |
| | | .highlight { |
| | | color: #007AFF; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | /* æé®æ ·å¼ */ |
| | | .action-btn { |
| | | width: 100%; |
| | | padding: 12px; |
| | | border-radius: 8px; |
| | | border: none; |
| | | color: #fff; |
| | | font-size: 16px; |
| | | font-weight: 500; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | transition: background-color 0.3s ease; |
| | | } |
| | | |
| | | .btn-primary { |
| | | background-color: #007AFF; |
| | | } |
| | | |
| | | .btn-primary:hover { |
| | | background-color: #0056CC; |
| | | } |
| | | |
| | | .btn-warn { |
| | | background-color: #f1b344; |
| | | } |
| | | |
| | | .btn-warn:hover { |
| | | background-color: #e6a135; |
| | | } |
| | | |
| | | .btn-disabled { |
| | | background-color: #c0c0c0; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | /* å¼¹åºå±æ ·å¼ */ |
| | | .overlay { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: rgba(0, 0, 0, 0.5); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | z-index: 1000; |
| | | opacity: 0; |
| | | transition: opacity 0.3s ease; |
| | | } |
| | | |
| | | .overlay.active { |
| | | opacity: 1; |
| | | } |
| | | |
| | | .popup { |
| | | background-color: #fff; |
| | | border-radius: 12px; |
| | | width: 90%; |
| | | max-width: 500px; |
| | | padding: 20px; |
| | | transform: scale(0.8); |
| | | transition: transform 0.3s ease; |
| | | } |
| | | |
| | | .popup-scale { |
| | | transform: scale(1); |
| | | } |
| | | |
| | | .popup-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .popup-title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #333; |
| | | } |
| | | |
| | | .close-btn { |
| | | font-size: 20px; |
| | | color: #333; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | /* æä½æé®ç» */ |
| | | .button-group { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .button-group button { |
| | | width: 48%; |
| | | padding: 10px; |
| | | border-radius: 8px; |
| | | border: none; |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | /* æ£éªç»æè¡¨æ ¼å¡ç */ |
| | | .table-card { |
| | | background-color: #fff; |
| | | border-radius: 12px; |
| | | padding: 20px; |
| | | margin-bottom: 20px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | /* è¡¨æ ¼æ é¢ */ |
| | | .table-title { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 16px; |
| | | color: #333; |
| | | font-weight: 600; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .title-icon { |
| | | font-size: 22px; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | /* è¡¨æ ¼æ ·å¼ */ |
| | | .uni-table { |
| | | width: 100%; |
| | | border-collapse: collapse; |
| | | } |
| | | |
| | | .uni-th, |
| | | .uni-td { |
| | | padding: 12px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .uni-th { |
| | | background-color: #f5f5f5; |
| | | font-size: 14px; |
| | | color: #666; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .table-row { |
| | | background-color: #fff; |
| | | border-bottom: 1px solid #e0e0e0; |
| | | } |
| | | |
| | | .table-row:hover { |
| | | background-color: #f9f9f9; |
| | | } |
| | | |
| | | .result-badge { |
| | | padding: 5px 12px; |
| | | font-size: 12px; |
| | | border-radius: 10px; |
| | | color: #fff; |
| | | display: inline-block; |
| | | } |
| | | |
| | | .pass { |
| | | background-color: #28a745; |
| | | } |
| | | |
| | | .fail { |
| | | background-color: #dc3545; |
| | | } |
| | | |
| | | .pending { |
| | | background-color: #f1b344; |
| | | } |
| | | |
| | | .action-group { |
| | | display: flex; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .action-btn.btn-sm { |
| | | width: auto; |
| | | padding: 6px 12px; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | /* æç¤ºä¿¡æ¯ */ |
| | | .hover-effect:hover { |
| | | background-color: #f9f9f9; |
| | | } |
| | | |
| | | .btn-sm { |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .btn-loading { |
| | | background-color: #c0c0c0; |
| | | cursor: not-allowed; |
| | | } |
| | | </style> |
| | |
| | | import Vuex from 'vuex' |
| | | |
| | | //å¼å
¥vuexæä»¶ è¿è¡ç¶æç®¡ç |
| | | Vue.use(Vuex) |
| | | Vue.use(Vuex) |
| | | const store = new Vuex.Store({ |
| | | state: { |
| | | state: { |
| | | id: 'id', |
| | | serverInfo:{//æå¡ä¿¡æ¯ |
| | | networkFlag:'å
ç½', |
| | | serverURLInt:'http://192.168.11.251:10054',//æå¡å¨ä½æ£ 10.0.1.104:10054 |
| | | serverURL:'http://localhost:10054',//æ¬å°è°è¯å°å |
| | | serverAPI:'http://localhost:5184/api',//å½åæ£å¨ä½¿ç¨æ¬å° |
| | | // serverAPI:'http://192.168.1.92:10054/api',//å½åæ£å¨ä½¿ç¨çæå¡å¨ |
| | | serverInfo: { //æå¡ä¿¡æ¯ |
| | | networkFlag: 'å
ç½', |
| | | serverURLInt: 'http://192.168.11.251:10054', //æå¡å¨ä½æ£ 10.0.1.104:10054 |
| | | serverURL: 'http://localhost:10054', //æ¬å°è°è¯å°å |
| | | serverAPI:'http://localhost:10054/api',//å½åæ£å¨ä½¿ç¨æ¬å° |
| | | //serverAPI: 'http://192.168.1.92:10054/api', //å½åæ£å¨ä½¿ç¨çæå¡å¨ |
| | | } |
| | | }, |
| | | mutations: { |
| | | test(state,id){ |
| | | test(state, id) { |
| | | state.id = id; |
| | | } |
| | | }, |
| | | getters:{ |
| | | currentColor(state){ |
| | | return state.colorList[state.colorIndex] |
| | | } |
| | | }, |
| | | getters: { |
| | | currentColor(state) { |
| | | return state.colorList[state.colorIndex] |
| | | } |
| | | }, |
| | | actions: { |
| | | // lazy loading openid |
| | | } |
| | | }) |
| | | |
| | | export default store |
| | | export default store |