啊鑫
2025-07-24 ef905a448385c2a78f3ebaa51d2420e1d7765bb9
优化首检模块UI和功能

- 优化备注弹出框大小和输入体验,支持多行文本输入
- 修改列表页状态显示逻辑,直接展示item.result值而非"已分配给"
- 添加检验结果颜色区分:合格(绿色)、不合格(蓝色)
- 优化提交成功后页面跳转逻辑,支持多种响应格式
- 添加fSubmit字段控制审核按钮显示状态
- 更新CLAUDE.md项目文档,完善架构说明
已修改3个文件
已添加1个文件
230 ■■■■ 文件已修改
CLAUDE.md 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/SJ/Add.vue 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/SJ/List.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/SJ/detail.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CLAUDE.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,122 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a **uni-app** mobile application project for Quality Control (QC) and Warehouse management in a Manufacturing Execution System (MES). The application is built for PDA devices and supports quality inspection processes and warehouse operations.
- **Framework**: uni-app (Vue 2.x based)
- **App Name**: GS-MES-AP (广深科技 MES Application)
- **Target Platform**: Android mobile/PDA devices
- **UI Framework**: uView UI library
## Build and Development Commands
This is a uni-app project that builds through HBuilderX IDE or uni-app CLI. The build output is generated in the `unpackage/` directory:
- **Development Build**: Use HBuilderX IDE or `npm run dev:app-plus` for development
- **Production Build**: APK files are generated in `unpackage/release/apk/`
- **Cache**: Build cache and temporary files are stored in `unpackage/cache/`
- **Testing**: Use HBuilderX IDE's built-in testing tools or deploy to PDA devices for testing
**Note**: This project does not have traditional npm scripts. Development and building are primarily done through HBuilderX IDE.
## Architecture Overview
### Core Structure
- **Entry Point**: `main.js` - Contains Vue prototypes, global mixins, and API configuration
- **State Management**: `store/index.js` - Vuex store with server configuration and minimal state
- **Routing**: `pages.json` - uni-app page configuration with tabBar navigation
- **Global Config**: `manifest.json` - App configuration including permissions and build settings
### Key Directories
- `pages/BasePages/` - Core app pages (login, main menu, user profile)
- `pages/QC/` - Quality Control modules (来料检验 LLJ, å·¡æ£€ XJ, é¦–检 SJ, å…¥åº“检 RKJ)
- `pages/Warehouse/` - Warehouse operations (inventory, purchasing, allocation)
- `components/` - Reusable UI components and third-party integrations
- `static/` - Static assets (images, audio files, CSS)
- `uni_modules/` - uni-app plugin modules including uView UI
### API Architecture
- **Base API**: Configured in Vuex store with environment-specific URLs
- **Request Methods**: Custom Vue prototypes (`$post`, `$get`, `$uni_request`) with loading states
- **Authentication**: User login state managed globally via `$loginInfo`
- **Error Handling**: Centralized error handling with toast messages
### Main Features
1. **Quality Control (QC)**:
   - æ¥æ–™æ£€éªŒ (LLJ) - Incoming Material Inspection
   - å·¡æ£€ (XJ) - Patrol Inspection
   - é¦–检 (SJ) - First Article Inspection
   - å…¥åº“检 (RKJ) - Warehouse Inspection
2. **Warehouse Operations**:
   - Purchase inventory management
   - Material allocation and transfers
   - Barcode printing and scanning
3. **Common Functions**:
   - Barcode/QR code scanning
   - Photo capture and upload
   - Bluetooth printing integration
   - Offline data synchronization
### Navigation Structure
- **Tab Bar**: 3 main tabs (首页/Home, æ¶ˆæ¯ä¸­å¿ƒ/Message Center, æˆ‘çš„/Profile)
- **Menu System**: Dynamic menu loading based on user permissions via `$getUserMenu()`
- **Page Flow**: List â†’ Detail â†’ Form pattern for most workflows
## Development Guidelines
### Server Configuration
The app connects to different servers based on environment:
- Development: `http://localhost:10054` or `http://192.168.1.104:10056/api`
- Check `store/index.js` for current active server endpoints
### Global Utilities
- `$showMessage()` - Display toast notifications
- `$showDialog()` - Show confirmation dialogs
- `$camera()` - Camera/photo selection functionality
- `$getDate()` - Date formatting utilities
- `$getUrlParams()` - URL parameter parsing
### Component Dependencies
- **uView UI**: Primary UI component library
- **Custom Components**: Scanner, printer utilities in `components/kk-printer/`
- **Third-party**: Charts (u-charts), maps (amap), markdown parsing
### File Upload System
Image uploads use base64 encoding via `$fileUpload()` method, sending to `/Base/saveImage` endpoint.
### Authentication System
- User authentication is managed through `$loginInfo` object in `main.js`
- Login state persists using `uni.getStorageSync()` and `uni.setStorageSync()`
- Global mixin `globalMixin.js` provides `checkUserAuth()` for automatic login verification
- Users are redirected to `/pages/BasePages/login` if not authenticated
### Request Architecture
- **$post()** and **$get()**: Standard API requests with automatic loading indicators
- **$uni_request()**: Core request method with error handling and status checking
- **$toERP()**: External ERP system integration requests
- **$postSyncPost()**: Promise-based synchronous POST requests
- All requests automatically handle loading states, error messages, and network failures
### Hardware Integration
- **Camera**: Native camera access via `$camera()` with image compression options
- **Barcode Scanner**: QR/barcode scanning capabilities for PDA devices
- **Bluetooth Printing**: Printer integration through `components/kk-printer/`
- **Device Permissions**: Configured in `manifest.json` for camera, storage, network, and Bluetooth access
### Page Architecture Patterns
- **List Pages**: Pagination with pull-to-refresh and infinite scroll
- **Detail Pages**: Read-only view with navigation to edit forms
- **Add/Edit Forms**: Input validation and submission with photo upload capabilities
- **Scan Pages**: Barcode scanning with immediate data processing
### Environment Configuration
Current server endpoints are configured in `store/index.js`:
- **Development**: `http://localhost:5184/api`
- **Internal Network**: `http://192.168.11.251:10054`
- **Testing**: `http://192.168.1.104:10056/api` or `10057/api`
- Switch between environments by updating `serverAPI` in the Vuex store
pages/QC/SJ/Add.vue
@@ -53,12 +53,8 @@
        <view class="info-value highlight">{{ formData.daa008 }}</view>
      </view>
      <view v-if="formData.remarks" class="info-block">
        <view class="info-label">不合格描述:</view>
        <view class="info-value">{{ formData.remarks }}</view>
      </view>
      <view v-if="formData.comments" class="info-block">
        <view class="info-label">备注:</view>
        <view class="info-value">{{ formData.comments }}</view>
        <view class="info-value">{{ formData.remarks }}</view>
      </view>
    </view>
@@ -137,9 +133,8 @@
      <button v-if="!isUpdate && !formData.statusUser && !isShowTable" class="secondary-btn" @click="removeXJ">
        åˆ é™¤å•据
      </button>
      <button v-if="!isUpdate && !isShowTable" class="secondary-btn" @click="saveRemarks">添加不合格描述</button>
      <button v-if="!isUpdate && !isShowTable" class="secondary-btn" @click="saveComments">添加备注</button>
      <button v-if="!isUpdate && !isShowTable" class="primary-btn" @click="submit">审核单据</button>
      <button v-if="!isUpdate && !isShowTable" class="secondary-btn" @click="saveRemarks">添加备注</button>
      <button v-if="!isUpdate && !isShowTable && formData.fSubmit != 1" class="primary-btn" @click="submit">审核单据</button>
      <button v-if="isShowTable" class="secondary-btn" @click="getTable">获取检验项目</button>
      <button v-if="isShowTable && isUpdate" class="primary-btn" @click="saveTable">生成检验项目</button>
    </view>
@@ -147,28 +142,14 @@
    <!-- å¼¹çª— -->
    <view v-if="remarksPopup" class="overlay">
      <view class="popup">
        <h3>修改不合格描述</h3>
        <form>
          <view class="form-group">
            <label class="form-label">不合格描述:</label>
            <input v-model="remarks" class="form-input" type="text"/>
          </view>
          <button class="updateBut" @click="editRemarks">修改</button>
          <button @click="remarksPopup = !remarksPopup">取消</button>
        </form>
      </view>
    </view>
    <view v-if="commentsPopup" class="overlay">
      <view class="popup">
        <h3>修改备注</h3>
        <form>
          <view class="form-group">
            <label class="form-label">备注:</label>
            <input v-model="comments" class="form-input" type="text"/>
            <textarea v-model="remarks" class="form-input form-textarea" placeholder="请输入备注信息..."></textarea>
          </view>
          <button class="updateBut" @click="editComments">修改</button>
          <button @click="commentsPopup = !commentsPopup">取消</button>
          <button class="updateBut" @click="editRemarks">修改</button>
          <button @click="remarksPopup = !remarksPopup">取消</button>
        </form>
      </view>
    </view>
@@ -191,6 +172,7 @@
        comments: "",
        statusUser: "",
        itemId: "",
        fSubmit: 0,
      },
      DAA020List: [],
@@ -300,17 +282,26 @@
      }).then(res => {
        //2024-11-28 kyy æ ¡éªŒåˆæ ¼æäº¤å¢žåŠ æç¤º
        console.log("完整响应数据:", res);
        console.log("Status Code的值:", res.statusCode);
        if (res.statusCode === 200) {
        console.log("返回的数据:", res.data);
        // æ£€æŸ¥å¤šç§æˆåŠŸæ¡ä»¶
        if (res.statusCode === 200 || res.status === 0 || res.data === true || res.data.tbBillList === true) {
          this.$showMessage("成功提交检验");
          // ä½¿ç”¨setTimeout在7秒后隐藏消息
          // æäº¤æˆåŠŸåŽè·³è½¬åˆ°åˆ—è¡¨é¡µé¢
          setTimeout(() => {
            this.hideCustomMessage();
          }, 7000); // 7000毫秒等于7秒
            uni.navigateTo({
              url: '/pages/QC/SJ/List'
            });
          }, 1500); // 1.5秒后跳转,让用户看到成功提示
        } else {
          this.$showMessage(res.data.message);
          this.$showMessage(res.data.message || res.message || "提交失败");
        }
      }).catch(err => {
        console.log("提交出错:", err);
        this.$showMessage("提交失败,请重试");
      })
    },
@@ -426,7 +417,7 @@
        this.$post({
          url: "/SJ/SetQSItems",
          data: {
            itemId: this.formData.itemNo
            itemNo: this.formData.itemNo
          }
        }).then(res => {
          if (res.data.tbBillList.length > 0) {
@@ -459,7 +450,7 @@
      this.$post({
        url: "/SJ/SetQSItems",
        data: {
          itemId: this.formData.itemNo
          itemNo: this.formData.itemNo
        }
      }).then(res => {
        if (res.data.tbBillList.length > 0) {
@@ -1001,8 +992,9 @@
  padding: 20px;
  border: 1px solid #ccc;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  width: 68vw;
  height: 25vh;
  width: 85vw;
  min-height: 35vh;
  max-height: 60vh;
  border-radius: 8px;
}
@@ -1035,6 +1027,13 @@
  border-radius: 4px;
  font-size: 14px;
  box-sizing: border-box;
}
.popup .form-textarea {
  min-height: 120px;
  resize: vertical;
  font-family: inherit;
  line-height: 1.5;
}
.popup-buttons {
@@ -1155,6 +1154,18 @@
    width: 6px;
    height: 6px;
  }
  /* ç§»åŠ¨ç«¯å¼¹å‡ºæ¡†ä¼˜åŒ– */
  .popup {
    width: 95vw;
    min-height: 40vh;
    max-height: 70vh;
    padding: 15px;
  }
  .popup .form-textarea {
    min-height: 100px;
  }
}
/* å¹³æ¿è®¾å¤‡æ ·å¼ */
pages/QC/SJ/List.vue
@@ -35,9 +35,15 @@
          <view v-if="item.urgent == 1" class="badge urgent">急料</view>
          <view v-if="item.isFirst == 1" class="badge normal">首次</view>
          <view class="card-title">检验单号: {{ item.billNo }}</view>
          <view :class="{'status-pending': current === 0, 'status-assigned': current === 0 && item.statusUser, 'status-pass': current === 1 && item.result === '合格', 'status-fail': current === 1 && item.result === '不合格'}"
          <view :class="{
                  'status-pending': !item.result && current === 0,
                  'status-assigned': current === 0 && item.statusUser && !item.result,
                  'status-pass': item.result === '合格',
                  'status-fail': item.result === '不合格',
                  'status-submitted': !item.result && current === 1
                }"
                class="status">
            {{ current === 0 ? (item.statusUser ? '已分配' : '未提交') : (item.result ? item.result : '已提交') }}
            {{ current === 0 ? (item.result ? item.result : '未提交') : (item.result ? item.result : '已提交') }}
          </view>
        </view>
@@ -460,7 +466,12 @@
}
.status-fail {
  background: linear-gradient(135deg, #e74c3c, #c0392b);
  background: linear-gradient(135deg, #3498db, #2980b9);
  color: white;
}
.status-submitted {
  background: linear-gradient(135deg, #95a5a6, #7f8c8d);
  color: white;
}
pages/QC/SJ/detail.vue
@@ -76,7 +76,7 @@
              <view class="info-value">{{ formData.result }}</view>
            </view>
            <view v-if="formData.remarks" class="info-item">
              <view class="info-label">不合格描述</view>
              <view class="info-label">备注</view>
              <view class="info-value danger">{{ formData.remarks }}</view>
            </view>
          </view>
@@ -104,7 +104,7 @@
              </button>
              <button class="btn upload-btn" @click="saveRemarks">
                <uni-icons color="#fff" size="16" type="compose"></uni-icons>
                ä¸åˆæ ¼æè¿°
                å¤‡æ³¨
              </button>
            </view>
          </view>
@@ -118,7 +118,7 @@
              </button>
              <button class="btn upload-btn" @click="saveRemarks">
                <uni-icons color="#fff" size="16" type="compose"></uni-icons>
                ä¸åˆæ ¼æè¿°
                å¤‡æ³¨
              </button>
            </view>
            <view class="input-wrapper" style="margin-top: 15px;">
@@ -181,13 +181,13 @@
        </view>
      </view>
      <!-- å¼¹å‡ºå±‚ - ä¸åˆæ ¼æè¿° -->
      <!-- å¼¹å‡ºå±‚ - å¤‡æ³¨ -->
      <view v-if="remarksPopup" class="overlay">
        <view class="popup">
          <h3>修改不合格描述</h3>
          <h3>修改备注</h3>
          <form>
            <view class="form-group">
              <label class="form-label">不合格描述:</label>
              <label class="form-label">备注:</label>
              <input v-model="remarks" class="form-input" type="text"/>
            </view>
            <view class="popup-buttons">