From 30590221cd34912a61f4734ea474859a0df98be6 Mon Sep 17 00:00:00 2001
From: Houjie <714924425@qq.com>
Date: 星期五, 05 九月 2025 15:19:03 +0800
Subject: [PATCH] 上料 下料 报工  图标添加  打印机配置

---
 uni_modules/uv-ui-tools/libs/css/components.scss                                          |   23 
 uni_modules/uv-ui-tools/libs/luch-request/index.d.ts                                      |  197 
 uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js                        |   14 
 pages/eam/quality/productionInspection/productionInspection.vue                           |  801 ++
 uni_modules/uv-ui-tools/libs/util/dayjs.js                                                |  216 
 pages/eam/andon/andonDetail/andonDetail.vue                                               |  315 
 pages/eam/production/ProductionManager/ProductionManager.vue                              |  965 ++
 uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js                               |  132 
 uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js                                  |  264 
 uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js                                |   33 
 pages/eam/quality/qualityInspection/addInspection/addInspection.vue                       |  446 +
 uni_modules/uv-ui-tools/index.scss                                                        |    7 
 pages/eam/quality/inspectionDetail/inspectionDetail.vue                                   |  456 +
 pages/eam/quality/qualityInspectionDetail/qualityInspectionDetail.vue                     |  444 +
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/image.js                           |   96 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLmethod.js              |  142 
 uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js                             |   64 
 pages/eam/quality/defectiveProductReview/defectiveProductReview.vue                       |  587 +
 uni_modules/uv-ui-tools/libs/luch-request/utils.js                                        |  135 
 pages/eam/production/materialLoading/materialLoading.vue                                  |  443 +
 uni_modules/uv-ui-tools/libs/mixin/mpShare.js                                             |   13 
 uni_modules/uv-ui-tools/changelog.md                                                      |   76 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/tool.js                            |   24 
 pages/finished-product-preview/finished-product-preview.vue                               |  333 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Buffer.js                |   21 
 pages/eam/production/sample/sample.vue                                                    |  358 
 uni_modules/uv-ui-tools/libs/function/debounce.js                                         |   29 
 pages/eam/andon/myInitiated/myInitiated.vue                                               |  361 
 static/home/128/icon_code.png                                                             |    0 
 uni_modules/uv-ui-tools/libs/css/variable.scss                                            |  111 
 pages/eam/production/feed/feed.vue                                                        |  163 
 uni_modules/uv-ui-tools/libs/function/throttle.js                                         |   30 
 uni_modules/uv-ui-tools/libs/function/digit.js                                            |  167 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js  |   17 
 pages/eam/production/record/record.vue                                                    |  876 ++
 uni_modules/uv-qrcode/components/uv-qrcode/props.js                                       |   85 
 common/util/system.js                                                                     |  152 
 pages/eam/andon/andonAction/andonAction.vue                                               |  286 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/RenderingContext.js      | 1191 +++
 uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js                           |   20 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Program.js               |   21 
 static/home/128/icon_wait.png                                                             |    0 
 uni_modules/uv-qrcode/package.json                                                        |   87 
 uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js                             |  126 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/classUtils.js            |    3 
 components/mes/pdaScan.vue                                                                |   79 
 uni_modules/uv-qrcode/components/uv-qrcode/cache.js                                       |    1 
 static/index_logo.png                                                                     |    0 
 uni_modules/uv-ui-tools/libs/config/config.js                                             |   34 
 pages/eam/andon/andonAdd/andonAdd.vue                                                     |  359 
 uni_modules/uv-ui-tools/libs/function/test.js                                             |  287 
 uni_modules/uv-ui-tools/libs/mixin/mixin.js                                               |  172 
 pages/eam/quality/checkItem/checkItem.vue                                                 |  468 +
 pages/eam/andon/andonHandler/andonHandler.vue                                             |  671 +
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/index.js                               |   39 
 uni_modules/uv-ui-tools/index.js                                                          |   79 
 uni_modules/uv-ui-tools/libs/function/colorGradient.js                                    |  134 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ActiveInfo.js            |   11 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js |   11 
 uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue                                  | 1038 ++
 uni_modules/uv-ui-tools/libs/css/vue.scss                                                 |   40 
 static/icon_dayin.png                                                                     |    0 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLenum.js                |  298 
 uni_modules/uv-qrcode/changelog.md                                                        |   13 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/RenderingContext.js         |  666 +
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/UniformLocation.js       |   22 
 uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js                          |   14 
 uni_modules/uv-ui-tools/libs/util/route.js                                                |  126 
 pages/eam/production/check/check.vue                                                      |  355 
 uni_modules/uv-qrcode/readme.md                                                           |   21 
 uni_modules/uv-ui-tools/libs/luch-request/core/Request.js                                 |  201 
 uni_modules/uv-ui-tools/libs/mixin/mpMixin.js                                             |    8 
 static/home/128/icon_report.png                                                           |    0 
 static/home/128/icon_quality.png                                                          |    0 
 uni_modules/uv-ui-tools/libs/css/color.scss                                               |   32 
 pages/eam/andon/andonRespond/andonRespond.vue                                             |  335 
 pages/selectUsers/selectUsers.vue                                                         |  315 
 pages/eam/production/ToDoList/ToDoList.vue                                                |  566 +
 pages/eam/quality/reviewDocument/reviewDocument.vue                                       |  468 +
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js  |   18 
 pages/print-preview/print-preview.vue                                                     |  356 
 uni_modules/uv-ui-tools/libs/mixin/button.js                                              |   13 
 uni_modules/uv-ui-tools/libs/function/platform.js                                         |   75 
 uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js                      |   51 
 common/util/printer-commands.js                                                           |  322 
 uni_modules/uv-ui-tools/libs/function/index.js                                            |  734 +
 pages/eam/andon/andonCall/andonCall.vue                                                   |  405 +
 uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js                         |    6 
 uni_modules/uv-ui-tools/libs/luch-request/index.js                                        |    2 
 uni_modules/uv-ui-tools/libs/mixin/openType.js                                            |   47 
 uni_modules/uv-ui-tools/readme.md                                                         |   23 
 uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue                            |    6 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Framebuffer.js           |   21 
 uni_modules/uv-qrcode/components/uv-qrcode/queue.js                                       |   41 
 static/home/128/icon_into.png                                                             |    0 
 uni_modules/uv-ui-tools/libs/css/common.scss                                              |  100 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Renderbuffer.js          |   21 
 uni_modules/uv-ui-tools/libs/luch-request/core/settle.js                                  |   16 
 static/home/128/icon_out.png                                                              |    0 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Shader.js                |   22 
 pages/eam/production/report/report.vue                                                    |  526 +
 pages/lineSelect/lineSelect.vue                                                           |  260 
 uni_modules/uv-ui-tools/package.json                                                      |   81 
 pages/inspection-tag-preview/inspection-tag-preview.vue                                   |  227 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/canvas.js                          |   74 
 uni_modules/uv-ui-tools/theme.scss                                                        |   43 
 pages/eam/production/partBlanking/partBlanking.vue                                        |   22 
 pages/eam/quality/checkItemDetail/checkItemDetail.vue                                     |  492 +
 pages/eam/quality/text/text.vue                                                           |   25 
 components/ren-dropdown-filter/ren-dropdown-filter.vue                                    |  244 
 pages/eam/quality/qualityInspection/qualityInspection.vue                                 |  780 ++
 uni_modules/uv-qrcode/components/uv-qrcode/qrcode.js                                      |   34 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLtype.js                |   23 
 uni_modules/uv-ui-tools/libs/mixin/touch.js                                               |   59 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/bridge/bridge-weex.js                  |  241 
 pages/eam/production/process/process.vue                                                  |  368 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Texture.js               |   22 
 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStylePattern.js         |    8 
 118 files changed, 23,001 insertions(+), 0 deletions(-)

diff --git a/common/util/printer-commands.js b/common/util/printer-commands.js
new file mode 100644
index 0000000..133e8f1
--- /dev/null
+++ b/common/util/printer-commands.js
@@ -0,0 +1,322 @@
+// pages/user/printer-commands.js
+export class PrinterCommands {
+  constructor(model = 'generic') {
+    this.model = model; // 鎵撳嵃鏈哄瀷鍙凤紙zebra/epson/citizen/generic锛�
+    // 1. ESC/POS 鍗忚瀵归綈鎸囦护锛堢埍鏅敓绛夐潪鏂戦┈鎵撳嵃鏈虹敤锛�
+    this.escPosAlign = {
+      left: [0x1B, 0x61, 0x00],
+      center: [0x1B, 0x61, 0x01],
+      right: [0x1B, 0x61, 0x02]
+    };
+    // 2. ZPL 鍗忚鍩虹鎸囦护锛堟枒椹墦鍗版満涓撶敤锛�
+    this.zplBase = {
+      start: '^XA',       // 鏍囩寮�濮�
+      end: '^XZ',         // 鏍囩缁撴潫
+      utf8: '^CI28',      // 鏀寔UTF-8缂栫爜锛堣В鍐充腑鏂囦贡鐮侊級
+      font: '^CFSIMSUN,', // 涓枃瀛椾綋锛堥渶鎻愬墠涓婁紶SIMSUN.TTF鍒版枒椹墦鍗版満锛�
+      qrCode: '^BQN,2,10' // 浜岀淮鐮侀厤缃紙QR Code锛岀籂閿欑瓑绾�2锛屽ぇ灏�10锛�
+    };
+  }
+
+  // ========================== 閫氱敤宸ュ叿鏂规硶 ==========================
+  // 鎷兼帴澶氫釜Uint8Array锛堝吋瀹逛袱绉嶅崗璁級
+  concatArrays(...arrays) {
+    const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
+    const result = new Uint8Array(totalLength);
+    let offset = 0;
+    arrays.forEach(arr => {
+      result.set(arr, offset);
+      offset += arr.length;
+    });
+    return result;
+  }
+
+  // 鏂囨湰杞琔int8Array锛堝吋瀹筓TF-8锛�
+  textToUint8(text) {
+    return new TextEncoder('utf-8').encode(text);
+  }
+
+  // ZPL鎸囦护瀛楃涓茶浆Uint8Array锛堟枒椹笓鐢級
+  zplToUint8(zplStr) {
+    // 鍘婚櫎澶氫綑绌烘牸锛岄伩鍏峑PL瑙f瀽閿欒
+    const cleanZpl = zplStr.replace(/\s+/g, '');
+    return this.textToUint8(cleanZpl);
+  }
+
+
+  // ========================== ESC/POS 鍗忚鎸囦护锛堥潪鏂戦┈鐢級 ==========================
+  // 鍒濆鍖栨墦鍗版満锛圗SC/POS锛�
+  escPosInit() {
+    return new Uint8Array([0x1B, 0x40]);
+  }
+
+  // 鎹㈣锛圗SC/POS锛�
+  escPosNewLine(lines = 1) {
+    const cmd = [];
+    for (let i = 0; i < lines; i++) cmd.push(0x0A);
+    return new Uint8Array(cmd);
+  }
+
+  // 鏂囨湰鍔犵矖锛圗SC/POS锛�
+  escPosBold(enable = true) {
+    return new Uint8Array([0x1B, 0x45, enable ? 0x01 : 0x00]);
+  }
+
+  // 璁剧疆瀛楀彿锛圗SC/POS锛�
+  escPosSetFontSize(size = 0) {
+    // 0:姝e父, 1:鍙屽�嶉珮, 2:鍙屽�嶅, 3:鍙屽�嶉珮浣�
+    return new Uint8Array([0x1D, 0x21, size]);
+  }
+
+  // 鍒囩焊锛圗SC/POS锛�
+  escPosCutPaper(partial = true) {
+    return new Uint8Array([0x1D, 0x56, partial ? 0x00 : 0x01]);
+  }
+
+  // 鎵撳嵃鍥剧墖锛圗SC/POS锛岄潪鏂戦┈鐢級
+  escPosPrintImage(buffer) {
+    const header = this.model === 'epson' 
+      ? [0x1B, 0x2A, 0x00] // 鐖辨櫘鐢熶綅鍥炬寚浠�
+      : [0x1D, 0x76, 0x30, 0x00]; // 閫氱敤浣嶅浘鎸囦护
+    // 鍥剧墖瀹藉害/楂樺害锛堢ず渚�128x128锛屽疄闄呴渶鏍规嵁鍥剧墖璁$畻锛�
+    header.push(0x00, 0x80, 0x00, 0x80); 
+    return this.concatArrays(new Uint8Array(header), new Uint8Array(buffer));
+  }
+
+
+  // ========================== ZPL 鍗忚鎸囦护锛堟枒椹笓鐢級 ==========================
+  // 鏋勫缓ZPL鏂囨湰鎸囦护锛堝甫鍧愭爣瀹氫綅锛�
+  zplText(x, y, text, fontSize = 24) {
+    // ^FOx,y: 瀹氫綅鍧愭爣锛坸妯潗鏍囷紝y绾靛潗鏍囷級
+    // ^CF瀛椾綋: 瀛楀彿锛堥粯璁�24锛�
+    return `${this.zplBase.font}${fontSize}^FO${x},${y}^FD${text}^FS`;
+  }
+
+  // 鏋勫缓ZPL浜岀淮鐮佹寚浠わ紙甯﹀潗鏍囧畾浣嶏級
+  zplQrCode(x, y, content) {
+    // ^FOx,y: 浜岀淮鐮佸潗鏍�
+    // ^BQN,2,10: 浜岀淮鐮佺被鍨嬶紙QR Code锛�
+    // ^FDQA,content: QA鍓嶇紑=QR Code锛宑ontent=浜岀淮鐮佸唴瀹�
+    return `${this.zplBase.qrCode}^FO${x},${y}^FDQA,${content}^FS`;
+  }
+
+  // 鏂戦┈鍒囩焊鎸囦护锛圸PL锛�
+  zplCutPaper() {
+    // 鏂戦┈鎵撳嵃鏈洪�氳繃^PQ1锛堟墦鍗�1浠斤級+ ^XZ锛堢粨鏉燂級鑷姩鍒囩焊
+    return '^PQ1';
+  }
+
+
+  // ========================== 瀵瑰缁熶竴鎺ュ彛锛堣嚜鍔ㄩ�傞厤鍗忚锛� ==========================
+  // 1. 鍒濆鍖栨墦鍗版満锛堢粺涓�璋冪敤锛�
+  init() {
+    return this.model === 'zebra' 
+      ? this.textToUint8(this.zplBase.start + this.zplBase.utf8) // 鏂戦┈锛歓PL寮�濮�+UTF-8缂栫爜
+      : this.escPosInit(); // 鍏朵粬锛欵SC/POS鍒濆鍖�
+  }
+
+  // 2. 鍒囩焊锛堢粺涓�璋冪敤锛�
+  cutPaper(partial = true) {
+    if (this.model === 'zebra') {
+      // 鏂戦┈锛氳繑鍥瀂PL鍒囩焊鎸囦护杞琔int8Array
+      return this.textToUint8(this.zplCutPaper());
+    } else {
+      // 鍏朵粬锛欵SC/POS鍒囩焊
+      return this.escPosCutPaper(partial);
+    }
+  }
+
+  // 3. 鏋勫缓娴嬭瘯椤碉紙缁熶竴璋冪敤锛�
+  buildTestPage(data) {
+    if (this.model === 'zebra') {
+      // 鏂戦┈锛歓PL娴嬭瘯椤碉紙鍚腑鏂�+鏂囨湰锛�
+      const zpl = [
+        this.zplBase.start,
+        this.zplBase.utf8,
+        this.zplText(50, 50, '鏂戦┈鎵撳嵃鏈烘祴璇曢〉锛堜腑鏂囷級', 30),
+        this.zplText(50, 100, `娴嬭瘯鍐呭锛�${data.text}`, 24),
+        this.zplText(50, 150, `鎵撳嵃鏃堕棿锛�${new Date().toLocaleString()}`, 24),
+        this.zplCutPaper(),
+        this.zplBase.end
+      ].join('');
+      return this.zplToUint8(zpl);
+    } else {
+      // 鍏朵粬锛欵SC/POS娴嬭瘯椤碉紙鍘熸湁閫昏緫锛�
+      return this.concatArrays(
+        this.escPosInit(),
+        this.escPosSetFontSize(1),
+        this.escPosAlign.center,
+        this.textToUint8('娴嬭瘯鎵撳嵃椤礬n'),
+        this.escPosSetFontSize(0),
+        this.escPosAlign.left,
+        this.textToUint8(data.text + '\n'),
+        this.escPosNewLine(3),
+        this.escPosCutPaper()
+      );
+    }
+  }
+
+  // 4. 鏋勫缓鎴愬搧鍏ュ簱鏍囩锛堢粺涓�璋冪敤锛�
+  buildStockLabel(data) {
+    if (this.model === 'zebra') {
+      // 鏂戦┈锛歓PL鍏ュ簱鏍囩锛堝惈涓枃+浜岀淮鐮侊級
+      const qrContent = `鐗╂枡鍙�:${data.materialNo},鎵规:${data.batchNo},鏁伴噺:${data.quantity}`;
+      const zpl = [
+        this.zplBase.start,
+        this.zplBase.utf8,
+        // 鏍囬锛堝眳涓級
+        this.zplText(100, 30, '鎴愬搧鍏ュ簱鏍囩', 30),
+        // 鏍囩鍐呭锛堝乏瀵归綈锛屽潗鏍囦緷娆″悜涓嬶級
+        this.zplText(30, 80, `閿�鍞鍗曞彿: ${data.orderNo || '-'}`),
+        this.zplText(30, 120, `瀹㈡埛鍚嶇О: ${data.customer || '-'}`),
+        this.zplText(30, 160, `瀹㈡埛鍨嬪彿: ${data.model || '-'}`),
+        this.zplText(30, 200, `鐢熶骇鍒嗗巶: 浜斿垎鍘傝皟搴﹀憳`),
+        this.zplText(30, 240, `妫�楠岀姸鎬�: 鍚堟牸`),
+        // 閲嶇偣瀛楁锛堝姞绮楃敤澶у彿瀛椾綋锛�
+        this.zplText(30, 280, `鐗╂枡鍙�: ${data.materialNo}`, 28),
+        this.zplText(30, 320, `鐢熶骇鎵瑰彿: ${data.batchNo}`, 28),
+        // 琛ュ厖瀛楁
+        this.zplText(30, 360, `瑙勬牸鍨嬪彿: ${data.spec || '-'}`),
+        this.zplText(30, 400, `鏁伴噺: ${data.quantity || 0} 浠禶),
+        this.zplText(30, 440, `鏃ユ湡: ${data.date || new Date().toLocaleDateString()} 琛ㄩ潰: 鍚堟牸`),
+        // 浜岀淮鐮侊紙鍙充晶瀵归綈锛�
+        this.zplQrCode(250, 80, qrContent),
+        // 鍒囩焊+缁撴潫
+        this.zplCutPaper(),
+        this.zplBase.end
+      ].join('');
+      return this.zplToUint8(zpl);
+    } else {
+      // 鍏朵粬锛欵SC/POS鍏ュ簱鏍囩锛堝師鏈夐�昏緫锛�
+      return this.concatArrays(
+        this.escPosInit(),
+        this.escPosSetFontSize(2),
+        this.escPosAlign.center,
+        this.textToUint8('鎴愬搧鍏ュ簱鏍囩\n'),
+        this.escPosSetFontSize(0),
+        this.escPosNewLine(1),
+        this.escPosAlign.left,
+        this.textToUint8(`閿�鍞鍗曞彿: \n`),
+        this.textToUint8(`鐢熶骇璁㈠崟鍙�: ${data.orderNo}\n`),
+        this.textToUint8(`瀹㈡埛鍚嶇О: ${data.customer}\n`),
+        this.textToUint8(`瀹㈡埛鍨嬪彿: ${data.model}\n`),
+        this.textToUint8(`鐢熶骇鍒嗗巶: 浜斿垎鍘傝皟搴﹀憳\n`),
+        this.textToUint8(`妫�楠岀姸鎬�: \n`),
+        this.escPosBold(true),
+        this.textToUint8(`鐗╂枡鍙�: ${data.materialNo}\n`),
+        this.textToUint8(`鐢熶骇鎵瑰彿: ${data.batchNo}\n`),
+        this.escPosBold(false),
+        this.textToUint8(`瑙勬牸鍨嬪彿: ${data.spec}\n`),
+        this.textToUint8(`鏁伴噺: ${data.quantity}\n`),
+        this.textToUint8(`鏃ユ湡: ${data.date} 琛ㄩ潰: 鍚堟牸\n`),
+        this.escPosNewLine(1),
+        this.escPosAlign.center,
+        this.escPosPrintImage(data.qrBuffer),
+        this.escPosNewLine(3),
+        this.escPosCutPaper()
+      );
+    }
+  }
+
+  // 5. 鏋勫缓绉诲簱鍗曪紙缁熶竴璋冪敤锛�
+  buildTransferOrder(data) {
+    if (this.model === 'zebra') {
+      // 鏂戦┈锛歓PL绉诲簱鍗�
+      const qrContent = `绉诲簱鍗�:${data.orderNo},鐗╂枡:${data.materialNo},鏁伴噺:${data.quantity}`;
+      const zpl = [
+        this.zplBase.start,
+        this.zplBase.utf8,
+        this.zplText(120, 30, '绉诲簱鍗�', 30),
+        this.zplText(30, 80, `鐢熶骇璁㈠崟鍙�: ${data.orderNo || '-'}`),
+        this.zplText(30, 120, `浜у搧鍨嬪彿: ${data.productModel || '-'}`),
+        this.zplText(30, 160, `瀹㈡埛鍚嶇О: ${data.customer || '-'}`),
+        this.zplText(30, 200, `鐗╂枡鍙�: ${data.materialNo || '-'}`),
+        this.zplText(30, 240, `瀹㈡埛鍨嬪彿: ${data.customerModel || '-'}`),
+        this.zplText(30, 280, `鐢熶骇鎵瑰彿: ${data.batchNo || '-'}`),
+        this.zplText(30, 320, `鐢熶骇鍒嗗巶: ${data.factory || '-'}`),
+        this.zplText(30, 360, `鏁伴噺: ${data.quantity || 0} 浠禶, 28),
+        this.zplQrCode(250, 80, qrContent),
+        this.zplCutPaper(),
+        this.zplBase.end
+      ].join('');
+      return this.zplToUint8(zpl);
+    } else {
+      // 鍏朵粬锛欵SC/POS绉诲簱鍗曪紙鍘熸湁閫昏緫锛�
+      return this.concatArrays(
+        this.escPosInit(),
+        this.escPosSetFontSize(2),
+        this.escPosAlign.center,
+        this.textToUint8('绉诲簱鍗昞n'),
+        this.escPosSetFontSize(0),
+        this.escPosNewLine(1),
+        this.escPosAlign.left,
+        this.textToUint8(`鐢熶骇璁㈠崟鍙�: ${data.orderNo}\n`),
+        this.textToUint8(`浜у搧鍨嬪彿: ${data.productModel}\n`),
+        this.textToUint8(`瀹㈡埛鍚嶇О: ${data.customer}\n`),
+        this.textToUint8(`鐗╂枡鍙�: ${data.materialNo}\n`),
+        this.textToUint8(`瀹㈡埛鍨嬪彿: ${data.customerModel}\n`),
+        this.textToUint8(`鐢熶骇鎵瑰彿: ${data.batchNo}\n`),
+        this.textToUint8(`鐢熶骇鍒嗗巶: ${data.factory}\n`),
+        this.textToUint8(`鏁伴噺: ${data.quantity}\n`),
+        this.escPosNewLine(1),
+        this.escPosAlign.center,
+        this.escPosPrintImage(data.qrBuffer),
+        this.escPosNewLine(3),
+        this.escPosCutPaper()
+      );
+    }
+  }
+
+  // 6. 鏋勫缓妫�楠屽崟锛堢粺涓�璋冪敤锛�
+  buildInspectionForm(data, type) {
+    if (this.model === 'zebra') {
+      // 鏂戦┈锛歓PL妫�楠屽崟
+      const formTitle = type === 'inspectionA' ? '妫�楠屽崟A' : '妫�楠屽崟B';
+      const qrContent = `妫�楠屽崟:${data.formNo},鐗╂枡:${data.materialNo},鎵规:${data.batchNo}`;
+      // 鍔ㄦ�佺敓鎴愭楠岄」锛堟牴鎹甦ata.items锛�
+      let inspectionItems = '';
+      data.items.forEach((item, idx) => {
+        const yPos = 120 + idx * 40; // 姣忚妫�楠岄」鍚戜笅鍋忕Щ40
+        inspectionItems += this.zplText(30, yPos, `${item.name}: ${item.result}`);
+      });
+      const zpl = [
+        this.zplBase.start,
+        this.zplBase.utf8,
+        this.zplText(120, 30, formTitle, 30),
+        this.zplText(30, 80, `琛ㄥ崟缂栧彿: ${data.formNo || '-'}`),
+        inspectionItems, // 鍔ㄦ�佹楠岄」
+        this.zplText(30, 120 + data.items.length * 40 + 20, `妫�楠屽憳: ${data.inspector || '-'}`),
+        this.zplText(30, 120 + data.items.length * 40 + 60, `妫�楠屾棩鏈�: ${data.date || new Date().toLocaleDateString()}`),
+        this.zplQrCode(250, 80, qrContent),
+        this.zplCutPaper(),
+        this.zplBase.end
+      ].join('');
+      return this.zplToUint8(zpl);
+    } else {
+      // 鍏朵粬锛欵SC/POS妫�楠屽崟锛堝師鏈夐�昏緫锛�
+      let formContent = type === 'inspectionA' ? '妫�楠屽崟A\n' : '妫�楠屽崟B\n';
+      data.items.forEach(item => {
+        formContent += `${item.name}: ${item.result}\n`;
+      });
+      return this.concatArrays(
+        this.escPosInit(),
+        this.escPosSetFontSize(2),
+        this.escPosAlign.center,
+        this.textToUint8(formContent),
+        this.escPosSetFontSize(0),
+        this.escPosNewLine(1),
+        this.escPosAlign.left,
+        this.textToUint8(`琛ㄥ崟缂栧彿: ${data.formNo}\n`),
+        this.textToUint8(`鐗╂枡鍙�: ${data.materialNo}\n`),
+        this.textToUint8(`鐢熶骇鎵瑰彿: ${data.batchNo}\n`),
+        this.textToUint8(`妫�楠屽憳: ${data.inspector}\n`),
+        this.textToUint8(`妫�楠屾棩鏈�: ${data.date}\n`),
+        this.escPosNewLine(1),
+        this.escPosAlign.center,
+        this.escPosPrintImage(data.qrBuffer),
+        this.escPosNewLine(3),
+        this.escPosCutPaper()
+      );
+    }
+  }
+}
\ No newline at end of file
diff --git a/common/util/system.js b/common/util/system.js
new file mode 100644
index 0000000..1dab937
--- /dev/null
+++ b/common/util/system.js
@@ -0,0 +1,152 @@
+/**
+ * @file @/common/util/system.js
+ * @description UniApp 绯荤粺淇℃伅宸ュ叿绫伙細灏佽骞冲彴鍒ゆ柇銆佽澶囦俊鎭幏鍙栥�佸睆骞曢�傞厤绛夐�氱敤鑳藉姏
+ * @author 閫傞厤鍏ㄥ钩鍙帮紙APP/灏忕▼搴�/H5/蹇簲鐢ㄧ瓑锛�
+ */
+
+// 缂撳瓨绯荤粺淇℃伅锛堥伩鍏嶉噸澶嶈皟鐢� uni.getSystemInfoSync锛屾彁鍗囨�ц兘锛�
+let systemInfoCache = null;
+
+/**
+ * 1. 鏍稿績鏂规硶锛氳幏鍙栬澶囩郴缁熶俊鎭紙甯︾紦瀛橈級
+ * @returns {Object} 绯荤粺淇℃伅瀹屾暣瀵硅薄
+ * @property {string} platform - 杩愯骞冲彴锛坅ndroid/ios/mp-weixin/mp-alipay/h5/quickapp绛夛級
+ * @property {number} screenWidth - 灞忓箷瀹藉害锛坧x锛�
+ * @property {number} screenHeight - 灞忓箷楂樺害锛坧x锛�
+ * @property {number} statusBarHeight - 鐘舵�佹爮楂樺害锛坧x锛岀敤浜庡鑸爮閫傞厤锛�
+ * @property {string} system - 绯荤粺鐗堟湰锛堝 "Android 13"銆�"iOS 16.1"锛�
+ * @property {string} model - 璁惧鍨嬪彿锛堝 "iPhone 13"銆�"MI 12"锛�
+ */
+export function getSystemInfo() {
+  // 鑻ュ凡缂撳瓨锛岀洿鎺ヨ繑鍥�
+  if (systemInfoCache) return systemInfoCache;
+
+  try {
+    // 鍚屾鑾峰彇绯荤粺淇℃伅锛圲niApp 鍘熺敓 API锛屾敮鎸佸叏骞冲彴锛�
+    systemInfoCache = uni.getSystemInfoSync();
+    return systemInfoCache;
+  } catch (error) {
+    console.error('鑾峰彇绯荤粺淇℃伅澶辫触:', error);
+    // 寮傚父鏃惰繑鍥為粯璁ゅ�硷紝閬垮厤涓氬姟宕╂簝
+    return {
+      platform: 'unknown',
+      screenWidth: 375,
+      screenHeight: 667,
+      statusBarHeight: 20,
+      system: 'Unknown',
+      model: 'Unknown Device'
+    };
+  }
+}
+
+/**
+ * 2. 骞冲彴鍒ゆ柇锛氭槸鍚︿负 APP 绔紙瀹夊崜/iOS锛�
+ * @returns {boolean} true=APP绔紝false=鍏朵粬骞冲彴
+ */
+export function isApp() {
+  const { platform } = getSystemInfo();
+  return platform === 'android' || platform === 'ios';
+}
+
+/**
+ * 3. 骞冲彴鍒ゆ柇锛氭槸鍚︿负灏忕▼搴忕锛堟敮鎸佸井淇�/鏀粯瀹�/鐧惧害/瀛楄妭绛夛級
+ * @param {string} [specificMiniType] 鍙�夛細鎸囧畾灏忕▼搴忕被鍨嬶紙濡� "mp-weixin" 浠呭垽鏂井淇″皬绋嬪簭锛�
+ * @returns {boolean} true=灏忕▼搴忕锛宖alse=鍏朵粬骞冲彴
+ * @example isMini() 鈫� 鍒ゆ柇鎵�鏈夊皬绋嬪簭锛沬sMini('mp-alipay') 鈫� 浠呭垽鏂敮浠樺疂灏忕▼搴�
+ */
+export function isMini(specificMiniType = '') {
+  const { platform } = getSystemInfo();
+  // 灏忕▼搴忓钩鍙版爣璇嗗潎浠� "mp-" 寮�澶达紙濡� mp-weixin/mp-alipay/mp-baidu锛�
+  const isMiniPlatform = platform.startsWith('mp-');
+  
+  // 鑻ユ寚瀹氫簡鍏蜂綋灏忕▼搴忕被鍨嬶紙濡備粎鍒ゆ柇寰俊锛夛紝鍒欒繘涓�姝ュ尮閰�
+  if (specificMiniType) {
+    return isMiniPlatform && platform === specificMiniType;
+  }
+  
+  return isMiniPlatform;
+}
+
+/**
+ * 4. 骞冲彴鍒ゆ柇锛氭槸鍚︿负 H5 绔紙娴忚鍣級
+ * @returns {boolean} true=H5绔紝false=鍏朵粬骞冲彴
+ */
+export function isH5() {
+  const { platform } = getSystemInfo();
+  return platform === 'h5';
+}
+
+/**
+ * 5. 骞冲彴鍒ゆ柇锛氭槸鍚︿负蹇簲鐢ㄧ
+ * @returns {boolean} true=蹇簲鐢ㄧ锛宖alse=鍏朵粬骞冲彴
+ */
+export function isQuickApp() {
+  const { platform } = getSystemInfo();
+  return platform === 'quickapp';
+}
+
+/**
+ * 6. 璁惧鍒ゆ柇锛氭槸鍚︿负 iOS 璁惧锛堜粎 APP 绔湁鏁堬級
+ * @returns {boolean} true=iOS璁惧锛宖alse=瀹夊崜鎴栧叾浠栧钩鍙�
+ */
+export function isIOS() {
+  const { platform } = getSystemInfo();
+  return platform === 'ios';
+}
+
+/**
+ * 7. 璁惧鍒ゆ柇锛氭槸鍚︿负瀹夊崜璁惧锛堜粎 APP 绔湁鏁堬級
+ * @returns {boolean} true=瀹夊崜璁惧锛宖alse=iOS鎴栧叾浠栧钩鍙�
+ */
+export function isAndroid() {
+  const { platform } = getSystemInfo();
+  return platform === 'android';
+}
+
+/**
+ * 8. 灞忓箷閫傞厤锛氳幏鍙栧鑸爮楂樺害锛堢姸鎬佹爮 + 瀵艰埅鏍忓唴瀹瑰尯锛岀敤浜庤嚜瀹氫箟瀵艰埅鏍忥級
+ * @returns {number} 瀵艰埅鏍忔�婚珮搴︼紙px锛�
+ */
+export function getNavBarHeight() {
+  const { statusBarHeight, platform } = getSystemInfo();
+  // 閫傞厤瑙勫垯锛歩OS 瀵艰埅鏍忓唴瀹瑰尯楂樺害 44px锛屽畨鍗� 48px锛圲niApp 閫氱敤鏍囧噯锛�
+  const navContentHeight = platform === 'ios' ? 44 : 48;
+  return statusBarHeight + navContentHeight;
+}
+
+/**
+ * 9. 灞忓箷閫傞厤锛歱x 杞� rpx锛圲niApp 鏍峰紡閫傞厤锛�750rpx = 灞忓箷瀹藉害锛�
+ * @param {number} px - 璁捐绋夸腑鐨� px 鍊硷紙鍩轰簬 750px 瀹藉害璁捐绋匡級
+ * @returns {number} 杞崲鍚庣殑 rpx 鍊�
+ */
+export function px2rpx(px) {
+  const { screenWidth } = getSystemInfo();
+  // 鍏紡锛歳px = px * (750 / 灞忓箷瀹藉害)
+  return Math.floor(px * (750 / screenWidth));
+}
+
+/**
+ * 10. 灞忓箷閫傞厤锛歳px 杞� px锛堢敤浜庡姩鎬佽绠楀厓绱犲昂瀵革級
+ * @param {number} rpx - 鏍峰紡涓殑 rpx 鍊�
+ * @returns {number} 杞崲鍚庣殑 px 鍊�
+ */
+export function rpx2px(rpx) {
+  const { screenWidth } = getSystemInfo();
+  // 鍏紡锛歱x = rpx * (灞忓箷瀹藉害 / 750)
+  return Math.floor(rpx * (screenWidth / 750));
+}
+
+/**
+ * 11. 鑾峰彇璁惧鍞竴鏍囪瘑锛堟敞鎰忥細閮ㄥ垎骞冲彴鏈夐殣绉侀檺鍒讹級
+ * @returns {string} 璁惧鏍囪瘑锛堝け璐ユ椂杩斿洖绌哄瓧绗︿覆锛�
+ */
+export function getDeviceId() {
+  try {
+    const { deviceId } = getSystemInfo();
+    // 閮ㄥ垎骞冲彴锛堝 iOS 14+锛夊彲鑳借繑鍥炵┖锛岄渶鍏煎
+    return deviceId || '';
+  } catch (error) {
+    console.error('鑾峰彇璁惧ID澶辫触:', error);
+    return '';
+  }
+}
\ No newline at end of file
diff --git a/components/mes/pdaScan.vue b/components/mes/pdaScan.vue
new file mode 100644
index 0000000..2263041
--- /dev/null
+++ b/components/mes/pdaScan.vue
@@ -0,0 +1,79 @@
+<template>  
+    <view class="content"></view>  
+</template>  
+
+<script>  
+var main,receiver,filter;    
+var _codeQueryTag = false;    
+export default {  
+	name:"pdaScan",
+    data() {  
+        return {  
+            scanCode: ''  
+        }  
+    },  
+    created: function (option) {  
+        // #ifdef APP-PLUS
+        if (typeof plus !== 'undefined') {
+            this.initScan()  
+            this.startScan();    
+        }
+        // #endif
+    },    
+    onHide:function(){    
+        // #ifdef APP-PLUS
+        if (typeof plus !== 'undefined') {
+            this.stopScan();    
+        }
+        // #endif
+    },  
+    destroyed:function(){    
+        /*椤甸潰閫�鍑烘椂涓�瀹氳鍗歌浇鐩戝惉,鍚﹀垯涓嬫杩涙潵鏃朵細閲嶅锛岄�犳垚鎵竴娆″嚭2涓互涓婄殑缁撴灉*/    
+        // #ifdef APP-PLUS
+        if (typeof plus !== 'undefined') {
+            this.stopScan();    
+        }
+        // #endif
+    },    
+    methods: {  
+        initScan() {  
+            let _this = this;  
+            main = plus.android.runtimeMainActivity();//鑾峰彇activity  
+            var IntentFilter = plus.android.importClass('android.content.IntentFilter');   
+            filter = new IntentFilter();    
+            filter.addAction("android.intent.ACTION_DECODE_DATA"); // 鎹綘鐨勫箍鎾姩浣�  
+            receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver',{  
+            onReceive : function(context, intent) {  
+                plus.android.importClass(intent);     
+                let code = intent.getStringExtra("barcode_string");// 鎹綘鐨勫箍鎾爣绛�  
+                _this.queryCode(code);    
+            }});    
+        },    
+        startScan(){    
+            main.registerReceiver(receiver,filter);  
+        },    
+        stopScan(){  
+            main.unregisterReceiver(receiver);    
+        },    
+        queryCode: function(code){  
+            //闃查噸澶�  
+            if(_codeQueryTag)return false;    
+            _codeQueryTag = true;    
+            setTimeout(function(){    
+                _codeQueryTag = false;    
+            },150);  
+            var id = code  
+            uni.$emit('scancodedate',{code:id})  
+        }  
+    }  
+}  
+</script>  
+
+<style>  
+    page {  
+        background-color: #efeff4;  
+    }  
+    .content {  
+        text-align: center;  
+    }  
+</style>
\ No newline at end of file
diff --git a/components/ren-dropdown-filter/ren-dropdown-filter.vue b/components/ren-dropdown-filter/ren-dropdown-filter.vue
new file mode 100644
index 0000000..621f983
--- /dev/null
+++ b/components/ren-dropdown-filter/ren-dropdown-filter.vue
@@ -0,0 +1,244 @@
+<template>
+    <view class="filter-wrapper" :style="{ height: height + 'rpx', top: top,'border-top':border?'1rpx solid #f2f2f2':'none' }" @touchmove.stop.prevent="discard">
+        <view class="inner-wrapper">
+            <view class="mask" :class="showMask ? 'show' : 'hide'" @tap="tapMask"></view>
+            <view class="navs">
+                <view class="c-flex-align" :class="{ 'c-flex-center': index > 0, actNav: index === actNav }" v-for="(item, index) in navData" :key="index" @click="navClick(index)">
+                    <view v-for="(child, childx) in item" :key="childx" v-if="child.select">{{ child.text }}</view>
+                    <image src="https://i.loli.net/2020/07/15/QsHxlr1gbSImvWt.png" mode="" class="icon-triangle" v-if="index === actNav"></image>
+                    <image src="https://i.loli.net/2020/07/15/xjVSvzWcH9NO7al.png" mode="" class="icon-triangle" v-else></image>
+                </view>
+
+                <view class="date-wrapper">
+                    <picker mode="date" @change="handleDate">
+                        <view class="date c-flex-align" :style="{ height: height + 'rpx' }" @click="dateClick">
+                            <view>{{ selDate }}</view>
+                            <image src="https://i.loli.net/2020/07/15/xjVSvzWcH9NO7al.png" mode="" class="icon-triangle"></image>
+                        </view>
+                    </picker>
+                </view>
+            </view>
+            <scroll-view scroll-y="true" class="popup" :class="popupShow ? 'popupShow' : ''">
+                <view class="item-opt c-flex-align" :class="item.select ? 'actOpt' : ''" v-for="(item, index) in navData[actNav]" :key="index" @click="handleOpt(index)">
+                    {{ item.text }}
+                </view>
+            </scroll-view>
+        </view>
+    </view>
+</template>
+
+<script>
+// import { getCurDateTime } from '@/libs/utils.js';
+export default {
+    props: {
+        height: {
+            type: Number,
+            default: 108
+        },
+        top: {
+            type: String,
+            default: 'calc(var(--window-statsu-bar) + 44px)'
+        },
+        border: {
+            type: Boolean,
+            default: false
+        },
+        filterData: {
+            //蹇呭~
+            type: Array,
+            default: () => {
+                return [];
+            }
+            // default: () => {
+            //     return [
+            //         [{ text: '鍏ㄩ儴鐘舵��', value: '' }, { text: '鐘舵��1', value: 1 }, { text: '鐘舵��2', value: 2 }, { text: '鐘舵��3', value: 3 }],
+            //         [{ text: '鍏ㄩ儴绫诲瀷', value: '' }, { text: '绫诲瀷1', value: 1 }, { text: '绫诲瀷2', value: 2 }, { text: '绫诲瀷3', value: 3 }]
+            //     ];
+            // }
+        },
+        defaultIndex: {
+            //榛樿閫変腑鏉′欢绱㈠紩,瓒呭嚭涓�绫绘椂蹇呭~
+            type: Array,
+            default: () => {
+                return [0];
+            }
+        }
+    },
+    data() {
+        return {
+            navData: [],
+            popupShow: false,
+            showMask: false,
+            actNav: null,
+            selDate: '閫夋嫨鏃ユ湡',
+            selIndex: [] //閫変腑鏉′欢绱㈠紩
+        };
+    },
+    created() {
+        this.navData = this.filterData;
+        this.selIndex = this.defaultIndex;
+        this.keepStatus();
+    },
+    mounted() {
+        // this.selDate = getCurDateTime().formatDate;
+    },
+    methods: {
+        keepStatus() {
+            this.navData.forEach(itemnavData => {
+                itemnavData.map(child => {
+                    child.select = false;
+                });
+                return itemnavData;
+            });
+            for (let i = 0; i < this.selIndex.length; i++) {
+                let selindex = this.selIndex[i];
+                this.navData[i][selindex].select = true;
+            }
+        },
+        navClick(index) {
+            if (index === this.actNav) {
+                this.tapMask();
+                return;
+            }
+            this.popupShow = true;
+            this.showMask = true;
+            this.actNav = index;
+        },
+        handleOpt(index) {
+            this.selIndex[this.actNav] = index;
+            this.keepStatus();
+            setTimeout(() => {
+                this.tapMask();
+            }, 100);
+            let data = [];
+            let res = this.navData.forEach(item => {
+                let sel = item.filter(child => child.select);
+                data.push(sel);
+            });
+            console.log(data);
+            this.$emit('onSelected', data);
+        },
+        dateClick() {
+            this.tapMask();
+        },
+        tapMask() {
+            this.showMask = false;
+            this.popupShow = false;
+            this.actNav = null;
+        },
+        handleDate(e) {
+            let d = e.detail.value;
+            this.selDate = d;
+            this.$emit('dateChange', d);
+        },
+        discard() {}
+    }
+};
+</script>
+
+<style lang="scss" scoped>
+page {
+    font-size: 28rpx;
+}
+.c-flex-align {
+    display: flex;
+    align-items: center;
+}
+.c-flex-center {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+}
+.filter-wrapper {
+    position: fixed;
+    left: 0;
+    width: 750rpx;
+    z-index: 999;
+    .inner-wrapper {
+        // position: relative;
+        .navs {
+            position: relative;
+            height: 110rpx;
+            padding: 0 40rpx;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            background-color: #fff;
+            border-bottom: 2rpx solid #f5f6f9;
+            color: #8b9aae;
+            z-index: 999;
+            box-sizing: border-box;
+            & > view {
+                flex: 1;
+                height: 100%;
+                flex-direction: row;
+                z-index: 999;
+            }
+            .date {
+                justify-content: flex-end;
+            }
+            .actNav {
+                color: #4d7df9;
+                font-weight: bold;
+            }
+        }
+        .mask {
+            z-index: 666;
+            position: fixed;
+            top: calc(var(--status-bar-height) + 44px);
+            left: 0;
+            right: 0;
+            bottom: 0;
+            background-color: rgba(0, 0, 0, 0);
+            transition: background-color 0.15s linear;
+            &.show {
+                background-color: rgba(0, 0, 0, 0.4);
+            }
+            &.hide {
+                display: none;
+            }
+        }
+        .popup {
+            position: relative;
+            max-height: 500rpx;
+            background-color: #fff;
+            border-bottom-left-radius: 20rpx;
+            border-bottom-right-radius: 20rpx;
+            overflow: scroll;
+            z-index: 999;
+            transition: all 1s linear;
+            opacity: 0;
+            display: none;
+            .item-opt {
+                height: 100rpx;
+                padding: 0 40rpx;
+                color: #8b9aae;
+                border-bottom: 2rpx solid #f5f6f9;
+            }
+            .actOpt {
+                color: #4d7df9;
+                font-weight: bold;
+                position: relative;
+                &::after {
+                    content: '鉁�';
+                    font-weight: bold;
+                    font-size: 36rpx;
+                    position: absolute;
+                    right: 40rpx;
+                }
+            }
+        }
+        .popupShow {
+            display: block;
+            opacity: 1;
+        }
+    }
+
+    .icon-triangle {
+        width: 16rpx;
+        height: 16rpx;
+        margin-left: 10rpx;
+    }
+}
+</style>
diff --git a/pages/eam/andon/andonAction/andonAction.vue b/pages/eam/andon/andonAction/andonAction.vue
new file mode 100644
index 0000000..aaa9706
--- /dev/null
+++ b/pages/eam/andon/andonAction/andonAction.vue
@@ -0,0 +1,286 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">寮傚父濉姤</block>
+		</cu-custom>
+		<view class="container">
+
+
+			<uni-forms ref="form" :modelValue="formData" validate-trigger="bind" err-show-type="undertext">
+				<uni-group top="1">
+
+
+					<uni-forms-item :label-width="100" name="andonAlertMessage" label="瀹夌伅鎻忚堪:">
+						<uni-easyinput type="textarea" v-model="formData.andonAlertMessage" />
+					</uni-forms-item>
+
+					<uni-forms-item :label-width="100" name="outNum" label="瀹夌伅鍥剧墖:">
+						<uni-file-picker limit="9" :value="fileList" :image-styles="imageStyles" @select="select"
+							:sourceType="sourceType" @progress="progress" @success="success" @fail="fail"
+							@delete="deletea" :readonly="readonly" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="andonhandle" label="澶勭悊鏂瑰紡鎻忚堪:">
+						<uni-easyinput type="textarea" v-model="formData.andonhandle" />
+					</uni-forms-item>
+				</uni-group>
+			</uni-forms>
+
+
+			<view v-show="isSHowBtn" class="padding flex flex-direction">
+				<view class="flex-sub bg-blue padding-sm margin-xl radius text-sm text-center text-white"
+					@click.stop="ProductionTask()" hover-class="is-hover">纭畾</view>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	import configService from "@/common/service/config.service";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				// 鍥剧墖鍥炴樉
+				fileLists: [],
+				// 涓婁紶鍥剧墖鐨勬牱寮�
+				imageStyles: {
+					width: 90,
+					height: 90,
+				},
+				sourceType: ['album', 'camera'],
+				ipAndPort: configService.staticURL,
+				scrollLeft: 0,
+				uploadUrl: "/sys/common/upload",
+				formData: {
+					andonAlertMessage: '',
+					andonhandle: '',
+					avatar: []
+				},
+
+
+				NavBarColor: this.NavBarColor,
+				url: {
+					upload: "/eam/sysFiles/batch_upload",
+					stallList: "/eam/eamRepairOrder/queryById",
+					getEquipmentList: 'eam/equipment/list',
+					approval: '/eam/eamRepairOrder/perform'
+				},
+
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				msg1Count: 0,
+				msg2Count: 0,
+				msg1Title: ""
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 160
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+		onLoad(options) {
+			const annItem = JSON.parse(decodeURIComponent(options.item));
+		},
+		created() {
+
+
+		},
+
+		methods: {
+			select(e) {
+				const tempFilePaths = e.tempFilePaths;
+				uni.showLoading({
+					title: '涓婁紶涓�...'
+				});
+				const uploadPromises = tempFilePaths.map((filePath, index) => {
+					return new Promise((resolve, reject) => {
+						this.$http.upload(this.url.upload, {
+								filePath: filePath,
+								name: 'file'
+							})
+							.then(uploadRes => {
+								// 鍋囪鏈嶅姟鍣ㄨ繑鍥炵殑缁撴灉涓寘鍚枃浠惰矾寰�
+								const serverFilePath = uploadRes.data.result[0];
+								this.formData.avatar.push(serverFilePath);
+								resolve(uploadRes); // 杩斿洖缁撴灉缁� Promise.all
+							})
+							.catch(err => {
+								console.error(`鍥剧墖 ${index + 1} 涓婁紶澶辫触:`, err);
+								reject(err);
+							});
+					});
+				});
+
+				Promise.all(uploadPromises)
+					.then(() => {
+						uni.hideLoading();
+						uni.showToast({
+							title: '鍏ㄩ儴涓婁紶鎴愬姛'
+						});
+					})
+					.catch(err => {
+						uni.hideLoading();
+						uni.showToast({
+							title: '閮ㄥ垎涓婁紶澶辫触',
+							icon: 'none'
+						});
+						console.error('涓婁紶寮傚父:', err);
+					});
+			},
+			// 鍒犻櫎
+			deletea(e) {
+				console.log('鍒犻櫎鍥剧墖', e);
+			},
+			ProductionTask() {
+
+				uni.showLoading({
+					mask: true,
+					title: "鍔犺浇涓�....",
+				})
+				this.$http.post(this.url.approval, {
+					sparePartDescription: this.ScanData.sparePartDescription,
+					dataId: this.id,
+					equipmentId: this.formData.num,
+					faultReason: this.formData.faultReason,
+					id: this.id,
+					imageFilesResult: this.formData.avatar,
+					instanceId: this.procInstId,
+					isUseSpare: this.formData.isSpare,
+					repairDescription: this.formData.repairDescription,
+					taskId: this.taskId
+				}).then(res => {
+					uni.hideLoading()
+					if (res.data.success) {
+						uni.showToast({
+							icon: "success",
+							title: '鎻愪氦鎴愬姛',
+							duration: 2000
+						});
+						this.$Router.replaceAll({
+							name: 'ToDoList'
+						})
+					} else {
+
+						uni.showModal({
+							title: "鎻愮ず",
+							content: res.data.message,
+							confirmText: '纭畾',
+							showCancel: false,
+						})
+					}
+				}).catch(() => {
+					this.$tip.loaded();
+					uni.showToast({
+						icon: "error",
+						title: res.data.message,
+						duration: 2000
+					});
+				});
+			},
+
+			changeEquipmentList(e) {
+				this.formData.num = e;
+			},
+
+
+
+
+
+
+			upCallback() {
+				this.$http.get(this.url.stallList, {
+					params: {
+						id: this.id
+					},
+
+				}).then(res => {
+					this.announcement1 = res.data.result
+					console.log("url", res.data.result.reportStatus)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						// if (this.announcement1.imageFiles) {
+						// 	try {
+						// 		const parsedDataIn = JSON.parse(this.announcement1.imageFiles);
+						// 		this.imageAvatarTwo = parsedDataIn;
+						// 		this.imgTwoList = parsedDataIn.map(imageObj => {
+						// 			return `${this.ipAndPort}${imageObj.filePath}`;
+						// 		});
+
+						// 		this.fileLists = this.imgTwoList.map(url => ({
+						// 			url: url,
+						// 			extname: 'png',
+						// 			name: 'eam'
+						// 		}));
+						// 	} catch (error) {
+						// 		console.error('JSON 瑙f瀽澶辫触:', error);
+						// 		this.imageAvatarTwo = [];
+						// 		this.imgTwoList = [];
+						// 		this.fileLists = [];
+						// 	}
+						// }
+					}
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+				})
+			},
+		},
+
+	}
+</script>
+
+<style>
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+
+	.divider {
+		display: flex;
+		align-items: center;
+		text-align: center;
+		color: gray;
+		/* 鏂囧瓧棰滆壊 */
+		margin: 20px 0;
+		/* 涓婁笅闂磋窛 */
+	}
+
+	.divider::before,
+	.divider::after {
+		content: '';
+		flex: 1;
+		border-bottom: 1px solid gray;
+		/* 妯嚎棰滆壊 */
+		margin: 0 16px;
+		/* 妯嚎涓庢枃瀛椾箣闂寸殑闂磋窛 */
+	}
+
+	.divider text {
+		white-space: nowrap;
+		/* 闃叉鏂囧瓧鎹㈣ */
+	}
+
+	.content {
+		margin-top: 5px;
+	}
+
+	.content scroll-view {
+		scrollIndicator: "none"
+	}
+
+	.popupView {
+		margin-top: 45px;
+		height: auto;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/andon/andonAdd/andonAdd.vue b/pages/eam/andon/andonAdd/andonAdd.vue
new file mode 100644
index 0000000..f4ca109
--- /dev/null
+++ b/pages/eam/andon/andonAdd/andonAdd.vue
@@ -0,0 +1,359 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">瀹夌伅澶勭悊</block>
+		</cu-custom>
+
+		<uni-forms ref="form" :modelValue="formData" :rules="rules" validate-trigger="submit" err-show-type="undertext">
+			<uni-group top="10">
+				<uni-forms-item name="factoryId" label="浜х嚎:" :label-width="100" :required="true">
+					<uni-data-select :localdata="formData.msListCategory" popup-title="璇烽�夋嫨" @change="changeLine"
+						:disabled="true" :clear="false" v-model="formData.factoryId">
+					</uni-data-select>
+				</uni-forms-item>
+
+				<uni-forms-item name="buttonId" label="瀹夌伅绫诲瀷:" :label-width="100">
+					<uni-data-select :localdata="formData.handleList" popup-title="璇烽�夋嫨" :disabled="true"
+						@change="changehnadle" :clear="false" v-model="formData.buttonId">
+					</uni-data-select>
+				</uni-forms-item>
+
+				<uni-forms-item name="andonTime" :label-width="100" label="瀹夌伅鏃堕棿:">
+					<uni-datetime-picker type="datetime" :disabled="true" v-model="formData.andonTime" />
+				</uni-forms-item>
+
+				<uni-forms-item name="andonLevel" :label-width="100" label="瀹夌伅绛夌骇:">
+					<uni-data-select :localdata="formData.andonLevel" popup-title="璇烽�夋嫨" @change="changeLevel"
+						:clear="false" :disabled="true" v-model="formData.andonLevelValue">
+					</uni-data-select>
+				</uni-forms-item>
+
+				<uni-forms-item name="orderStatus" :label-width="100" label="瀹夌伅鐘舵��:">
+					<uni-data-select :localdata="formData.andonStatus" popup-title="璇烽�夋嫨" @change="changeStatus"
+						:disabled="true" :clear="false" v-model="formData.orderStatus">
+					</uni-data-select>
+				</uni-forms-item>
+				<uni-forms-item name="num" :label-width="100" label="瀹夌伅鍙戣捣浜�:">
+					<uni-easyinput v-model="formData.operator" :disabled="true" />
+				</uni-forms-item>
+				<uni-forms-item name="num" :label-width="100" label="澶勭悊浜�:">
+					<uni-easyinput v-model="formData.realname" :disabled="true" />
+				</uni-forms-item>
+				<uni-forms-item name="num" :label-width="100" label="鍝嶅簲浜�:">
+					<uni-easyinput v-model="formData.realname" :disabled="true" />
+				</uni-forms-item>
+				<uni-forms-item name="problemDescreption" :label-width="100" label="闂鎻忚堪:">
+					<uni-easyinput type="textarea" placeholder="璇疯緭鍏ラ棶棰樻弿杩�" v-model="formData.problemDescreption"
+						:maxlength="500" />
+				</uni-forms-item>
+
+				<uni-forms-item name="resolutionDescreption" :label-width="100" label="澶勭悊缁撴灉鎻忚堪:">
+					<uni-easyinput type="textarea" placeholder="璇疯緭鍏ュ鐞嗙粨鏋滄弿杩�" v-model="formData.resolutionDescreption"
+						:maxlength="500" />
+				</uni-forms-item>
+			</uni-group>
+		</uni-forms>
+
+		<button class="margin-bottom" type="primary" @click="submitForm">纭畾</button>
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+
+	export default {
+		mixins: [MescrollMixin],
+		data() {
+			return {
+				NavBarColor: this.NavBarColor,
+				url: {
+					add: "andonorder/andonOrder/AndonHandel",
+					andonLevel: "sys/dict/getDictItems/andon_level",
+					andonStatus: "sys/dict/getDictItems/order_status",
+					andonType: 'sys/dict/getDictItems/andon_button_config,button_name,id',
+					andonCategory: "base/factory/queryUserProductionLineList"
+				},
+
+				formData: {
+					operator:'',
+					orderIds: '',
+					handleList: [],
+					msListCategory: [],
+					andonLevel: [],
+					andonStatus: [],
+					problemDescreption: '',
+					resolutionDescreption: '',
+					andonTime: Date.now(),
+					factoryId: '',
+					buttonId: '',
+					andonLevelValue: '',
+					orderStatus: '',
+					realname: '',
+					userId: ''
+				},
+
+				receivedItem: {},
+				currentLineId: '',
+				// 琛ㄥ崟楠岃瘉瑙勫垯
+				rules: {
+					factoryId: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨浜х嚎'
+						}]
+					},
+					buttonId: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨瀹夌伅绫诲瀷'
+						}]
+					},
+					andonTime: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨瀹夌伅鏃堕棿'
+						}]
+					},
+					andonLevelValue: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨瀹夌伅绛夌骇'
+						}]
+					},
+					orderStatus: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨瀹夌伅鐘舵��'
+						}]
+					}
+				}
+			}
+		},
+		onLoad(options) {
+			// 鎺ユ敹 item 鍙傛暟锛堥渶瑕佽В鐮佸苟杞崲鍥炲璞★級
+			if (options.item) {
+				// 鍏堣В鐮佸啀杞垚瀵硅薄
+				this.receivedItem = JSON.parse(decodeURIComponent(options.item));
+
+			}
+			
+			this.formData.orderIds = this.receivedItem.id;
+			this.formData.factoryId = options.currentLineId;
+			this.formData.orderStatus = this.receivedItem.orderStatus;
+			this.formData.operator=this.receivedItem.operatorName;
+			this.formData.andonLevelValue = this.receivedItem.andonLevel;
+			this.formData.realname = this.receivedItem.responder;
+			this.formData.buttonId = this.receivedItem.buttonId;
+			console.log('鎺ユ敹鐨刬tem鍙傛暟锛�', this.receivedItem);
+
+		},
+		created() {
+			this.loadData();
+		},
+
+		methods: {
+			serialNumScan() {
+				uni.navigateTo({
+					url: "/pages/selectUsers/selectUsers"
+				})
+			},
+			// 鍔犺浇鎵�鏈変笅鎷夊垪琛ㄦ暟鎹�
+			loadData() {
+				// 骞惰鍔犺浇澶氫釜鎺ュ彛锛屼紭鍖栨�ц兘
+				Promise.all([
+					this.andonCategory(),
+					this.andonType(),
+					this.andonLevel(),
+					this.andonStatus()
+				]).then(() => {
+					console.log('鎵�鏈夋暟鎹姞杞藉畬鎴�');
+				}).catch(() => {
+					uni.showToast({
+						title: '鏁版嵁鍔犺浇澶辫触',
+						icon: 'none'
+					});
+				});
+			},
+
+
+			// 浜х嚎鍙樻洿
+			changeLine(e) {
+				this.formData.factoryId = e;
+			},
+
+			// 瀹夌伅绫诲瀷鍙樻洿
+			changehnadle(e) {
+				this.formData.buttonId = e;
+			},
+
+			// 瀹夌伅绛夌骇鍙樻洿
+			changeLevel(e) {
+				this.formData.andonLevelValue = e;
+			},
+
+			// 瀹夌伅鐘舵�佸彉鏇�
+			changeStatus(e) {
+				this.formData.orderStatus = e;
+			},
+
+			// 鑾峰彇浜х嚎鍒楄〃
+			andonCategory() {
+				return new Promise((resolve, reject) => {
+					this.$http.get(this.url.andonCategory).then(res => {
+						if (res.data.success) {
+							this.formData.msListCategory = res.data.result;
+							resolve();
+						} else {
+							reject();
+						}
+					}).catch(() => {
+						uni.showToast({
+							title: '浜х嚎鏁版嵁鍔犺浇澶辫触',
+							icon: 'none'
+						});
+						reject();
+					});
+				});
+			},
+
+			// 鑾峰彇瀹夌伅绫诲瀷鍒楄〃
+			andonType() {
+				return new Promise((resolve, reject) => {
+					this.$http.get(this.url.andonType).then(res => {
+						if (res.data.success) {
+							this.formData.handleList = res.data.result;
+							resolve();
+						} else {
+							reject();
+						}
+					}).catch(() => {
+						uni.showToast({
+							title: '瀹夌伅绫诲瀷鍔犺浇澶辫触',
+							icon: 'none'
+						});
+						reject();
+					});
+				});
+			},
+
+			// 鑾峰彇瀹夌伅绛夌骇鍒楄〃
+			andonLevel() {
+				return new Promise((resolve, reject) => {
+					this.$http.get(this.url.andonLevel).then(res => {
+						if (res.data.success) {
+							this.formData.andonLevel = res.data.result;
+							resolve();
+						} else {
+							reject();
+						}
+					}).catch(() => {
+						uni.showToast({
+							title: '瀹夌伅绛夌骇鍔犺浇澶辫触',
+							icon: 'none'
+						});
+						reject();
+					});
+				});
+			},
+
+			// 鑾峰彇瀹夌伅鐘舵�佸垪琛�
+			andonStatus() {
+				return new Promise((resolve, reject) => {
+					this.$http.get(this.url.andonStatus).then(res => {
+						if (res.data.success) {
+							this.formData.andonStatus = res.data.result;
+							resolve();
+						} else {
+							reject();
+						}
+					}).catch(() => {
+						uni.showToast({
+							title: '瀹夌伅鐘舵�佸姞杞藉け璐�',
+							icon: 'none'
+						});
+						reject();
+					});
+				});
+			},
+
+			// 琛ㄥ崟鎻愪氦
+			submitForm() {
+				this.AddLoadMaterial();
+
+			},
+
+			// 鎻愪氦瀹夌伅宸ュ崟
+			AddLoadMaterial() {
+				/**
+				 * 瀹夌伅浜�- 鍙戣捣浜�
+				 */
+				// 鏄剧ず鍔犺浇涓�
+				uni.showLoading({
+					title: '鎻愪氦涓�...'
+				});
+				this.$http.post(this.url.add, {
+					andonLevel: this.formData.andonLevelValue,
+					buttonId: this.formData.buttonId,
+					factoryId: this.formData.factoryId,
+					id: this.formData.orderIds,
+					operateTime: this.formData.andonTime,
+					operator:this.formData.operator,
+					responder: this.formData.realname,
+					processor: this.formData.realname,
+					orderStatus: this.formData.orderStatus,
+					problemDescreption: this.formData.problemDescreption,
+					resolutionDescreption: this.formData.resolutionDescreption
+				}).then(res => {
+					uni.hideLoading();
+
+					if (res.data.success) {
+						uni.showModal({
+							title: '鎴愬姛',
+							content: res.data.message || '澶勭悊鎴愬姛',
+							showCancel: false,
+							success: () => {
+								uni.reLaunch({
+									url:'/pages/eam/andon/andonCall/andonCall'
+								})
+							}
+						});
+					} else {
+						uni.showModal({
+							title: '鎻愮ず',
+							content: res.data.message || '鎻愪氦澶辫触锛岃閲嶈瘯',
+							showCancel: false
+						});
+					}
+				}).catch(() => {
+					uni.hideLoading();
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				});
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.container {
+		background-color: #f5f5f5;
+		min-height: 100vh;
+	}
+
+	.margin-bottom {
+		margin: 30px 30px 50px;
+		width: calc(100% - 60px);
+	}
+
+	uni-easyinput[type="textarea"] {
+		min-height: 100px;
+	}
+
+	/* 浼樺寲琛ㄥ崟椤归棿璺� */
+	uni-forms-item {
+		margin-bottom: 10px;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/andon/andonCall/andonCall.vue b/pages/eam/andon/andonCall/andonCall.vue
new file mode 100644
index 0000000..d6ab601
--- /dev/null
+++ b/pages/eam/andon/andonCall/andonCall.vue
@@ -0,0 +1,405 @@
+<template>
+	<view class="andon-call-page">
+		<!-- 澶撮儴鍖哄煙 -->
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">瀹夌伅鍛煎彨</block>
+		</cu-custom>
+
+		<!-- 鐢ㄦ埛淇℃伅鍖哄煙 -->
+		<view class="user-info">
+			<image class="avatar" src="/static/avatar_boy.png"></image>
+			<view class="user-detail">
+				<view class="username">{{username}}</view>
+				<view class="user-desc">鎵�灞炰骇绾匡細{{currentLineName || '鏈�夋嫨浜х嚎' }}</view>
+			</view>
+		</view>
+
+		<!-- 缁熻鍏ュ彛鍖哄煙 -->
+		<view class="stats-entry">
+			<view class="entry-item" @click="goToMyInitiated">
+				<view class="icon-container">
+					<image class="avatar-icon" src="/static/icon/kaoqin.png"></image>
+				</view>
+				<text>鎴戝彂璧风殑</text>
+			</view>
+			<view class="entry-item" @click="goToResponded">
+				<view class="icon-container">
+					<image class="avatar-icon" src="/static/icon/tongzhi.png"></image>
+				</view>
+				<text>宸插搷搴�</text>
+			</view>
+			<view class="entry-item" @click="goToProcessed">
+				<view class="icon-container">
+					<image class="avatar-icon" src="/static/icon/liucheng.png"></image>
+				</view>
+				<text>宸插鐞�</text>
+			</view>
+		</view>
+
+		<view class="content"></view>
+
+		<view class="call-type-title">瀹夌伅鎸夐挳</view>
+
+		<!-- 瀹夌伅鎸夐挳鍖哄煙 -->
+		<view class="call-type-grid">
+			<view class="call-type-item" :class="{ 'blink': item.blinkingFlag > 0 }" :style="getButtonColor(item)"
+				@click="toggleBlink(item)" v-for="(item, index) in buttonList" :key="index">
+				<text>{{ item.buttonName }}</text>
+				<view class="shine-effect"></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	import {
+		mapGetters
+	} from "vuex";
+
+	export default {
+		mixins: [MescrollMixin],
+		data() {
+			return {
+				NavBarColor: this.NavBarColor,
+				// 瀹夌伅鎸夐挳鏁版嵁
+				buttonList: [],
+				// 鎸夐挳棰滆壊鏄犲皠
+				buttonColorMap: {
+					"璁惧瀹夌伅": {
+						normal: "linear-gradient(145deg, #ff6b6b, #ee5253)",
+						active: "linear-gradient(145deg, #ff3838, #c0392b)"
+					},
+					"宸ヨ壓瀹夌伅": {
+						normal: "linear-gradient(145deg, #feca57, #ff9f43)",
+						active: "linear-gradient(145deg, #ff9800, #e67e22)"
+					},
+					"璐ㄩ噺瀹夌伅": {
+						normal: "linear-gradient(145deg, #48dbfb, #1dd1a1)",
+						active: "linear-gradient(145deg, #1abc9c, #16a085)"
+					},
+					"浜哄憳瀹夌伅": {
+						normal: "linear-gradient(145deg, #8e44ad, #9b59b6)",
+						active: "linear-gradient(145deg, #8e44ad, #7d3c98)"
+					},
+					"瀹夐槻瀹夌伅": {
+						normal: "linear-gradient(145deg, #54a0ff, #2e86de)",
+						active: "linear-gradient(145deg, #2980b9, #3498db)"
+					}
+				},
+				url: {
+					sendMessage: 'andonresponseconfig/andonResponseConfig/sendMessage',
+					add: "andonorder/andonOrder/app/add",
+					button: "/andonbuttonconfig/andonButtonConfig/queryUserAndonButtonList"
+				},
+				defaultColor: {
+					normal: "linear-gradient(145deg, #0088ff, #0066cc)",
+					active: "linear-gradient(145deg, #ff4d4d, #cc0000)"
+				}
+
+			};
+		},
+		computed: {
+			...mapGetters(["currentLineName", "username", "currentLineId"]),
+			top() {
+				return this.CustomBar * 2 + 200
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				return `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+			},
+		},
+		created() {
+			this.getAndonButtonList()
+		},
+		methods: {
+			
+			getAndonButtonList() {
+				console.log(this.currentLineId)
+				this.$http.get(this.url.button, {
+
+					params: {
+						factoryId: this.currentLineId
+						
+					}
+				}).then(res => {
+					//璁剧疆鍒楄〃鏁版嵁
+
+					if (res.data.success) {
+						console.log(res.data.result)
+						this.buttonList = res.data.result
+					} else {
+						uni.showToast({
+							title: "鎸夐挳鏁版嵁鍔犺浇澶辫触",
+							icon: "none"
+						});
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 
+					uni.showToast({
+						title: "缃戠粶閿欒锛屾棤娉曞姞杞芥寜閽�",
+						icon: "none"
+					});
+				})
+			},
+
+
+
+			/**
+			 * 鍒囨崲闂儊鐘舵�侊紙0=涓嶉棯鐑侊紝1=闂儊锛�
+			 */
+			toggleBlink(item) {
+					this.sendMessage(item);
+			},
+			sendMessage(item) {
+			    this.$http.post(this.url.add,  {
+					/**浜х嚎ID*/
+					   factoryId:this.currentLineId,
+						/**瀹夌伅绫诲瀷*/
+					     buttonId:item.buttonId,
+						/**瀹夌伅浜�*/
+					    operator:uni.getStorageSync("userId"),
+						/**瀹夌伅鏃堕棿*/
+					    operateTime:null,
+						/**瀹夌伅绛夌骇*/
+					     andonLevel:null,
+						/**鍝嶅簲浜�*/
+					    responder:null,
+						/**鍝嶅簲鏃堕棿*/
+					     responseTime:null,
+						/**澶勭悊浜�*/
+					     processor:null,
+						/**澶勭悊瀹屾垚鏃堕棿*/
+					   processTime:null,
+						/**瀹夌伅鐘舵��*/
+					     orderStatus:'1'
+				})
+			        .then(res => {
+			            if (res.data.success) {
+			                uni.showToast({
+			                    title: "鍙戦�佹垚鍔�",
+			                    icon: "none"
+			                });
+							this.getAndonButtonList()
+			            } else {
+			                uni.showToast({
+			                    title: res.data.message,
+			                    icon: "none"
+			                });
+			            }
+			        })
+			        .catch(() => {
+			            uni.showToast({
+			                title: "缃戠粶閿欒锛屾棤娉曞姞杞芥寜閽�",
+			                icon: "none"
+			            });
+			        })
+			},
+
+			/**
+			 * 鑾峰彇鎸夐挳棰滆壊锛堟牴鎹甶nt鐘舵�佸垽鏂級
+			 */
+			getButtonColor(item) {
+				const colorConfig = this.buttonColorMap[item.buttonName] || this.defaultColor;
+				// 1=闂儊锛堜娇鐢╝ctive鑹诧級锛�0=涓嶉棯鐑侊紙浣跨敤normal鑹诧級
+				return {
+					background: item.isBlinking === 1 ? colorConfig.active : colorConfig.normal
+				};
+			},
+
+			// 璺宠浆鏂规硶
+			goToMyInitiated() {
+				uni.navigateTo({
+					url: '/pages/eam/andon/myInitiated/myInitiated?currentLineId=' + this.currentLineId
+				});
+			},
+			goToResponded() {
+				uni.navigateTo({
+					url: '/pages/eam/andon/andonRespond/andonRespond?currentLineId=' + this.currentLineId
+				});
+			},
+			goToProcessed() {
+				uni.navigateTo({
+					url: '/pages/eam/andon/andonDetail/andonDetail?currentLineId=' + this.currentLineId
+				});
+			}
+		}
+	};
+</script>
+
+<style scoped>
+	/* 鍘熸湁鏍峰紡淇濇寔涓嶅彉 */
+	.andon-call-page {
+		background-color: #f9f9f9;
+		min-height: 100vh;
+	}
+
+	.user-info {
+		display: flex;
+		padding: 15px;
+		background-color: #fff;
+		border-bottom: 1px solid #eee;
+		margin-bottom: 10px;
+		box-shadow: 0 2px 5px rgba(0, 0, 0, 0.03);
+	}
+
+	.avatar {
+		width: 80px;
+		height: 80px;
+		border-radius: 50%;
+		margin-right: 10px;
+		border: 3px solid #f0f7ff;
+		box-shadow: 0 3px 8px rgba(0, 122, 255, 0.15);
+	}
+
+	.user-detail {
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+	}
+
+	.username {
+		font-size: 18px;
+		font-weight: bold;
+		margin-bottom: 5px;
+		color: #333;
+	}
+
+	.user-desc {
+		font-size: 14px;
+		color: #666;
+		line-height: 1.6;
+	}
+
+	.stats-entry {
+		display: flex;
+		justify-content: space-around;
+		padding: 20px 15px;
+		background-color: #fff;
+		border-bottom: 10px solid #f5f5f5;
+	}
+
+	.entry-item {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		padding: 15px 0;
+		border-radius: 12px;
+		width: 30%;
+		transition: all 0.3s ease;
+	}
+
+	.entry-item:active {
+		transform: scale(0.96);
+		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) inset;
+	}
+
+	.icon-container {
+		width: 60px;
+		height: 60px;
+		border-radius: 16px;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		background: linear-gradient(145deg, #f0f0f0, #ffffff);
+		box-shadow: 5px 5px 10px #e0e0e0, -5px -5px 10px #ffffff;
+	}
+
+	.avatar-icon {
+		width: 32px;
+		height: 32px;
+	}
+
+	.entry-item text {
+		margin-top: 10px;
+		font-size: 14px;
+		color: #333;
+		font-weight: 500;
+	}
+
+	.call-type-title {
+		font-size: 16px;
+		font-weight: bold;
+		padding: 15px;
+		background-color: #fff;
+		margin-top: 10px;
+		border-bottom: 1px solid #eee;
+		color: #333;
+	}
+
+	.call-type-grid {
+		display: flex;
+		flex-wrap: wrap;
+		padding: 10px;
+		background-color: #fff;
+	}
+
+	.call-type-item {
+		width: calc(50% - 10px);
+		height: 110px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		margin: 5px;
+		border-radius: 16px;
+		font-size: 18px;
+		font-weight: 600;
+		color: #fff;
+		position: relative;
+		box-shadow: 6px 6px 12px rgba(0, 0, 0, 0.15),
+			-3px -3px 8px rgba(255, 255, 255, 0.2);
+		transition: all 0.2s ease;
+		overflow: hidden;
+	}
+
+	.shine-effect {
+		position: absolute;
+		top: 0;
+		left: -100%;
+		width: 50%;
+		height: 100%;
+		background: linear-gradient(to right,
+				rgba(255, 255, 255, 0) 0%,
+				rgba(255, 255, 255, 0.2) 50%,
+				rgba(255, 255, 255, 0) 100%);
+		transform: skewX(-25deg);
+		transition: left 0.6s ease;
+	}
+
+	.call-type-item:active .shine-effect,
+	.call-type-item:hover .shine-effect {
+		left: 120%;
+	}
+
+	.call-type-item:active {
+		transform: translateY(2px);
+		box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.2);
+	}
+
+	.blink {
+		animation: blinkEffect 0.8s infinite;
+	}
+
+	@keyframes blinkEffect {
+		0% {
+			opacity: 1;
+			box-shadow: 6px 6px 12px rgba(0, 0, 0, 0.15),
+				-3px -3px 8px rgba(255, 255, 255, 0.2);
+		}
+
+		50% {
+			opacity: 0.6;
+			box-shadow: 0 0 20px rgba(255, 255, 255, 0.7),
+				6px 6px 15px rgba(0, 0, 0, 0.2);
+		}
+
+		100% {
+			opacity: 1;
+			box-shadow: 6px 6px 12px rgba(0, 0, 0, 0.15),
+				-3px -3px 8px rgba(255, 255, 255, 0.2);
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/andon/andonDetail/andonDetail.vue b/pages/eam/andon/andonDetail/andonDetail.vue
new file mode 100644
index 0000000..9d6da9f
--- /dev/null
+++ b/pages/eam/andon/andonDetail/andonDetail.vue
@@ -0,0 +1,315 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">鎴戠殑澶勭悊</block>
+		</cu-custom>
+
+		<view class="list-container">
+			<!-- 鍒楄〃椤� -->
+			<view class="andon-item" v-for="(item, index) in mockBillList" :key="index">
+				<!-- 涓讳俊鎭笌鎿嶄綔鍖哄鍣� -->
+				<view class="item-content">
+					<!-- 宸︿晶淇℃伅鍖� -->
+					<view class="info-section">
+						<!-- 椤堕儴鏍稿績淇℃伅 -->
+						<view class="item-header">
+							<text class="type-value">{{ item.buttonName }}</text>
+							<text class="status-tag" :style="{ backgroundColor: statusColorMap[item.orderStatus] }">
+								{{ statusMap[item.orderStatus] || '鏈煡' }}
+							</text>
+						</view>
+
+						<!-- 涓棿淇℃伅鍗$墖 -->
+						<view class="info-card">
+							<view class="info-row">
+								<view class="info-col">
+									<text class="label">宸ュ巶锛�</text>
+									<text class="value">{{item.parentFactoryName || '-' }}</text>
+								</view>
+								<view class="info-col">
+									<text class="label">浜х嚎锛�</text>
+									<text class="value">{{item.factoryName || '-' }}</text>
+								</view>
+							</view>
+							<view class="info-row">
+								<view class="info-col">
+									<text class="label">鍙戣捣浜猴細</text>
+									<text class="value">{{item.operator}}</text>
+								</view>
+								<view class="info-col">
+									<text class="label">鍝嶅簲鏃堕暱锛�</text>
+									<text class="value">{{item.upgradeResponseDuration || '-' }} 鍒嗛挓</text>
+								</view>
+							</view>
+						</view>
+
+						<!-- 鍝嶅簲浜轰俊鎭� -->
+						<view class="responder-group">
+							<text class="responder-title">鍝嶅簲浜猴細</text>
+							<text class="responder-name">{{item.responder || '鏈垎閰�' }}</text>
+						</view>
+						<view class="responder-group">
+							<text class="responder-title">澶勭悊浜猴細</text>
+							<text class="responder-name">{{item.responder || '鏈垎閰�' }}</text>
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<!-- 绌虹姸鎬� -->
+			<view v-if="mockBillList.length === 0" class="empty-state">
+				<image src="/static/icon/empty_andon.png" class="empty-img" mode="widthFix"></image>
+				<text class="empty-text">鏆傛棤鍙戣捣鐨勫畨鐏褰�</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				mockBillList: [],
+				NavBarColor: this.NavBarColor || '#ffffff',
+				url: {
+					button: "/andonbuttonconfig/andonButtonConfig/queryUserAndonCallList",
+				},
+				currentLineId: '',
+				statusMap: {
+					'1': '寰呭搷搴�',
+					'2': '寰呭鐞�',
+					'3': '宸插畬鎴�'
+					
+				},
+				statusColorMap: {
+					'1': '#ff5252', // 寰呭搷搴�-绾㈣壊
+					'2': '#ff9800', // 宸插搷搴�-姗欒壊
+					'3': '#4caf50', // 宸插鐞�-缁胯壊
+					
+				}
+			};
+		},
+		created() {
+			this.getAndonButtonList();
+		},
+		methods: {
+			// 鑾峰彇宸ュ崟鍒楄〃鏁版嵁
+			getAndonButtonList() {
+				this.$http
+					.get(this.url.button, {
+						params: {
+							factoryId: this.currentLineId,
+							orderStatus:"3"
+						}
+					})
+					.then((res) => {
+						if (res.data.success) {
+							this.mockBillList = res.data.result || [];
+							// 鎸夋椂闂村�掑簭鎺掑簭锛堝亣璁惧瓨鍦╝ndonTime瀛楁锛�
+							this.mockBillList.sort((a, b) => new Date(b.andonTime) - new Date(a.andonTime));
+						} else {
+							uni.showToast({
+								title: "鏁版嵁鍔犺浇澶辫触",
+								icon: "none"
+							});
+						}
+					})
+					.catch(() => {
+						uni.showToast({
+							title: "缃戠粶閿欒锛屾棤娉曞姞杞�",
+							icon: "none"
+						});
+					});
+			},
+
+			
+		},
+		onLoad(options) {
+			// 鎺ユ敹椤甸潰鍙傛暟
+			this.currentLineId = options.currentLineId || '';
+			console.log(this.currentLineId)
+		}
+	};
+</script>
+
+<style scoped>
+	.container {
+		background-color: #f5f5f5;
+		min-height: 100vh;
+	}
+
+	.list-container {
+		padding: 20rpx;
+	}
+
+	/* 鍒楄〃椤规牱寮� */
+	.andon-item {
+		background-color: #ffffff;
+		border-radius: 12rpx;
+		padding: 24rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+	}
+
+	/* 鍐呭涓庢搷浣滃尯瀹瑰櫒 */
+	.item-content {
+		display: flex;
+		align-items: flex-start;
+		/* 椤堕儴瀵归綈 */
+		gap: 16rpx;
+	}
+
+	/* 宸︿晶淇℃伅鍖� */
+	.info-section {
+		flex: 1;
+		min-width: 0;
+		/* 瑙e喅flex瀛愬厓绱犳孩鍑洪棶棰� */
+	}
+
+	/* 椤堕儴鏍稿績淇℃伅鍖� */
+	.item-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 24rpx;
+		/* 澧炲ぇ涓庝笅鏂瑰尯鍩熺殑闂磋窛 */
+		padding-bottom: 16rpx;
+		border-bottom: 1rpx solid #f1f1f1;
+	}
+
+	.type-value {
+		font-size: 30rpx;
+		font-weight: 600;
+		color: #333333;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	/* 鐘舵�佹爣绛炬牱寮� */
+	.status-tag {
+		font-size: 24rpx;
+		padding: 6rpx 16rpx;
+		border-radius: 20rpx;
+		color: #ffffff;
+		font-weight: 500;
+		line-height: 1;
+	}
+
+	/* 涓棿淇℃伅鍗$墖 */
+	.info-card {
+		background-color: #f9f9f9;
+		border-radius: 8rpx;
+		padding: 16rpx;
+		margin-bottom: 24rpx;
+		/* 澧炲ぇ涓庝笅鏂瑰尯鍩熺殑闂磋窛 */
+	}
+
+	.info-row {
+		display: flex;
+		justify-content: space-between;
+		margin-bottom: 12rpx;
+	}
+
+	.info-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.info-col {
+		flex: 1;
+		display: flex;
+		align-items: center;
+	}
+
+	.info-col .label {
+		font-size: 24rpx;
+		color: #666666;
+		width: 120rpx;
+	}
+
+	.info-col .value {
+		font-size: 26rpx;
+		color: #333333;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	/* 鍝嶅簲浜轰俊鎭尯 */
+	.responder-group {
+		display: flex;
+		align-items: center;
+		margin-bottom: 24rpx;
+		/* 澧炲ぇ涓庝笅鏂规搷浣滆鐨勯棿璺� */
+	}
+
+	.responder-title {
+		font-size: 26rpx;
+		color: #666666;
+		margin-right: 8rpx;
+	}
+
+	.responder-name {
+		font-size: 26rpx;
+		color: #333333;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	/* 鏂板鎿嶄綔琛� */
+	.action-row {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+		/* 鎸夐挳闈犲彸 */
+	}
+
+	.action-label {
+		font-size: 26rpx;
+		color: #666666;
+		margin-right: 16rpx;
+		/* 澧炲ぇ涓庢寜閽殑闂磋窛 */
+	}
+
+	/* 鍝嶅簲鎸夐挳鏍峰紡 */
+	.respond-btn {
+		background-color: #007aff;
+		color: #ffffff;
+		border-radius: 8rpx;
+		padding: 10rpx 24rpx;
+		font-size: 26rpx;
+		line-height: 1;
+		border: none;
+	}
+
+	/* 绂佺敤鐘舵�佹寜閽� */
+	.respond-btn.disabled {
+		background-color: #e5e9f2;
+		color: #c9cdD4;
+	}
+
+	/* 鎸夐挳鐐瑰嚮鍙嶉 */
+	.respond-btn:not(.disabled):active {
+		background-color: #0051aa;
+	}
+
+	/* 绌虹姸鎬佹牱寮� */
+	.empty-state {
+		text-align: center;
+		padding: 150rpx 0;
+		color: #999999;
+	}
+
+	.empty-img {
+		width: 160rpx;
+		height: 160rpx;
+		margin-bottom: 30rpx;
+		opacity: 0.5;
+	}
+
+	.empty-text {
+		font-size: 28rpx;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/andon/andonHandler/andonHandler.vue b/pages/eam/andon/andonHandler/andonHandler.vue
new file mode 100644
index 0000000..f9af9df
--- /dev/null
+++ b/pages/eam/andon/andonHandler/andonHandler.vue
@@ -0,0 +1,671 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">瀹夌伅澶勭疆</block>
+		</cu-custom>
+
+		<uni-search-bar placeholder="鍗曞彿鏌ヨ" @confirm="search" :focus="false" v-model="searchValue" @blur="blur"
+			@focus="focus" @input="input" @cancel="cancel" @clear="clear">
+		</uni-search-bar>
+
+		<view class="content">
+			<ren-dropdown-filter :filterData='filterData' :defaultIndex='defaultIndex' @onSelected='ed'
+				@dateChange='dateChange'>
+			</ren-dropdown-filter>
+		</view>
+
+
+		<view class="container">
+
+			<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+				<view class="production-container">
+					<view class="bill-table" v-for="(item, index) in mockBillList" :key="index">
+						<!-- 琛ㄥご锛堝叡鐢ㄦ牱寮忥級 -->
+						<view class="table-content">
+							<!-- 鍗曟嵁鍙疯 -->
+							<view class="table-row">
+								<text class="table-header">鍗曟嵁鍙凤細</text>
+								<text class="table-value">{{item.billNo || item.num}}</text>
+							</view>
+							<!-- 瀹夌伅绛夌骇琛� -->
+							<view class="table-row">
+								<text class="table-header">瀹夌伅绛夌骇锛�</text>
+								<text class="table-value">{{item.materialCode}}</text>
+							</view>
+							<!-- 浜х嚎琛� -->
+							<view class="table-row">
+								<text class="table-header">浜х嚎锛�</text>
+								<text class="table-value">{{item.materialDesc}}</text>
+							</view>
+							<!--宸ヤ綅琛� -->
+							<view class="table-row">
+								<text class="table-header">宸ヤ綅锛�</text>
+								<text class="table-value">{{item.productionLine}}</text>
+							</view>
+							<!-- 闂绫诲瀷琛� -->
+							<view class="table-row">
+								<text class="table-header">闂绫诲瀷锛�</text>
+								<text class="table-value">{{item.team}}</text>
+							</view>
+							<!-- 闂鍙戣捣浜鸿 -->
+							<view class="table-row">
+								<text class="table-header">闂鍙戣捣浜猴細</text>
+								<text class="table-value">{{item.team}}</text>
+							</view>
+							<!-- 鍙戣捣鏃堕棿琛� -->
+							<view class="table-row">
+								<text class="table-header">鍙戣捣鏃堕棿锛�</text>
+								<text class="table-value">{{item.team}}</text>
+							</view>
+							<view class="table-row">
+								<text class="table-header">鍗曟嵁鐘舵�侊細</text>
+								<view class="table-value">
+									<text class="status-tag"
+										:class="[{ passed: item.inspectResult === '鏈搷搴�' },{ failed: item.inspectResult === '宸插畬鎴�' },{ called: item.inspectResult === '宸插搷搴�' }]">
+										{{item.inspectResult}}
+									</text>
+								</view>
+							</view>
+							<!-- 鎿嶄綔琛� -->
+							<view class="table-row operation-row">
+								<text class="table-header">鎿嶄綔锛�</text>
+								<view class="table-value">
+									<view class="button-group">
+										<button class="action-btn" v-for="btn in getActionButtons(item.inspectResult)"
+											:key="btn.type" @click="handleButtonClick(item, btn)" :class="btn.type">
+											{{btn.text}}
+										</button>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</mescroll-uni>
+		</view>
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				mockBillList: [{
+						billNo: 'ADD2025052010110201', // 鍗曟嵁鍙�
+						materialCode: '涓�绾�', // 鐗╂枡缂栫爜
+						materialDesc: '鐑鐞嗙嚎', // 鐗╂枡鎻忚堪
+						spec: '1鍙峰伐浣�', // 瑙勬牸鍨嬪彿
+						productionLine: '鐑鐞嗙粍', // 浜х嚎
+						team: '璁惧寮傚父', // 鐝粍
+						produceDate: 'admin', // 鐢熶骇鏃ユ湡
+						planQty: '2025-05-11 10:20:15',
+						inspectResult: '鏈搷搴�'
+					},
+					{
+						billNo: 'ADD2025052010110201', // 鍗曟嵁鍙�
+						materialCode: '涓�绾�', // 鐗╂枡缂栫爜
+						materialDesc: '鐑鐞嗙嚎', // 鐗╂枡鎻忚堪
+						spec: '1鍙峰伐浣�', // 瑙勬牸鍨嬪彿
+						productionLine: '鐑鐞嗙粍', // 浜х嚎
+						team: '璁惧寮傚父', // 鐝粍
+						produceDate: 'admin', // 鐢熶骇鏃ユ湡
+						planQty: '2025-05-11 10:20:15',
+						inspectResult: '宸插搷搴�'
+					},
+					{
+						billNo: 'ADD2025052010110201', // 鍗曟嵁鍙�
+						materialCode: '涓�绾�', // 鐗╂枡缂栫爜
+						materialDesc: '鐑鐞嗙嚎', // 鐗╂枡鎻忚堪
+						spec: '1鍙峰伐浣�', // 瑙勬牸鍨嬪彿
+						productionLine: '鐑鐞嗙粍', // 浜х嚎
+						team: '璁惧寮傚父', // 鐝粍
+						produceDate: 'admin', // 鐢熶骇鏃ユ湡
+						planQty: '2025-05-11 10:20:15',
+						inspectResult: '宸插畬鎴�'
+					},
+					{
+						billNo: 'ADD2025052010110201', // 鍗曟嵁鍙�
+						materialCode: '涓�绾�', // 鐗╂枡缂栫爜
+						materialDesc: '鐑鐞嗙嚎', // 鐗╂枡鎻忚堪
+						spec: '1鍙峰伐浣�', // 瑙勬牸鍨嬪彿
+						productionLine: '鐑鐞嗙粍', // 浜х嚎
+						team: '璁惧寮傚父', // 鐝粍
+						produceDate: 'admin', // 鐢熶骇鏃ユ湡
+						planQty: '2025-05-11 10:20:15',
+						inspectResult: '宸插畬鎴�'
+					},
+					{
+						billNo: 'ADD2025052010110201', // 鍗曟嵁鍙�
+						materialCode: '涓�绾�', // 鐗╂枡缂栫爜
+						materialDesc: '鐑鐞嗙嚎', // 鐗╂枡鎻忚堪
+						spec: '1鍙峰伐浣�', // 瑙勬牸鍨嬪彿
+						productionLine: '鐑鐞嗙粍', // 浜х嚎
+						team: '璁惧寮傚父', // 鐝粍
+						produceDate: 'admin', // 鐢熶骇鏃ユ湡
+						planQty: '2025-05-11 10:20:15',
+						inspectResult: '鏈搷搴�'
+					},
+					{
+						billNo: 'ADD2025052010110201', // 鍗曟嵁鍙�
+						materialCode: '涓�绾�', // 鐗╂枡缂栫爜
+						materialDesc: '鐑鐞嗙嚎', // 鐗╂枡鎻忚堪
+						spec: '1鍙峰伐浣�', // 瑙勬牸鍨嬪彿
+						productionLine: '鐑鐞嗙粍', // 浜х嚎
+						team: '璁惧寮傚父', // 鐝粍
+						produceDate: 'admin', // 鐢熶骇鏃ユ湡
+						planQty: '2025-05-11 10:20:15',
+						inspectResult: '鏈搷搴�'
+					},
+					{
+						billNo: 'ADD2025052010110201', // 鍗曟嵁鍙�
+						materialCode: '涓�绾�', // 鐗╂枡缂栫爜
+						materialDesc: '鐑鐞嗙嚎', // 鐗╂枡鎻忚堪
+						spec: '1鍙峰伐浣�', // 瑙勬牸鍨嬪彿
+						productionLine: '鐑鐞嗙粍', // 浜х嚎
+						team: '璁惧寮傚父', // 鐝粍
+						produceDate: 'admin', // 鐢熶骇鏃ユ湡
+						planQty: '2025-05-11 10:20:15',
+						inspectResult: '鏈搷搴�'
+					}
+				],
+				searchValue: '',
+				filterData: [
+					[{
+						text: '浜х嚎',
+						value: ''
+					}, {
+						text: '浜х嚎1',
+						value: 1
+					}, {
+						text: '浜х嚎2',
+						value: 2
+					}, {
+						text: '浜х嚎3',
+						value: 3
+					}],
+					[{
+						text: '鐝粍',
+						value: ''
+					}, {
+						text: '鐝粍1',
+						value: 1
+					}, {
+						text: '鐝粍2',
+						value: 2
+					}, {
+						text: '鐝粍3',
+						value: 3
+					}]
+				],
+				defaultIndex: [0, 0],
+				scrollLeft: 0,
+				NavBarColor: this.NavBarColor,
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10, // 姣忛〉鏁版嵁鐨勬暟閲�
+
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				actionConfig: {
+					// 鏈搷搴旂姸鎬佷笅鐨勬搷浣滄寜閽�
+					'unexecuted': [{
+							text: '鍝嶅簲',
+							type: 'check',
+							path: '/pages/eam/production/check/check'
+						},
+						// {
+						// 	text: '濉姤',
+						// 	type: 'process',
+						// 	path: '/pages/eam/production/process/process'
+						// },
+						{
+							text: '璇︽儏',
+							type: 'device',
+							path: '/pages/eam/andon/andonDetail/andonDetail'
+						}
+					],
+					'executing': [{
+							text: '濉姤',
+							type: 'process',
+							path: '/pages/eam/andon/andonAction/andonAction'
+						},
+						{
+							text: '璇︽儏',
+							type: 'device',
+							path: '/pages/eam/andon/andonDetail/andonDetail'
+						}
+					],
+					
+					'completed': [
+						{
+							text: '璇︽儏',
+							type: 'device',
+							path: '/pages/eam/andon/andonDetail/andonDetail'
+						}
+					]
+
+				},
+				url: {
+					delete: "/pm/arrivalAdvice/delete",
+					sub: "/pm/arrivalAdvice/issue",
+					list: "/pm/arrivalAdvice/list",
+
+				},
+				placeholderStyle: "color:#2979FF;font-size:14px",
+				msdDelList: [],
+				msgList: [], //鍒楄〃鏁版嵁
+				announcementList: [],
+			}
+		},
+
+		computed: {
+			top() {
+				return this.CustomBar * 3 + 200
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+
+		methods: {
+			// 鏍规嵁鐘舵�佽幏鍙栧搴旂殑鎿嶄綔鎸夐挳
+			getActionButtons(status) {
+				switch (status) {
+					case '鏈搷搴�':
+					case 0:
+						return this.actionConfig.unexecuted;
+					case '宸插搷搴�':
+					case 1:
+						return this.actionConfig.executing;
+					case '宸插畬鎴�':
+					case 2:
+						return this.actionConfig.completed;
+					default:
+						return this.actionConfig.unexecuted;
+				}
+			},
+
+			search(res) {
+				uni.showToast({
+					title: '鎼滅储锛�' + res.value,
+					icon: 'none'
+				})
+			},
+			input(res) {
+				console.log('----input:', res)
+			},
+			clear(res) {
+				console.log('clear浜嬩欢锛屾竻闄ゅ�间负锛�' + res.value)
+			},
+			/**
+			 * @param {Object} res
+			 * 褰撹緭鍏ユ澶卞幓鐒︾偣鏃惰Е鍙�
+			 */
+			blur(res) {
+				console.log('blur浜嬩欢锛岃緭鍏ュ�间负锛�' + res.value)
+
+			},
+			/**
+			 * @param {Object} e
+			 * 褰撹緭鍏ユ鑾峰緱鐒︾偣鏃惰Е鍙�
+			 */
+			focus(e) {
+				console.log('blur浜嬩欢锛岃緭鍏ュ�间负锛�' + e.value)
+
+			},
+			cancel(res) {
+				console.log('blur浜嬩欢锛岃緭鍏ュ�间负锛�' + res.value)
+			},
+			ed(res) {
+				console.log(res)
+			},
+			dateChange(d) {
+				uni.showToast({
+					icon: 'none',
+					title: d
+				})
+			},
+
+			searBut() {
+				this.msgList = [];
+				this.$http.get(this.url.list, {
+					params: {
+						pageNo: 1,
+						pageSize: this.upOption.page.size,
+						num: this.formData.num,
+						createUserName: this.formData.createUserName,
+						endCreateTime: this.formData.endCreateTime,
+						startCreateTime: this.formData.startCreateTime,
+						column: "createTime",
+						order: "desc",
+						type: 2,
+						status: 0
+					}
+				}).then(res => {
+					//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+
+
+			},
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+
+			// 鎸夐挳鐐瑰嚮澶勭悊
+			handleButtonClick(item, button) {
+				console.log('鐐瑰嚮鎸夐挳:', button.text, '宸ュ崟:', item.billNo);
+
+				switch (button.type) {
+					case 'check':
+						// 榻愬妫�鏌�
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					case 'process':
+						// 宸ヨ壓鐐规
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					case 'device':
+						// 璁惧鐐规
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					case 'sample':
+						// 鏍蜂欢鏍¢獙
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					case 'feed':
+						// 涓婃枡
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					case 'record':
+						// 鎿嶄綔璁板綍
+						uni.navigateTo({
+							url: button.path + '?billNo=' + item.billNo
+						});
+						break;
+					case 'report':
+						// 鎶ュ伐
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					case 'inspection':
+						// 鐢熶骇妫�楠�
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					case 'detail':
+						// 璇︽儏
+						uni.navigateTo({
+							url: button.path + '?billNo=' + item.billNo
+						});
+						break;
+					default:
+						uni.showToast({
+							title: '鍔熻兘寮�鍙戜腑',
+							icon: 'none'
+						});
+				}
+			},
+
+			upCallback(page) {
+				//鑱旂綉鍔犺浇鏁版嵁
+				this.$http.get(this.url.list, {
+					params: {
+						pageNo: page.num,
+						pageSize: page.size,
+						order: "desc",
+						column: "createTime",
+						type: 2,
+						status: 0
+
+					}
+				}).then(res => {
+					//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					//console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+
+			},
+
+		}
+	}
+</script>
+
+<style>
+	<style scoped>.container {
+		background-color: #f5f5f5;
+		min-height: 100vh;
+	}
+
+	.tab-container {
+		background-color: #ffffff;
+	}
+
+	.production-container {
+		padding: 20rpx;
+	}
+
+	.bill-table {
+		background-color: #ffffff;
+		border-radius: 16rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+		overflow: hidden;
+	}
+
+	.table-content {
+		padding: 20rpx;
+	}
+
+	.table-row {
+		display: flex;
+		margin-bottom: 15rpx;
+	}
+
+	.table-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.table-header {
+		flex: 0 0 180rpx;
+		font-size: 28rpx;
+		color: #666;
+	}
+
+	.table-value {
+		flex: 1;
+		font-size: 28rpx;
+		color: #333;
+		display: flex;
+		align-items: center;
+	}
+
+	.right-content {
+		margin-left: auto;
+		color: #999;
+		font-size: 26rpx;
+	}
+
+	.status-tag {
+		padding: 6rpx 12rpx;
+		border-radius: 8rpx;
+		font-size: 24rpx;
+		background-color: #ff6347;
+		color: #ffffff;
+	}
+
+	.status-tag.passed {
+		background-color: #39b54a;
+	}
+
+	.status-tag.called {
+		background-color: #ffaa00;
+	}
+
+	.button-group {
+		display: flex;
+		flex-wrap: wrap;
+		gap: 15rpx;
+	}
+
+	.action-btn {
+		padding: 12rpx 20rpx;
+		font-size: 24rpx;
+		border-radius: 8rpx;
+		border: none;
+		background-color: #007AFF;
+		color: #ffffff;
+		min-width: 120rpx;
+		text-align: center;
+	}
+
+	/* 涓嶅悓鎿嶄綔鎸夐挳鐨勯鑹� */
+	.action-btn.check {
+		background-color: #007AFF;
+	}
+
+	.action-btn.process {
+		background-color: #39b54a;
+	}
+
+	.action-btn.device {
+		background-color: #9932cc;
+	}
+
+	.action-btn.sample {
+		background-color: #ff6347;
+	}
+
+	.action-btn.feed {
+		background-color: #ffa500;
+	}
+
+	.action-btn.report {
+		background-color: #1e90ff;
+	}
+
+	.action-btn.inspection {
+		background-color: #228b22;
+	}
+
+	.action-btn.detail {
+		background-color: #6a5acd;
+	}
+
+	.action-btn.record {
+		background-color: #808080;
+	}
+
+	.operation-row {
+		margin-top: 10rpx;
+		padding-top: 15rpx;
+		border-top: 1rpx solid #eee;
+	}
+
+	.empty-tip {
+		text-align: center;
+		padding: 100rpx 0;
+		color: #999;
+		font-size: 28rpx;
+	}
+
+	/* 鏍囩椤垫牱寮� */
+	.nav {
+		white-space: nowrap;
+		width: 100%;
+	}
+
+	.cu-item {
+		display: inline-block;
+		min-width: 150rpx;
+		padding: 0 30rpx;
+		height: 80rpx;
+		line-height: 80rpx;
+		text-align: center;
+	}
+
+	.cu-item.cur {
+		border-bottom: 4rpx solid #0081ff;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/andon/andonRespond/andonRespond.vue b/pages/eam/andon/andonRespond/andonRespond.vue
new file mode 100644
index 0000000..abc405f
--- /dev/null
+++ b/pages/eam/andon/andonRespond/andonRespond.vue
@@ -0,0 +1,335 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">瀹夌伅鍝嶅簲</block>
+		</cu-custom>
+
+		<view class="list-container">
+			<!-- 鍒楄〃椤� -->
+			<view class="andon-item" v-for="(item, index) in mockBillList" :key="index">
+				<!-- 涓讳俊鎭笌鎿嶄綔鍖哄鍣� -->
+				<view class="item-content">
+					<!-- 宸︿晶淇℃伅鍖� -->
+					<view class="info-section">
+						<!-- 椤堕儴鏍稿績淇℃伅 -->
+						<view class="item-header">
+							<text class="type-value">{{ item.buttonName }}</text>
+							<text class="status-tag" :style="{ backgroundColor: statusColorMap[item.orderStatus] }">
+								{{ statusMap[item.orderStatus] || '鏈煡' }}
+							</text>
+						</view>
+
+						<!-- 涓棿淇℃伅鍗$墖 -->
+						<view class="info-card">
+							<view class="info-row">
+								<view class="info-col">
+									<text class="label">宸ュ巶锛�</text>
+									<text class="value">{{item.parentFactoryName || '-' }}</text>
+								</view>
+								<view class="info-col">
+									<text class="label">浜х嚎锛�</text>
+									<text class="value">{{item.factoryName || '-' }}</text>
+								</view>
+							</view>
+							<view class="info-row">
+								<view class="info-col">
+									<text class="label">鍙戣捣浜猴細</text>
+									<text class="value">{{item.operatorName}}</text>
+								</view>
+								<view class="info-col">
+									<text class="label">鍝嶅簲鏃堕暱锛�</text>
+									<text class="value">{{item.upgradeResponseDuration || '-' }} 鍒嗛挓</text>
+								</view>
+							</view>
+						</view>
+
+						<!-- 鍝嶅簲浜轰俊鎭� -->
+						<view class="responder-group">
+							<text class="responder-title">鍝嶅簲浜猴細</text>
+							<text class="responder-name">{{item.responder || '鏈垎閰�' }}</text>
+						</view>
+						<view class="responder-group">
+							<text class="responder-title">澶勭悊浜猴細</text>
+							<text class="responder-name">{{item.processor || '鏈垎閰�' }}</text>
+						</view>
+
+						<!-- 鏂板鎿嶄綔琛� -->
+						<view class="action-row">
+							<text class="action-label">鎿嶄綔锛�</text>
+							<button class="respond-btn" :class="{ disabled: !canRespond(item.orderStatus) }"
+								@click="handleRespond(item)" :disabled="!canRespond(item.orderStatus)">
+								澶勭悊
+							</button>
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<!-- 绌虹姸鎬� -->
+			<view v-if="mockBillList.length === 0" class="empty-state">
+				<image src="/static/icon/empty_andon.png" class="empty-img" mode="widthFix"></image>
+				<text class="empty-text">鏆傛棤鍙戣捣鐨勫畨鐏褰�</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				mockBillList: [],
+				NavBarColor: this.NavBarColor || '#ffffff',
+				url: {
+					button: "/andonbuttonconfig/andonButtonConfig/queryUserAndonCallList",
+					respond: "/andonorder/andonOrder/AndonHandel"
+				},
+				currentLineId: '',
+				statusMap: {
+					'1': '寰呭搷搴�',
+					'2': '寰呭鐞�',
+					'3': '宸插畬鎴�'
+					
+				},
+				statusColorMap: {
+					'1': '#ff5252', // 寰呭搷搴�-绾㈣壊
+					'2': '#ff9800', // 宸插搷搴�-姗欒壊
+					'3': '#4caf50', // 宸插鐞�-缁胯壊
+					
+				}
+			};
+		},
+		methods: {
+			// 鑾峰彇宸ュ崟鍒楄〃鏁版嵁
+			getAndonButtonList() {
+				this.$http
+					.get(this.url.button, {
+						params: {
+							factoryId: this.currentLineId,
+							orderStatus:"2"
+						}
+					})
+					.then((res) => {
+						if (res.data.success) {
+							this.mockBillList = res.data.result || [];
+							// 鎸夋椂闂村�掑簭鎺掑簭锛堝亣璁惧瓨鍦╝ndonTime瀛楁锛�
+							this.mockBillList.sort((a, b) => new Date(b.andonTime) - new Date(a.andonTime));
+						} else {
+							uni.showToast({
+								title: "鏁版嵁鍔犺浇澶辫触",
+								icon: "none"
+							});
+						}
+					})
+					.catch(() => {
+						uni.showToast({
+							title: "缃戠粶閿欒锛屾棤娉曞姞杞�",
+							icon: "none"
+						});
+					});
+			},
+
+			// 鍒ゆ柇鏄惁鍙搷搴旓紙浠呭緟鍝嶅簲鐘舵�佸彲鐐瑰嚮锛�
+			canRespond(status) {
+				return status === '2'; // 鐘舵��1涓哄緟鍝嶅簲
+			},
+
+			// 澶勭悊鍝嶅簲閫昏緫
+			handleRespond(item) {
+				uni.redirectTo({
+					url: '/pages/eam/andon/andonAdd/andonAdd?item=' +
+						encodeURIComponent(JSON.stringify(item)) +
+						'&currentLineId=' + this.currentLineId
+				})
+			}
+		},
+		onLoad(options) {
+			// 鎺ユ敹椤甸潰鍙傛暟
+			this.currentLineId = options.currentLineId || '';
+			// 鍔犺浇鏁版嵁
+			this.getAndonButtonList();
+		}
+	};
+</script>
+
+<style scoped>
+	.container {
+		background-color: #f5f5f5;
+		min-height: 100vh;
+	}
+
+	.list-container {
+		padding: 20rpx;
+	}
+
+	/* 鍒楄〃椤规牱寮� */
+	.andon-item {
+		background-color: #ffffff;
+		border-radius: 12rpx;
+		padding: 24rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+	}
+
+	/* 鍐呭涓庢搷浣滃尯瀹瑰櫒 */
+	.item-content {
+		display: flex;
+		align-items: flex-start;
+		/* 椤堕儴瀵归綈 */
+		gap: 16rpx;
+	}
+
+	/* 宸︿晶淇℃伅鍖� */
+	.info-section {
+		flex: 1;
+		min-width: 0;
+		/* 瑙e喅flex瀛愬厓绱犳孩鍑洪棶棰� */
+	}
+
+	/* 椤堕儴鏍稿績淇℃伅鍖� */
+	.item-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 24rpx;
+		/* 澧炲ぇ涓庝笅鏂瑰尯鍩熺殑闂磋窛 */
+		padding-bottom: 16rpx;
+		border-bottom: 1rpx solid #f1f1f1;
+	}
+
+	.type-value {
+		font-size: 30rpx;
+		font-weight: 600;
+		color: #333333;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	/* 鐘舵�佹爣绛炬牱寮� */
+	.status-tag {
+		font-size: 24rpx;
+		padding: 6rpx 16rpx;
+		border-radius: 20rpx;
+		color: #ffffff;
+		font-weight: 500;
+		line-height: 1;
+	}
+
+	/* 涓棿淇℃伅鍗$墖 */
+	.info-card {
+		background-color: #f9f9f9;
+		border-radius: 8rpx;
+		padding: 16rpx;
+		margin-bottom: 24rpx;
+		/* 澧炲ぇ涓庝笅鏂瑰尯鍩熺殑闂磋窛 */
+	}
+
+	.info-row {
+		display: flex;
+		justify-content: space-between;
+		margin-bottom: 12rpx;
+	}
+
+	.info-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.info-col {
+		flex: 1;
+		display: flex;
+		align-items: center;
+	}
+
+	.info-col .label {
+		font-size: 24rpx;
+		color: #666666;
+		width: 120rpx;
+	}
+
+	.info-col .value {
+		font-size: 26rpx;
+		color: #333333;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	/* 鍝嶅簲浜轰俊鎭尯 */
+	.responder-group {
+		display: flex;
+		align-items: center;
+		margin-bottom: 24rpx;
+		/* 澧炲ぇ涓庝笅鏂规搷浣滆鐨勯棿璺� */
+	}
+
+	.responder-title {
+		font-size: 26rpx;
+		color: #666666;
+		margin-right: 8rpx;
+	}
+
+	.responder-name {
+		font-size: 26rpx;
+		color: #333333;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	/* 鏂板鎿嶄綔琛� */
+	.action-row {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+		/* 鎸夐挳闈犲彸 */
+	}
+
+	.action-label {
+		font-size: 26rpx;
+		color: #666666;
+		margin-right: 16rpx;
+		/* 澧炲ぇ涓庢寜閽殑闂磋窛 */
+	}
+
+	/* 鍝嶅簲鎸夐挳鏍峰紡 */
+	.respond-btn {
+		background-color: #007aff;
+		color: #ffffff;
+		border-radius: 8rpx;
+		padding: 10rpx 24rpx;
+		font-size: 26rpx;
+		line-height: 1;
+		border: none;
+	}
+
+	/* 绂佺敤鐘舵�佹寜閽� */
+	.respond-btn.disabled {
+		background-color: #e5e9f2;
+		color: #c9cdD4;
+	}
+
+	/* 鎸夐挳鐐瑰嚮鍙嶉 */
+	.respond-btn:not(.disabled):active {
+		background-color: #0051aa;
+	}
+
+	/* 绌虹姸鎬佹牱寮� */
+	.empty-state {
+		text-align: center;
+		padding: 150rpx 0;
+		color: #999999;
+	}
+
+	.empty-img {
+		width: 160rpx;
+		height: 160rpx;
+		margin-bottom: 30rpx;
+		opacity: 0.5;
+	}
+
+	.empty-text {
+		font-size: 28rpx;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/andon/myInitiated/myInitiated.vue b/pages/eam/andon/myInitiated/myInitiated.vue
new file mode 100644
index 0000000..290fa3a
--- /dev/null
+++ b/pages/eam/andon/myInitiated/myInitiated.vue
@@ -0,0 +1,361 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">鎴戠殑鍙戣捣</block>
+		</cu-custom>
+
+		<view class="list-container">
+			<!-- 鍒楄〃椤� -->
+			<view class="andon-item" v-for="(item, index) in mockBillList" :key="index">
+				<!-- 涓讳俊鎭笌鎿嶄綔鍖哄鍣� -->
+				<view class="item-content">
+					<!-- 宸︿晶淇℃伅鍖� -->
+					<view class="info-section">
+						<!-- 椤堕儴鏍稿績淇℃伅 -->
+						<view class="item-header">
+							<text class="type-value">{{ item.buttonName }}</text>
+							<text class="status-tag" :style="{ backgroundColor: statusColorMap[item.orderStatus] }">
+								{{ statusMap[item.orderStatus] || '鏈煡' }}
+							</text>
+						</view>
+
+						<!-- 涓棿淇℃伅鍗$墖 -->
+						<view class="info-card">
+							<view class="info-row">
+								<view class="info-col">
+									<text class="label">宸ュ巶锛�</text>
+									<text class="value">{{ item.parentFactoryName || '-' }}</text>
+								</view>
+								<view class="info-col">
+									<text class="label">浜х嚎锛�</text>
+									<text class="value">{{ item.factoryName || '-' }}</text>
+								</view>
+							</view>
+							<view class="info-row">
+								<view class="info-col">
+									<text class="label">鍙戣捣浜猴細</text>
+									<text class="value">{{ item.operatorName}}</text>
+								</view>
+								<view class="info-col">
+									<text class="label">鍝嶅簲鏃堕暱锛�</text>
+									<text class="value">{{item.upgradeResponseDuration || '-' }} 鍒嗛挓</text>
+								</view>
+							</view>
+							<view class="info-row">
+								<view class="info-col">
+									<text class="label">鍝嶅簲浜猴細</text>
+									<text class="value">{{ item.responder}}</text>
+								</view>
+								<view class="info-col">
+									<text class="label">澶勭悊浜猴細</text>
+									<text class="value">{{item.processor || '-' }} 鍒嗛挓</text>
+								</view>
+							</view>
+						</view>
+
+						
+						
+
+						<!-- 鏂板鎿嶄綔琛� -->
+						<view class="action-row">
+							<text class="action-label">鎿嶄綔锛�</text>
+							<button class="respond-btn" :class="{ disabled: !canRespond(item.orderStatus) }"
+								@click="handleRespond(item)" :disabled="!canRespond(item.orderStatus)">
+								鍝嶅簲
+							</button>
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<!-- 绌虹姸鎬� -->
+			<view v-if="mockBillList.length === 0" class="empty-state">
+				<image src="/static/icon/empty_andon.png" class="empty-img" mode="widthFix"></image>
+				<text class="empty-text">鏆傛棤鍙戣捣鐨勫畨鐏褰�</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				mockBillList: [],
+				NavBarColor: this.NavBarColor || '#ffffff',
+				url: {
+					button: "/andonbuttonconfig/andonButtonConfig/queryUserAndonCallList",
+					respond: "/andonorder/andonOrder/AndonRespond"
+				},
+				currentLineId: '',
+				statusMap: {
+					'1': '寰呭搷搴�',
+					'2': '寰呭鐞�',
+					'3': '宸插畬鎴�'
+					
+				},
+				statusColorMap: {
+					'1': '#ff5252', // 寰呭搷搴�-绾㈣壊
+					'2': '#ff9800', // 宸插搷搴�-姗欒壊
+					'3': '#4caf50', // 宸插鐞�-缁胯壊
+				}
+			};
+		},
+		methods: {
+			// 鑾峰彇宸ュ崟鍒楄〃鏁版嵁
+			getAndonButtonList() {
+				this.$http
+					.get(this.url.button, {
+						params: {
+							factoryId: this.currentLineId,
+							orderStatus:"1"
+						}
+					})
+					.then((res) => {
+						if (res.data.success) {
+							this.mockBillList = res.data.result || [];
+							// 鎸夋椂闂村�掑簭鎺掑簭锛堝亣璁惧瓨鍦╝ndonTime瀛楁锛�
+							this.mockBillList.sort((a, b) => new Date(b.andonTime) - new Date(a.andonTime));
+						} else {
+							uni.showToast({
+								title: "鏁版嵁鍔犺浇澶辫触",
+								icon: "none"
+							});
+						}
+					})
+					.catch(() => {
+						uni.showToast({
+							title: "缃戠粶閿欒锛屾棤娉曞姞杞�",
+							icon: "none"
+						});
+					});
+			},
+
+			// 鍒ゆ柇鏄惁鍙搷搴旓紙浠呭緟鍝嶅簲鐘舵�佸彲鐐瑰嚮锛�
+			canRespond(status) {
+				return status === '1'; // 鐘舵��1涓哄緟鍝嶅簲
+			},
+
+			// 澶勭悊鍝嶅簲閫昏緫
+			handleRespond(item) {
+				// 妯℃嫙缃戠粶璇锋眰
+				this.$http.get(this.url.respond, {
+					params: {
+						id: item.id
+					}
+
+				}).then(res => {
+					if (res.data.success) {
+						uni.showToast({
+							title: "鍝嶅簲鎴愬姛",
+							icon: "none",
+							duration: 1500
+						});
+						// 寤惰繜鍒锋柊鍒楄〃锛岀‘淇濇彁绀哄彲瑙�
+						setTimeout(() => {
+							this.getAndonButtonList();
+						}, 500);
+					} else {
+						uni.showToast({
+							title: res.data.message || "鍝嶅簲澶辫触",
+							icon: "none"
+						});
+					}
+				}).catch(() => {
+					uni.showToast({
+						title: "缃戠粶閿欒锛屽搷搴斿け璐�",
+						icon: "none"
+					});
+				});
+			}
+		},
+		onLoad(options) {
+			// 鎺ユ敹椤甸潰鍙傛暟
+			this.currentLineId = options.currentLineId || '';
+			// 鍔犺浇鏁版嵁
+			this.getAndonButtonList();
+		}
+	};
+</script>
+
+<style scoped>
+	.container {
+		background-color: #f5f5f5;
+		min-height: 100vh;
+	}
+
+	.list-container {
+		padding: 20rpx;
+	}
+
+	/* 鍒楄〃椤规牱寮� */
+	.andon-item {
+		background-color: #ffffff;
+		border-radius: 12rpx;
+		padding: 24rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+	}
+
+	/* 鍐呭涓庢搷浣滃尯瀹瑰櫒 */
+	.item-content {
+		display: flex;
+		align-items: flex-start;
+		/* 椤堕儴瀵归綈 */
+		gap: 16rpx;
+	}
+
+	/* 宸︿晶淇℃伅鍖� */
+	.info-section {
+		flex: 1;
+		min-width: 0;
+		/* 瑙e喅flex瀛愬厓绱犳孩鍑洪棶棰� */
+	}
+
+	/* 椤堕儴鏍稿績淇℃伅鍖� */
+	.item-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 24rpx;
+		/* 澧炲ぇ涓庝笅鏂瑰尯鍩熺殑闂磋窛 */
+		padding-bottom: 16rpx;
+		border-bottom: 1rpx solid #f1f1f1;
+	}
+
+	.type-value {
+		font-size: 30rpx;
+		font-weight: 600;
+		color: #333333;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	/* 鐘舵�佹爣绛炬牱寮� */
+	.status-tag {
+		font-size: 24rpx;
+		padding: 6rpx 16rpx;
+		border-radius: 20rpx;
+		color: #ffffff;
+		font-weight: 500;
+		line-height: 1;
+	}
+
+	/* 涓棿淇℃伅鍗$墖 */
+	.info-card {
+		background-color: #79f4b5;
+		border-radius: 8rpx;
+		padding: 16rpx;
+		margin-bottom: 24rpx;
+		/* 澧炲ぇ涓庝笅鏂瑰尯鍩熺殑闂磋窛 */
+	}
+
+	.info-row {
+		display: flex;
+		justify-content: space-between;
+		margin-bottom: 12rpx;
+	}
+
+	.info-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.info-col {
+		flex: 1;
+		display: flex;
+		align-items: center;
+	}
+
+	.info-col .label {
+		font-size: 24rpx;
+		color: #666666;
+		width: 120rpx;
+	}
+
+	.info-col .value {
+		font-size: 26rpx;
+		color: #333333;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	/* 鍝嶅簲浜轰俊鎭尯 */
+	.responder-group {
+		display: flex;
+		align-items: center;
+		margin-bottom: 24rpx;
+		/* 澧炲ぇ涓庝笅鏂规搷浣滆鐨勯棿璺� */
+	}
+
+	.responder-title {
+		font-size: 26rpx;
+		color: #666666;
+		margin-right: 8rpx;
+	}
+
+	.responder-name {
+		font-size: 26rpx;
+		color: #333333;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	/* 鏂板鎿嶄綔琛� */
+	.action-row {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+		/* 鎸夐挳闈犲彸 */
+	}
+
+	.action-label {
+		font-size: 26rpx;
+		color: #666666;
+		margin-right: 16rpx;
+		/* 澧炲ぇ涓庢寜閽殑闂磋窛 */
+	}
+
+	/* 鍝嶅簲鎸夐挳鏍峰紡 */
+	.respond-btn {
+		background-color: #007aff;
+		color: #ffffff;
+		border-radius: 8rpx;
+		padding: 10rpx 24rpx;
+		font-size: 26rpx;
+		line-height: 1;
+		border: none;
+	}
+
+	/* 绂佺敤鐘舵�佹寜閽� */
+	.respond-btn.disabled {
+		background-color: #e5e9f2;
+		color: #c9cdD4;
+	}
+
+	/* 鎸夐挳鐐瑰嚮鍙嶉 */
+	.respond-btn:not(.disabled):active {
+		background-color: #0051aa;
+	}
+
+	/* 绌虹姸鎬佹牱寮� */
+	.empty-state {
+		text-align: center;
+		padding: 150rpx 0;
+		color: #999999;
+	}
+
+	.empty-img {
+		width: 160rpx;
+		height: 160rpx;
+		margin-bottom: 30rpx;
+		opacity: 0.5;
+	}
+
+	.empty-text {
+		font-size: 28rpx;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/production/ProductionManager/ProductionManager.vue b/pages/eam/production/ProductionManager/ProductionManager.vue
new file mode 100644
index 0000000..4f498e1
--- /dev/null
+++ b/pages/eam/production/ProductionManager/ProductionManager.vue
@@ -0,0 +1,965 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">鎺掍骇宸ュ崟</block>
+		</cu-custom>
+
+		<uni-search-bar placeholder="鐢熶骇鍗曞彿/鐗╂枡淇℃伅/鎵爜鏌ヨ" @confirm="search" :focus="false" v-model="searchValue"
+			@clear="clear" class="search-bar">
+		</uni-search-bar>
+
+		<!-- 		<view class="filter-container">
+			<ren-dropdown-filter :filterData='filterData' :defaultIndex='defaultIndex' @onSelected='ed'
+				@dateChange='dateChange'>
+			</ren-dropdown-filter>
+		</view> -->
+
+		<view class="status-tabs">
+			<view class="solid-bottom">
+				<scroll-view scroll-x class="bg-white nav text-center ">
+					<view class="flex text-center justify-around">
+						<view class="cu-item" :class="item.value==TabCur?'text-blue cur':''"
+							v-for="(item,index) in tabs" :key="index" @tap="tabSelect" :data-id="item.value">
+							{{item.title}}
+						</view>
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+
+		<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+			<view class="production-list">
+				<!-- 宸ュ崟鍒楄〃 -->
+				<view class="order-card" v-for="(item, index) in filteredBillList" :key="index"
+					:class="{ 'highlight': item.priority === '楂�' }">
+
+					<!-- 宸ュ崟澶撮儴 - 鍩烘湰淇℃伅 -->
+					<view class="order-header">
+						<view class="order-primary">
+							<text class="order-number">
+								{{ item.workOrderCode.length > 15 
+							    ? item.workOrderCode.substring(0, 15) + '...' 
+							    : item.workOrderCode 
+							  }}
+							</text>
+							<view class="order-status" :class="'status-' + item.workOrderStatus">
+								{{item.workOrderStatus_dictText}}
+							</view>
+						</view>
+						<view class="order-meta">
+							<text class="meta-item">{{item.materialNumber}}</text>
+							<text class="meta-item" style="margin-left: 10px;">{{item.materialName}}</text>
+						</view>
+					</view>
+
+					<!-- 宸ュ崟鍐呭 - 璇︾粏淇℃伅 -->
+					<view class="order-content">
+						<view class="content-row">
+							<text class="content-label">浜х嚎:</text>
+							<text class="content-value">{{item.factoryId_dictText}}</text>
+						</view>
+						<view class="content-row">
+							<text class="content-label">鐝:</text>
+							<text class="content-value">{{item.shiftId_dictText}}</text>
+						</view>
+						<view class="content-row">
+							<text class="content-label">鐝粍:</text>
+							<text class="content-value">{{item.groupId_dictText}}</text>
+						</view>
+
+
+						<view class="content-stats">
+							<view class="stat-item">
+								<text class="stat-text">璁″垝鐢熶骇鏁伴噺</text>
+								<text class="stat-number" style="color: orange;">{{item.planQuantity}}</text>
+							</view>
+							<view class="stat-item">
+								<text class="stat-text">瀹為檯鎶ュ伐鏁伴噺</text>
+								<text class="stat-number" style="color: yellowgreen;">{{item.actualQuantity}}</text>
+							</view>
+							<view class="stat-item">
+								<text class="stat-text">鎺掍骇鏃ユ湡
+								</text>
+								<text class="stat-number">{{item.workOrderDate}}</text>
+							</view>
+						</view>
+
+						<view class="content-row inspection-row">
+							<text class="content-label">鍙戝竷鏃堕棿:</text>
+							<view class="inspection-status">
+								<text class="status-text" :class="item.workOrderStatus === 'EXECUTING' ? 'passed' : ''">
+									{{ new Date(item.publishTime).toISOString().split('T')[0] }}
+								</text>
+							</view>
+							<text class="content-label">閲嶅彂甯冩椂闂�:</text>
+							<view class="inspection-status">
+								<text class="status-text"
+									:class="item.workOrderStatus === 'EXECUTING' ? 'passeds' : ''">
+									{{item.republishTime}}
+								</text>
+							</view>
+							<!-- <view class="feeding-info">
+								<text class="feeding-text">閲嶅彂甯冩椂闂�:{{item.republishTime.split(' ')[0]}}</text>
+							</view> -->
+						</view>
+						<!-- <view class="content-row inspection-row">
+							<text class="content-label">璋冨害鍛樺悕绉�:</text>
+							<view class="inspection-status">
+								<text class="status-text" :class="item.dispatcherName === '鍏巶璋冨害鍛�' ? 'passeds' : ''">
+									{{item.dispatcherName}}
+								</text>
+							</view>
+							<view class="feeding-info">
+								<text class="feeding-text">璋冨害鍛樼紪鍙�:{{item.dispatcherCode}}</text>
+							</view>
+						</view> -->
+					</view>
+
+					<!-- 鎿嶄綔鎸夐挳鍖� -->
+					<view class="order-actions">
+						<view class="action-buttons">
+							<button class="action-btn" v-for="btn in getActionButtons(TabCur)" :key="btn.type"
+								@click="handleButtonClick(item, btn)" :class="btn.type">
+								{{btn.text}}
+							</button>
+						</view>
+					</view>
+				</view>
+
+				<!-- 绌虹姸鎬� -->
+				<view class="empty-state" v-if="filteredBillList.length === 0">
+					<view class="empty-icon">
+						<text class="iconfont">&#xe61c;</text>
+					</view>
+					<text class="empty-text">鏆傛棤绗﹀悎鏉′欢鐨勫伐鍗�</text>
+				</view>
+			</view>
+		</mescroll-uni>
+		<pdaScan></pdaScan>
+	</view>
+</template>
+
+<script>
+	const tabs = [{
+			title: '寰呮墽琛�',
+			value: 0
+		},
+		{
+			title: '鎵ц涓�',
+			value: 1
+		},
+		{
+			title: '宸插畬鎴�',
+			value: 2
+		}
+	];
+	import pdaScan from "@/components/mes/pdaScan.vue"
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	import {
+		mapGetters
+	} from "vuex";
+	export default {
+		mixins: [MescrollMixin],
+		components: {
+			pdaScan
+		},
+		data() {
+			return {
+				announcement1: [],
+				NavBarColor: this.NavBarColor,
+				mockBillList: [],
+				searchValue: '',
+				filterData: [
+					[],
+					[{
+							text: '璁㈠崟绫诲瀷',
+							value: ''
+						},
+						{
+							text: '寮犳澃鐝粍',
+							value: '寮犳澃鐝粍'
+						},
+						{
+							text: '鏉庡崕鐝粍',
+							value: '鏉庡崕鐝粍'
+						},
+						{
+							text: '鐜嬪己鐝粍',
+							value: '鐜嬪己鐝粍'
+						},
+						{
+							text: '鍒樻檽鐝粍',
+							value: '鍒樻檽鐝粍'
+						},
+						{
+							text: '鍛ㄧ孩鐝粍',
+							value: '鍛ㄧ孩鐝粍'
+						},
+						{
+							text: '閮戝啗鐝粍',
+							value: '閮戝啗鐝粍'
+						}
+					]
+				],
+				defaultIndex: [0, 0],
+				tabs,
+				TabCur: 0,
+				upOption: {
+					page: {
+						num: 0,
+						size: 10,
+					},
+					noMoreSize: 4,
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~',
+					},
+					textNoMore: '宸插姞杞藉叏閮ㄦ暟鎹�'
+				},
+				actionConfig: {
+					'unexecuted': [{
+							text: '榻愬妫�鏌�',
+							type: 'check',
+							path: '/pages/eam/production/check/check'
+						},
+						{
+							text: '宸ヨ壓鐐规',
+							type: 'process',
+							path: '/pages/eam/production/process/process'
+						},
+						{
+							text: '璁惧鐐规',
+							type: 'device',
+							path: '/pages/eam/production/ToDoList/ToDoList'
+						},
+						{
+							text: '鏍蜂欢鏍¢獙',
+							type: 'sample',
+							path: '/pages/eam/production/sample/sample'
+						},
+						// {
+						// 	text: '涓婃枡',
+						// 	type: 'feed',
+						// 	path: '/pages/eam/production/feed/feed'
+						// },
+						{
+							text: '璁板綍',
+							type: 'record',
+							path: '/pages/eam/production/record/record'
+						}
+					],
+					'executing': [
+						// {
+						// 	text: '鎶ュ伐',
+						// 	type: 'report',
+						// 	path: '/pages/eam/production/report/report'
+						// },
+						{
+							text: '鐢熶骇妫�楠�',
+							type: 'inspection',
+							path: '/pages/eam/quality/qualityInspection/addInspection/addInspection'
+						},
+						// {
+						// 	text: '璁板綍',
+						// 	type: 'record',
+						// 	path: '/pages/eam/production/record/record'
+						// }
+					],
+					'completed': [{
+							text: '璇︽儏',
+							type: 'detail',
+							path: '/pages/eam/production/detail/detail'
+						},
+						// {
+						// 	text: '璁板綍',
+						// 	type: 'record',
+						// 	path: '/pages/eam/production/record/record'
+						// }
+					]
+				},
+				url: {
+					delete: "/pm/arrivalAdvice/delete",
+					orderCategory: 'sys/dict/getDictItems/work_order_status',
+					list: "/mes/mesProductionWorkOrder/list",
+				},
+				orderCategoryList: [],
+				msgList: [],
+				filterSelected: {
+					productionLine: '',
+					team: ''
+				}
+			}
+		},
+
+		computed: {
+			...mapGetters(["currentLineName", "username", "currentLineId"]),
+			top() {
+				return this.CustomBar * 3 + 150
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				return `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+			},
+			// 杩囨护鍚庣殑宸ュ崟鍒楄〃
+			filteredBillList() {
+				return this.msgList.filter(item => {
+					// 鐘舵�佽繃婊�
+					let statusMatch = false;
+					if (this.TabCur === 0) {
+						statusMatch = item.workOrderStatus === 'PUBLISHED';
+					} else if (this.TabCur === 1) {
+						statusMatch = item.workOrderStatus === 'EXECUTING';
+					} else if (this.TabCur === 2) {
+						statusMatch = item.workOrderStatus === 'CLOSED';
+					}
+
+					// 鎼滅储杩囨护
+					const searchMatch = this.searchValue === '' ||
+						(item.workOrderCode && item.workOrderCode.includes(this.searchValue));
+
+					// 绛涢�夊櫒杩囨护
+					const filterMatch =
+						(!this.filterSelected.productionLine || item.productionLine === this.filterSelected
+							.productionLine) &&
+						(!this.filterSelected.team || item.team === this.filterSelected.team);
+
+					return statusMatch && searchMatch && filterMatch;
+				});
+			}
+		},
+
+		created() {
+			this.getOrderCategory();
+		},
+		onShow() {
+			let that = this
+			uni.$off('scancodedate') // 姣忔杩涙潵鍏� 绉婚櫎鍏ㄥ眬鑷畾涔変簨浠剁洃鍚櫒
+			uni.$on('scancodedate', function(data) {
+				console.log(data.code)
+				let str = data.code;
+				that.searchValue = str;
+				that.search(that.searchValue);
+			})
+		},
+		methods: {
+			/**
+			 * @param {Object} status
+			 * 璁㈠崟绫诲瀷
+			 */
+
+			getOrderCategory() {
+				this.$http.get(this.url.orderCategory).then(res => {
+					if (res.data.success) {
+						this.orderCategoryList = res.data.result;
+
+						// 濡傛灉闇�瑕佽浆鎹㈡牸寮忎互鍖归厤 {text, value} 缁撴瀯
+						const formattedList = this.orderCategoryList.map(item => {
+							return {
+								text: item.name || item.text || item.label || item, // 鏍规嵁瀹為檯鏁版嵁缁撴瀯璋冩暣
+								value: item.id || item.value || item.name || item // 鏍规嵁瀹為檯鏁版嵁缁撴瀯璋冩暣
+							};
+						});
+
+						// 灏嗚浆鎹㈠悗鐨勬暟缁勮祴鍊肩粰 filterData 鐨勭涓�涓暟缁�
+						this.filterData[0] = formattedList;
+					}
+				}).catch(() => {
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+			},
+
+			// 鏍规嵁鐘舵�佽幏鍙栧搴旂殑鎿嶄綔鎸夐挳
+			getActionButtons(status) {
+				switch (status) {
+					case 0:
+						return this.actionConfig.unexecuted;
+					case 1:
+						return this.actionConfig.executing;
+					case 2:
+						return this.actionConfig.completed;
+					default:
+						return [];
+				}
+			},
+
+			search(res) {
+				this.msgList = [];
+				let keyword = this.TabCur;
+				// 缁熶竴澶勭悊鏌ヨ鍙傛暟锛堝叕鍏遍儴鍒嗭級
+				const baseParams = {
+					pageNo: 1,
+					factoryId: this.currentLineId,
+					pageSize: 10,
+					order: "desc",
+					column: "createTime",
+					// 鍚屾椂浼犻�掍袱涓煡璇㈠瓧娈碉紝鍊奸兘涓簊earchValue
+					workOrderCode: "*" + this.searchValue + "*"
+
+				};
+
+				// 鏍规嵁涓嶅悓TabCur璁剧疆瀵瑰簲鐨剋orkOrderStatus
+				let params;
+				if (keyword == 0) {
+					params = {
+						...baseParams,
+						workOrderStatus: 'PUBLISHED'
+					};
+				} else if (keyword == 1) {
+					params = {
+						...baseParams,
+						workOrderStatus: 'EXECUTING'
+					};
+				} else if (keyword == 2) {
+					params = {
+						...baseParams,
+						workOrderStatus: 'CLOSED'
+					};
+				}
+
+				// 鍙戣捣缁熶竴鐨勬煡璇㈣姹�
+				this.$http.get(this.url.list, {
+						params
+					})
+					.then(res => {
+						// 鑱旂綉鎴愬姛鐨勫洖璋�
+						const result = res.data.result || {};
+						const records = result.records || [];
+
+						// 鏍规嵁涓嶅悓TabCur鏇存柊瀵瑰簲鐨勬暟鎹�
+						if (keyword == 0) {
+							this.announcement1 = records;
+							this.msg1Count = result.total || 0;
+							this.msg1Title = `閫氱煡(${this.msg1Count})`;
+						} else {
+							this.announcement2 = records;
+							this.msg2Count = result.total || 0;
+							this.msg2Title = `閫氱煡(${this.msg2Count})`;
+						}
+
+						// 缁撴潫鍔犺浇鐘舵��
+						this.mescroll.endSuccess(records.length);
+
+						// 鍚堝苟鏁版嵁鍒癿sgList
+						if (res.data.success) {
+							records.forEach(item => {
+								this.msgList.push(item);
+							});
+						}
+					})
+					.catch(() => {
+						// 鑱旂綉澶辫触澶勭悊
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					});
+			},
+
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+			clear() {
+				this.searchValue = '';
+			},
+
+			ed(res) {
+				// 鏇存柊绛涢�夋潯浠�
+				this.filterSelected = {
+					productionLine: res[0].value,
+					team: res[1].value
+				};
+			},
+
+			dateChange(d) {
+				uni.showToast({
+					icon: 'none',
+					title: `鏃ユ湡绛涢��: ${d}`
+				});
+			},
+
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+
+			// 鎸夐挳鐐瑰嚮澶勭悊
+			handleButtonClick(item, button) {
+				console.log('鐐瑰嚮鎸夐挳:', button.text, '宸ュ崟:', item.id);
+				let url = button.path;
+					url += `?id=${item.id}`;
+				uni.navigateTo({
+					url
+				});
+			},
+
+
+			upCallback(page) {
+				//鑱旂綉鍔犺浇鏁版嵁
+				console.log("tabindex", this.TabCur)
+				let keyword = this.TabCur
+				if (keyword == 0) {
+					this.$http.get(this.url.list, {
+						params: {
+							pageNo: page.num,
+							pageSize: page.size,
+							order: "desc",
+							column: "createTime",
+							factoryId: this.currentLineId,
+							workOrderStatus: 'PUBLISHED'
+
+						}
+					}).then(res => {
+						//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+
+						this.announcement1 = res.data.result.records
+						console.log(this.announcement1)
+						this.mescroll.endSuccess(this.announcement1.length);
+						//console.log("url", res)
+						//璁剧疆鍒楄〃鏁版嵁
+						if (res.data.success) {
+							console.log("res", res.data)
+							this.msg1Count = res.data.result.total
+							this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+							for (let annItem of this.announcement1) {
+								this.msgList.push(annItem)
+							}
+						}
+						if (page.num == 1) {
+							this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+							this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+						}
+
+					}).catch(() => {
+						//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					})
+				} else if (keyword == 1) {
+					this.$http.get(this.url.list, {
+						params: {
+							pageSize: page.size,
+							order: "desc",
+							column: "createTime",
+							factoryId: this.currentLineId,
+							workOrderStatus: 'EXECUTING'
+						}
+					}).then(res => {
+						//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+						this.announcement2 = res.data.result.records
+						this.mescroll.endSuccess(this.announcement2.length, this.msgCount);
+
+						//璁剧疆鍒楄〃鏁版嵁
+						if (res.data.success) {
+							console.log("res sys", res.data)
+							this.msg2Count = res.data.result.total
+							this.msg2Title = "閫氱煡(" + res.data.result.total + ")";
+
+							for (let item of this.announcement2) {
+								this.msgList.push(item)
+							}
+						}
+						if (page.num == 1) {
+							this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+							this.msgList = this.msgList.concat(this.announcement2); //杩藉姞鏂版暟鎹�
+						}
+					}).catch(() => {
+						//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					})
+				} else if (keyword == 2) {
+
+					this.$http.get(this.url.list, {
+						params: {
+							pageSize: page.size,
+							order: "desc",
+							column: "createTime",
+							factoryId: this.currentLineId,
+							workOrderStatus: 'CLOSED'
+						}
+					}).then(res => {
+						//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+						this.announcement2 = res.data.result.records
+						this.mescroll.endSuccess(this.announcement2.length, this.msgCount);
+
+						//璁剧疆鍒楄〃鏁版嵁
+						if (res.data.success) {
+							console.log("res sys", res.data)
+							this.msg2Count = res.data.result.total
+							this.msg2Title = "閫氱煡(" + res.data.result.total + ")";
+
+							for (let item of this.announcement2) {
+								this.msgList.push(item)
+							}
+						}
+						if (page.num == 1) {
+							this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+							this.msgList = this.msgList.concat(this.announcement2); //杩藉姞鏂版暟鎹�
+						}
+					}).catch(() => {
+						//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					})
+
+				}
+
+			},
+
+			onClickItem(e) {
+				if (this.current != e.currentIndex) {
+					this.current = e.currentIndex;
+					console.log("閫変腑鐨勬槸锛�" + this.current);
+				}
+			},
+
+			tabSelect(e) {
+				this.TabCur = e.currentTarget.dataset.id;
+				this.scrollLeft = (e.currentTarget.dataset.id - 1) * 60;
+				this.msgList = [] // 鍏堢疆绌哄垪琛�,鏄剧ず鍔犺浇杩涘害
+				this.mescroll.resetUpScroll() // 鍐嶅埛鏂板垪琛ㄦ暟鎹�
+			},
+
+
+
+			ListTouchStart(e) {
+				this.listTouchStart = e.touches[0].pageX
+			},
+
+			// ListTouch璁$畻鏂瑰悜
+			ListTouchMove(e) {
+				this.listTouchDirection = e.touches[0].pageX - this.listTouchStart > 0 ? 'right' : 'left'
+			},
+
+			// ListTouch璁$畻婊氬姩
+			ListTouchEnd(e) {
+				if (this.listTouchDirection == 'left') {
+					this.modalName = e.currentTarget.dataset.target
+				} else {
+					this.modalName = null
+				}
+				this.listTouchDirection = null
+			},
+		}
+	}
+</script>
+
+<style scoped>
+	.container {
+		background-color: #f1f5f9;
+		min-height: 100vh;
+		font-family: 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
+	}
+
+	/* 鎼滅储鏍忔牱寮� */
+	.search-bar {
+		padding: 16rpx 20rpx;
+		background-color: #ffffff;
+	}
+
+	/* 绛涢�夊櫒瀹瑰櫒 */
+	.filter-container {
+		background-color: #ffffff;
+		border-bottom: 1px solid #e2e8f0;
+	}
+
+	/* 鐘舵�佹爣绛鹃〉 */
+	.status-tabs {
+		background-color: #1e293b;
+
+	}
+
+	.tab-scroll {
+		display: flex;
+		overflow-x: auto;
+		white-space: nowrap;
+	}
+
+	.tab-item {
+		color: #94a3b8;
+		font-size: 30rpx;
+		padding: 24rpx 36rpx;
+		position: relative;
+		cursor: pointer;
+		transition: all 0.3s ease;
+	}
+
+	.tab-item.active {
+		color: #ffffff;
+		font-weight: 500;
+	}
+
+	.tab-indicator {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		height: 4rpx;
+		background-color: #3b82f6;
+	}
+
+	/* 宸ュ崟鍒楄〃鏍峰紡 */
+	.production-list {
+		padding: 20rpx 0;
+	}
+
+	.order-card {
+		background-color: #ffffff;
+		border-radius: 8rpx;
+		margin: 0 20rpx 20rpx;
+		box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+		overflow: hidden;
+		transition: all 0.2s ease;
+	}
+
+
+
+	.order-card:hover {
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+
+	/* 宸ュ崟澶撮儴 */
+	.order-header {
+		padding: 20rpx;
+		border-bottom: 1px solid #f1f5f9;
+	}
+
+	.order-primary {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 12rpx;
+	}
+
+	.order-number {
+		font-size: 32rpx;
+		font-weight: 600;
+		color: #1e293b;
+	}
+
+	.order-status {
+		padding: 6rpx 16rpx;
+		border-radius: 16rpx;
+		font-size: 24rpx;
+		font-weight: 500;
+	}
+
+	.status-PUBLISHED {
+		background-color: #fef3c7;
+		color: #d97706;
+	}
+
+	.status-EXECUTING {
+		background-color: #dbeafe;
+		color: #1e40af;
+	}
+
+	.status-CLOSED {
+		background-color: #dcfce7;
+		color: #059669;
+	}
+
+	.order-meta {
+		display: flex;
+		gap: 20rpx;
+	}
+
+	.meta-item {
+		color: #64748b;
+		font-size: 24rpx;
+	}
+
+	/* 宸ュ崟鍐呭 */
+	.order-content {
+		padding: 20rpx;
+	}
+
+	.content-row {
+		display: flex;
+		margin-bottom: 16rpx;
+	}
+
+	.content-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.content-label {
+		flex: 0 0 180rpx;
+		color: #64748b;
+		font-size: 26rpx;
+	}
+
+	.content-value {
+		flex: 1;
+		color: #1e293b;
+		font-size: 26rpx;
+		word-break: break-word;
+	}
+
+	/* 缁熻鏁版嵁琛� */
+	.content-stats {
+		display: flex;
+		justify-content: space-between;
+		margin: 20rpx 0;
+		padding: 16rpx;
+		background-color: #f8fafc;
+		border-radius: 6rpx;
+	}
+
+	.stat-item {
+		text-align: center;
+		flex: 1;
+	}
+
+	.stat-text {
+		display: block;
+		color: #64748b;
+		font-size: 24rpx;
+		margin-bottom: 4rpx;
+	}
+
+	.stat-number {
+		display: block;
+		color: #1e293b;
+		font-size: 28rpx;
+		font-weight: 600;
+	}
+
+	/* 妫�楠岀姸鎬佽 */
+	.inspection-row {
+		align-items: center;
+	}
+
+	.inspection-status {
+		flex: 1;
+	}
+
+	.status-text {
+		padding: 4rpx 12rpx;
+		border-radius: 4rpx;
+		font-size: 24rpx;
+	}
+
+	.status-text.passed {
+		background-color: #dcfce7;
+		color: #059669;
+	}
+
+	.status-text.passeds {
+		background-color: #a9c8ab;
+		color: #059669;
+	}
+
+	.feeding-info {
+		color: #64748b;
+		font-size: 24rpx;
+	}
+
+	/* 鎿嶄綔鎸夐挳鍖哄鍣� */
+	.order-actions {
+		padding: 20rpx;
+		/* 澧炲姞瀹瑰櫒鍐呰竟璺濓紝鎻愬崌鏁翠綋涓婁笅闂磋窛 */
+		border-top: 1px solid #f1f5f9;
+		background-color: #f8fafc;
+	}
+
+	/* 鎿嶄綔鎸夐挳鍖� - 鏀规垚缃戞牸甯冨眬锛岃鎸夐挳鑷姩瀵归綈涓旈棿璺濇洿鍚堢悊 */
+	.action-buttons {
+		display: grid;
+		grid-template-columns: repeat(auto-fill, minmax(140rpx, 1fr));
+		gap: 20rpx;
+		/* 澧炲ぇ鎸夐挳闂磋窛锛堜笂涓嬪乏鍙崇粺涓�锛� */
+		padding: 20rpx 10rpx;
+		/* 澧炲姞瀹瑰櫒鍐呰竟璺濓紝閬垮厤鎸夐挳璐磋竟 */
+	}
+
+	/* 鎸夐挳鍩虹鏍峰紡 - 澧炲ぇ灏哄鍜岃Е鎽稿尯鍩� */
+	.action-btn {
+		padding: 28rpx 0;
+		/* 鍨傜洿鏂瑰悜鍔犲ぇ鍐呰竟璺濓紝瑙e喅涓婁笅鎷ユ尋 */
+		font-size: 28rpx;
+		/* 瀛椾綋鏀惧ぇ锛岄�傞厤宸ヤ笟鍦烘櫙鎿嶄綔 */
+		height: auto;
+		min-width: 140rpx;
+		/* 淇濊瘉鏈�灏忚Е鎽稿搴︼紙绾�50px锛岀鍚堢Щ鍔ㄧ瑙勮寖锛� */
+		border-radius: 8rpx;
+		/* 閫傚害鍦嗚锛屽吋椤惧伐涓氶涓庤Е鎽镐綋楠� */
+	}
+
+	/* 鎸夐挳棰滆壊淇濇寔宸ヤ笟椋庡姛鑳藉尯鍒� */
+	.action-btn.check {
+		background-color: #3b82f6;
+	}
+
+	.action-btn.process {
+		background-color: #10b981;
+	}
+
+	.action-btn.device {
+		background-color: #8b5cf6;
+	}
+
+	.action-btn.sample {
+		background-color: #ef4444;
+	}
+
+	.action-btn.feed {
+		background-color: #f59e0b;
+	}
+
+	.action-btn.report {
+		background-color: #0ea5e9;
+	}
+
+	.action-btn.inspection {
+		background-color: #10b981;
+	}
+
+	.action-btn.detail {
+		background-color: #6366f1;
+	}
+
+	.action-btn.record {
+		background-color: #64748b;
+	}
+
+	/* 瑙︽懜鍙嶉鏁堟灉 */
+	.action-btn:active {
+		opacity: 0.85;
+		/* 鐐瑰嚮鏃剁暐寰�忔槑锛屾彁渚涘弽棣� */
+		transform: scale(0.98);
+		/* 杞诲井缂╂斁锛屽寮鸿Е鎽告劅 */
+		transition: all 0.1s ease;
+	}
+
+	/* 绌虹姸鎬� */
+	.empty-state {
+		text-align: center;
+		padding: 100rpx 0;
+		color: #94a3b8;
+	}
+
+	.empty-icon {
+		font-size: 80rpx;
+		margin-bottom: 20rpx;
+		color: #cbd5e1;
+	}
+
+	.empty-text {
+		font-size: 28rpx;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/production/ToDoList/ToDoList.vue b/pages/eam/production/ToDoList/ToDoList.vue
new file mode 100644
index 0000000..1cf7501
--- /dev/null
+++ b/pages/eam/production/ToDoList/ToDoList.vue
@@ -0,0 +1,566 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">璁惧鐐规</block>
+		</cu-custom>
+		<view class="container">
+			<template>
+				<!-- 娴獥閬僵灞� -->
+				<view v-if="showPreview" class="overlay" @tap.stop="closePreview">
+					<view class="modal">
+						<!-- 鍏抽棴鎸夐挳 -->
+						<text class="close-btn" @tap.stop="showPreview = false">&times;</text>
+						<!-- 鍥剧墖灞曠ず -->
+						<image :src="previewImageSrc" mode="aspectFit" class="preview-image" @error="handleImageError"
+							:show-menu-by-longpress="false" />
+					</view>
+				</view>
+
+			</template>
+
+			<uni-forms ref="form" :modelValue="formData" validate-trigger="bind" err-show-type="undertext">
+				<uni-group top="1">
+					<view class="divider"><text>鍩烘湰淇℃伅</text></view>
+					<!-- <view class="text-gray margin-bottom-lg">鈥斺�斺�斺�斺�斺�斺�斺�斺�斺�� 鍩烘湰淇℃伅 鈥斺�斺�斺�斺�斺�斺�斺�斺�斺��</view> -->
+					<uni-forms-item :label-width="80" name="num" label="宸ュ崟鍙�:">
+						<uni-easyinput v-model="formData.orderNum" :disabled="true" />
+					</uni-forms-item>
+		
+					<uni-forms-item :label-width="80" name="num" label="璁惧缂栫爜:">
+							<uni-easyinput v-model="formData.inspectionStatus_dictText" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="80" name="installationPosition_dictText" label="瀹夎浣嶇疆:">
+						<uni-easyinput v-model="formData.installationPosition_dictText" :disabled="true" />
+					</uni-forms-item>
+
+					<uni-forms-item :label-width="80" name="remark" label="鐐规鏃ユ湡:">
+						<uni-easyinput v-model="formData.inspectionDate" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="80" name="outNum" label="鐐规浜�:">
+						<uni-easyinput v-model="formData.operator" :disabled="true" />
+					</uni-forms-item>
+
+					<uni-forms-item :label-width="80" name="formData.remark" label="澶囨敞:">
+						<uni-easyinput v-model="formData.remark" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="80" name="outNum" label="鐐规鍥剧墖:">
+
+						<uni-file-picker limit="9" :value="fileLists" :image-styles="imageStyles"
+							:sourceType="sourceType" @select="select" @progress="progress" @success="success"
+							@fail="fail" @delete="deletea" :readonly="readonly" />
+					</uni-forms-item>
+					<uni-forms-item name="outNum" :label-width="80" label="浣滀笟鎸囧:">
+						<button class="cu-btn  bg-blue" @tap="showPreview = true">鏌ョ湅</button>
+					</uni-forms-item>
+				</uni-group>
+			</uni-forms>
+			<!-- <view class="text-gray margin-bottom-lg">鈥斺�斺�斺�斺�斺�斺�斺�斺�斺�� 淇濆吇椤逛俊鎭� 鈥斺�斺�斺�斺�斺�斺�斺�斺�斺��</view> -->
+			<view class="divider"><text>淇濆吇椤逛俊鎭�</text></view>
+			<uni-collapse>
+				<uni-collapse-item :show-animation="true" :accordion="true" title="鏌ョ湅淇濆吇椤�" :border="false"
+					title-border="none">
+					<uni-card margin="10px" spacing="1px" v-for="(item,index) in partTakeAdviceDetailList" :key="index">
+
+
+						<view class="flex">
+							<view class="flex-sub text-light bg-white padding-xs margin-xs radius">琛屽彿:</view>
+							<view class="flex-sub bg-white padding-xs margin-xs radius text-right">{{index+1}}
+							</view>
+						</view>
+						<view class="flex">
+							<view class="flex-sub text-light bg-white padding-xs margin-xs radius">淇濆吇椤�:</view>
+							<view class="flex-sub bg-white padding-xs margin-xs text-bold radius text-right">
+								{{item.itemName}}
+							</view>
+						</view>
+
+						<view class="flex">
+							<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">淇濆吇瑕佹眰:</view>
+							<view class="flex-sub bg-white padding-xs margin-xs radius text-right">
+								{{item.itemDemand}}
+							</view>
+						</view>
+						<view class="flex">
+							<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">鐐规缁撴灉:</view>
+							<view class="flex-sub bg-white padding-xs     text-right margin-xs radius">
+								<uni-data-select :localdata="item.restle" v-model="item.inspectionResult"
+									@change="handleCode($event, index)" :disabled="item.istrue" />
+							</view>
+						</view>
+						<view class="flex">
+							<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">寮傚父鏄惁鎶ヤ慨:</view>
+							<view class="flex-sub bg-white padding-xs     text-right margin-xs radius">
+								<uni-data-select :localdata="item.type"  @change="handleType($event, index)"  v-model="item.reportFlag"
+									:disabled="item.istrue"/>
+							</view>
+						</view>
+
+
+						<view class="flex">
+							<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">寮傚父鎻忚堪:</view>
+							<view class="flex-sub bg-white padding-xs     text-right margin-xs radius">
+								<uni-easyinput v-model="item.exceptionDescription" :disabled="item.istrue" />
+							</view>
+						</view>
+					</uni-card>
+				</uni-collapse-item>
+			</uni-collapse>
+
+
+
+			<view v-show="isShowBtn" class="padding flex flex-direction">
+				<view class="flex-sub bg-blue padding-sm margin-xl radius text-sm text-center text-white"
+					@click.stop="ProductionTask()" hover-class="is-hover">纭畾</view>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	import configService from "@/common/service/config.service.js";
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				showPreview: false,
+				readonly: false,
+				// 鍥剧墖鍥炴樉
+				fileLists: [],
+				// 涓婁紶鍥剧墖鐨勬牱寮�
+				imageStyles: {
+					width: 90,
+					height: 90,
+				},
+				sourceType: ['album', 'camera'],
+				isShowTeam: false,
+				isShowBtn: true,
+				title: '',
+				isTouch: false,
+				scrollLeft: 0,
+				searchValue: '',
+				imgList: [],
+				equipmentList: [],
+				uploadUrl: "/sys/common/upload",
+				formData: {
+					num: '',
+					avatar: [],
+					orderNum: '',
+					operator: '',
+					inspectionDate: ''
+
+				},
+				ipAndPort: configService.staticURL,
+				istrue: true,
+				partTakeAdviceDetailList: [],
+				NavBarColor: this.NavBarColor,
+				url: {
+					upload: "/eam/sysFiles/batch_upload",
+					stallList: "/eam/eamInspectionOrder/queryById",
+					getStandardFile: "eam/maintenanceStandard/queryById",
+					getEquipmentList: 'eam/equipment/list',
+					BaoList: 'eam/eamInspectionOrderDetail/queryList',
+					approval: 'eam/eamInspectionOrder/approval'
+				},
+				id: '',
+				taskId: '',
+				imageFilesList: [],
+				inspectionResult: '',
+				reportFlag:'',
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10 // 姣忛〉鏁版嵁鐨勬暟閲�
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				msg1Count: 0,
+				msg2Count: 0,
+				msg1Title: "",
+				procInstId: '',
+				values: '',
+				flag: '',
+				from: '',
+				standardId: '',
+				previewImageSrc: '',
+				todoName: ''
+
+
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 160
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+		onLoad(options) {
+			const annItem = JSON.parse(decodeURIComponent(options.item));
+		},
+		created() {
+			this.getList();
+			// this.upCallback();
+		},
+
+		methods: {
+			handleImageError(e) {
+				const icon_prefix = "/static/";
+				this.previewImageSrc = icon_prefix + "icn_erro.png"
+			},
+			changehandlingType(e) {
+				this.ScanData.typeName = e;
+			},
+			closePreview() {
+				this.showPreview = false;
+			},
+			ProductionTask() {
+					uni.showLoading({
+						mask: true,
+						title: "鍔犺浇涓�....",
+					})
+					this.$http.post(this.url.approval, {
+						/**
+						 * 纭鎰忚
+						 */
+						confirmComment: this.ScanData.handlingSuggestion,
+						/**
+						 * 纭绫诲瀷 1 閫氳繃  2 椹冲洖
+						 */
+						confirmDealType: this.ScanData.typeName,
+						dataId: this.id,
+						fileList: this.imageFilesList, // 鍖呭惈涓婁紶鍚庣殑鍥剧墖璺緞,,
+						instanceId: this.procInstId,
+						tableDetailList: this.partTakeAdviceDetailList,
+						taskId: this.taskId,
+						userId: this.assignee,
+						values: this.values
+					}).then(res => {
+						uni.hideLoading();
+						if (res.data.success) {
+							uni.showToast({
+								icon: "success",
+								title: '鎻愪氦鎴愬姛',
+								duration: 2000
+							});
+							// this.$Router.replace({
+							// 	name: 'ToDoList'
+							// })
+							this.$Router.replaceAll({
+								name: 'ToDoList'
+							})
+						} else {
+							uni.showModal({
+								title: "鎻愮ず",
+								content: res.data.message,
+								confirmText: '纭畾',
+								showCancel: false,
+							})
+						}
+					}).catch(() => {
+						this.$tip.loaded();
+						uni.showToast({
+							icon: "error",
+							title: res.data.message,
+							duration: 2000
+						});
+					});
+				
+
+			},
+
+			changeEquipmentList(e) {
+				this.formData.num = e;
+			},
+			handleType(e, index) {
+				console.log(e);
+			},
+			handleCode(e, index) {
+				console.log(index);
+				// 鏍规嵁 e 鐨勫�兼潵鍒ゆ柇鏄惁闇�瑕佹洿鏂� isTrue 鐨勭姸鎬�
+				// 鏍规嵁 e 鐨勫�兼潵鍒ゆ柇鏄惁闇�瑕佹洿鏂� isTrue 鐨勭姸鎬�
+				if (e == '2') {
+					this.partTakeAdviceDetailList[index].istrue = false;
+
+				} else if (e == '1') {
+					this.partTakeAdviceDetailList[index].istrue = true;
+				}
+			},
+		
+			getList() {
+				this.$http.get(this.url.BaoList, {
+					params: {
+						orderId: this.id
+					},
+
+				}).then(res => {
+					this.partTakeAdviceDetailList = res.data.result;
+					const restle = [];
+					this.partTakeAdviceDetailList.forEach(item => {
+						item.restle = [{
+								text: "姝e父",
+								value: '1'
+							},
+							{
+								text: "寮傚父",
+								value: '2'
+							}
+						]; // 鏂板瓧娈碉紝鍊间负涓�涓┖鏁扮粍
+						item.type = [{
+								text: "鍚�",
+								value: "0"
+							},
+							{
+								text: "鏄�",
+								value: "1"
+							}
+						]; // 鏂板瓧娈碉紝鍊间负涓�涓┖鏁扮粍
+						item.istrue = true;
+					});
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data.result)
+
+					}
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+				})
+			},
+			getStandardFile() {
+				this.$http.get(this.url.getStandardFile, {
+					params: {
+						id: this.standardId
+					}
+				}).then(res => {
+					if (res.data.success) {
+						console.log("res", res.data.result);
+						const referenceFileStr = res.data.result.referenceFile;
+
+						// 鍒ゆ柇鏄惁瀛樺湪 referenceFile 骞惰繘琛岃В鏋�
+						if (referenceFileStr) {
+							try {
+								const referenceFileObj = JSON.parse(referenceFileStr);
+								const filePath = `${this.ipAndPort}${referenceFileObj.filePath}`;
+								this.previewImageSrc = filePath;
+								console.log('previewImageSrc:', this.previewImageSrc);
+							} catch (e) {
+								console.error("referenceFile 瑙f瀽澶辫触", e);
+								this.previewImageSrc = '';
+							}
+						} else {
+							console.warn("referenceFile 涓嶅瓨鍦�");
+							this.previewImageSrc = '';
+						}
+					}
+				}).catch(err => {
+					console.error("缃戠粶璇锋眰澶辫触", err);
+					// 鑱旂綉澶辫触, 缁撴潫鍔犺浇
+				});
+			},
+			upCallback() {
+				this.$http.get(this.url.stallList, {
+					params: {
+						id: this.id
+					},
+
+				}).then(res => {
+					this.announcement1 = res.data.result
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log(this.announcement1.operator_dictText)
+						this.formData.operator = this.announcement1.operator_dictText
+						this.formData.num = this.announcement1.equipmentId
+						this.formData.remark = this.announcement1.remark
+						this.formData.installationPosition_dictText = this.announcement1
+							.installationPosition_dictText
+						this.formData.inspectionStatus_dictText = this.announcement1.inspectionStatus_dictText
+						this.formData.operatorPhone_dictText = this.announcement1.operatorPhone_dictText
+						this.formData.orderNum = this.announcement1.orderNum
+						this.formData.inspectionDate = this.announcement1.inspectionDate
+						this.formData.inspectionStatus = this.announcement1.inspectionStatus
+						this.ScanData.typeName = this.announcement1.confirmDealType
+						this.formData.confirmComment = this.announcement1.confirmDealType_dictText
+						this.ScanData.handlingSuggestion = this.announcement1.confirmComment
+						this.title = this.todoName ?? '璇︽儏';
+						this.formData.avatar = this.announcement1.imageFiles
+						this.imageFilesList = JSON.parse(this.formData.avatar)
+						const imageObjects = JSON.parse(this.formData.avatar);
+						this.imgList = imageObjects.map(imageObj => {
+							return `${this.ipAndPort}${imageObj.filePath}`;
+						});
+
+						// 鏍规嵁 imgList 鏋勯�� fileLists
+						this.fileLists = this.imgList.map(url => ({
+							url: url,
+							extname: 'png',
+							name: 'eam'
+						}));
+						this.hasInspectionDateArrived();
+					}
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+				})
+			},
+
+			hasInspectionDateArrived() {
+				// 鑾峰彇褰撳墠鏃堕棿
+				const now = new Date();
+				// 鑾峰彇鐐规鏃ユ湡
+				const inspectionDate = new Date(this.formData.inspectionDate);
+				// 璁$畻褰撳墠鏃堕棿涓庣偣妫�鏃ユ湡涔嬮棿鐨勫皬鏃跺樊
+				const diffInHours = (inspectionDate - now) / (1000 * 60 * 60);
+				// 濡傛灉灏忔椂宸皬浜庣瓑浜�0锛岃〃绀哄綋鍓嶆椂闂村凡鍒拌揪鎴栬秴杩囩偣妫�鏃ユ湡
+				return diffInHours <= 0;
+			},
+
+			/* 妫�绱� */
+			getSera(res) {
+				this.msgList = [];
+				if (keyword == 0) {
+					this.$http.get(this.url.stallList, {
+						params: {
+							pageNo: 1,
+							pageSize: 999,
+							order: "desc",
+							column: "createTime",
+							equipmentCode: res
+						}
+					}).then(res => {
+						//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+
+						this.announcement1 = res.data.result.records
+						this.mescroll.endSuccess(this.announcement1.length);
+						console.log("url", res)
+						//璁剧疆鍒楄〃鏁版嵁
+						if (res.data.success) {
+							console.log("res", res.data)
+							this.msg1Count = res.data.result.total
+							this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+							for (let annItem of this.announcement1) {
+								this.msgList.push(annItem)
+							}
+						}
+						if (page.num == 1) {
+							this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+							this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+						}
+
+					}).catch(() => {
+						//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+						this.mescroll.endErr();
+					})
+				}
+			},
+
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+		},
+
+	}
+</script>
+
+<style>
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+
+
+
+	.content {
+		margin-top: 5px;
+	}
+
+	.content scroll-view {
+		scrollIndicator: "none"
+	}
+
+	.popupView {
+		margin-top: 45px;
+		height: auto;
+	}
+
+	.divider {
+		display: flex;
+		align-items: center;
+		text-align: center;
+		color: gray;
+		/* 鏂囧瓧棰滆壊 */
+		margin: 20px 0;
+		/* 涓婁笅闂磋窛 */
+	}
+
+	.divider::before,
+	.divider::after {
+		content: '';
+		flex: 1;
+		border-bottom: 1px solid gray;
+		/* 妯嚎棰滆壊 */
+		margin: 0 16px;
+		/* 妯嚎涓庢枃瀛椾箣闂寸殑闂磋窛 */
+	}
+
+	.divider text {
+		white-space: nowrap;
+		/* 闃叉鏂囧瓧鎹㈣ */
+	}
+
+	.overlay {
+		position: fixed;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		background-color: rgba(0, 0, 0, 0.7);
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		z-index: 999;
+	}
+
+	.modal {
+		position: relative;
+		width: 90%;
+		max-width: 600px;
+		background: #fff;
+		border-radius: 12rpx;
+		padding: 20rpx;
+		box-sizing: border-box;
+	}
+
+	.preview-image {
+		width: 100%;
+		max-height: 80vh;
+		object-fit: contain;
+	}
+
+	.close-btn {
+		position: absolute;
+		top: 10rpx;
+		right: 20rpx;
+		font-size: 40rpx;
+		color: #333;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/production/check/check.vue b/pages/eam/production/check/check.vue
new file mode 100644
index 0000000..d8dbb75
--- /dev/null
+++ b/pages/eam/production/check/check.vue
@@ -0,0 +1,355 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">榻愬妫�鏌�</block>
+
+		</cu-custom>
+
+
+		<view class="container">
+
+
+			<!-- 鍒楄〃淇℃伅寮�濮� -->
+			<view class="content" style="margin: 10px;">
+				<view class="check-list-container">
+					<view class="list-item" v-for="(item, index) in msgList" :key="index">
+						<!-- 閮ㄤ欢淇℃伅 -->
+						<view class="item-header">
+							<text class="part-code">{{ item.materialNumber }}</text>
+							<text class="warehouse-tag">{{ item.materialName }}</text>
+						</view>
+
+						<!-- 璇︾粏淇℃伅 -->
+						<view class="item-details">
+							<view class="detail-row">
+								<text class="label">闇�姹傛暟閲�:</text>
+								<view class="value editable">
+
+
+									<text>{{ item.requiredQuantity}}</text>
+
+								</view>
+							</view>
+
+							<view class="detail-row">
+								<text class="label">瀹為檯鏁伴噺:</text>
+								<view class="value editable">
+									<text>{{ item.actualQuantity}}</text>
+
+
+								</view>
+							</view>
+
+							<view class="detail-row">
+								<text class="label">鍩烘湰鍗曚綅:</text>
+								<text class="value">{{ item.productionUnit }}</text>
+							</view>
+
+							<view class="detail-row">
+								<text class="label">鏄惁榻愬:</text>
+								<text class="value" :class="{'warning-text': item.checkFlag === '0'}">鍚�</text>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="action-bar">
+				<button class="operation-btn" @click="handleLock">閿佸畾</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				scrollLeft: 0,
+				formData: {
+					num: '',
+					type: ''
+				},
+				NavBarColor: this.NavBarColor,
+				activeColor: '#5277A6',
+				url: {
+					stallList: "/mes/mesProductionWorkOrder/workOrderCompletenessCheck",
+					addBatch: '/mes/mesKittingCompletenessCheck/addBatch'
+				},
+
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10 // 姣忛〉鏁版嵁鐨勬暟閲�
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				typeList: [],
+				msgList: [], //鍒楄〃鏁版嵁
+				announcement1: [],
+				msg1Count: 0,
+				msg2Count: 0,
+				msg1Title: "",
+				workOrderId: ''
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 50
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+
+		onShow() {
+			if (this.mescroll) {
+				this.mescroll.resetUpScroll()
+			}
+		},
+		onLoad(options) {
+			// options 涓寘鍚烦杞椂鎼哄甫鐨勬墍鏈夊弬鏁�
+			if (options.id) {
+				this.workOrderId = options.id;
+				console.log('鎺ユ敹鐨勫伐鍗昳d:', this.workOrderId);
+
+				// 鍙湪姝ゅ璋冪敤鎺ュ彛锛屾牴鎹甶d鑾峰彇宸ュ崟璇︽儏
+				this.upCallback(this.workOrderId);
+			}
+		},
+		created() {
+
+		},
+		methods: {
+
+
+			upCallback() {
+				this.$http.get(this.url.stallList, {
+					params: {
+						id: this.workOrderId
+					},
+
+				}).then(res => {
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						this.msgList = res.data.result
+					}
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+
+				})
+
+			},
+
+
+
+			/**
+			 * 閿佸畾
+			 */
+			handleLock() {
+				
+
+				// 閬嶅巻 msgList 骞朵负姣忎釜 item 鐨� workOrderId 璁剧疆涓� currentRecordId
+				this.msgList.forEach(item => {
+					item.workOrderId = this.workOrderId;
+				});
+
+				this.$http.post(this.url.addBatch, this.msgList).then(res => {
+					console.log("url", res)
+					// 璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						uni.showToast({
+							icon: "success",
+							title: res.data.message,
+							duration: 2000
+						});
+						uni.navigateBack({
+							delta: 1
+						})
+					} else {
+						// 鍗充娇鏈嶅姟鍣ㄨ繑鍥炴垚鍔熷搷搴旓紝浣嗕笟鍔¢�昏緫澶辫触涔熻澶勭悊
+						uni.showToast({
+							icon: "none",
+							title: res.data.message || "鎿嶄綔澶辫触",
+							duration: 2000
+						});
+					}
+				}).catch(err => {
+					// 鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					uni.showToast({
+						icon: "exception",
+						title: "缃戠粶璇锋眰澶辫触",
+						duration: 2000
+					});
+					console.error("缃戠粶璇锋眰閿欒:", err);
+				})
+			},
+
+
+		},
+
+	}
+</script>
+
+<style>
+	/* 鍒楄〃瀹瑰櫒鏍峰紡 */
+	.check-list-container {
+		margin-bottom: 120rpx;
+		/* 涓哄簳閮ㄦ搷浣滄爮鐣欏嚭绌洪棿 */
+	}
+
+	/* 鍒楄〃椤规牱寮� */
+	.list-item {
+		background-color: #fff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+
+	/* 椤瑰ご閮ㄦ牱寮� */
+	.item-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 20rpx;
+		padding-bottom: 15rpx;
+		border-bottom: 1rpx solid #eee;
+	}
+
+	.part-code {
+		font-size: 32rpx;
+		font-weight: bold;
+		color: #333;
+	}
+
+	.warehouse-tag {
+		font-size: 24rpx;
+		color: #007AFF;
+		background-color: #e8f4ff;
+		padding: 6rpx 12rpx;
+		border-radius: 8rpx;
+	}
+
+	/* 璇︾粏淇℃伅鏍峰紡 */
+	.item-details {
+		margin-bottom: 20rpx;
+	}
+
+	.detail-row {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 15rpx;
+	}
+
+	.detail-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.label {
+		font-size: 28rpx;
+		color: #666;
+		flex: 1;
+	}
+
+	.value {
+		font-size: 28rpx;
+		color: #333;
+		flex: 1;
+		text-align: right;
+	}
+
+	.warning-text {
+		color: #ff6347;
+		font-weight: bold;
+	}
+
+	/* 鍙紪杈戞牱寮� */
+	.editable {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+	}
+
+	.edit-input {
+		border: 1rpx solid #007AFF;
+		border-radius: 8rpx;
+		padding: 10rpx;
+		width: 120rpx;
+		text-align: right;
+		font-size: 28rpx;
+	}
+
+	.edit-icon {
+		margin-left: 10rpx;
+		color: #007AFF;
+		font-size: 24rpx;
+	}
+
+	/* 鎿嶄綔鎸夐挳鏍峰紡 */
+	.item-actions {
+		display: flex;
+		justify-content: flex-end;
+		gap: 20rpx;
+	}
+
+	.action-btn {
+		padding: 12rpx 24rpx;
+		font-size: 13rpx;
+		border-radius: 8rpx;
+		border: none;
+		min-width: 60rpx;
+	}
+
+	.edit-btn {
+		background-color: #007AFF;
+		color: #fff;
+	}
+
+	.delete-btn {
+		background-color: #ff6347;
+		color: #fff;
+	}
+
+	/* 搴曢儴鎿嶄綔鏍忔牱寮� */
+	.action-bar {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #fff;
+		padding: 20rpx;
+		display: flex;
+		justify-content: space-around;
+		box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
+		z-index: 999;
+	}
+
+	.operation-btn {
+		padding: 20rpx 40rpx;
+		font-size: 22rpx;
+		border-radius: 12rpx;
+		background-color: #007AFF;
+		color: #fff;
+		border: none;
+		flex: 1;
+		margin: 0 10rpx;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/production/feed/feed.vue b/pages/eam/production/feed/feed.vue
new file mode 100644
index 0000000..c627499
--- /dev/null
+++ b/pages/eam/production/feed/feed.vue
@@ -0,0 +1,163 @@
+<template>
+	<view class="content">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">涓婃枡鎿嶄綔</block>
+		</cu-custom>
+
+		<view>
+			<uni-forms class='from' ref="form" :modelValue="scanData" validate-trigger="bind" err-show-type="undertext">
+				<uni-group>
+					<uni-forms-item name="feedNum"  :label-width="80"  label="浜岀淮鐮�:">
+						<uni-easyinput v-model="scanData.feedNum" type="text" placeholder="璇锋壂鎻忓崟鎹俊鎭�" suffixIcon="scan"
+							:disabled="true"/>
+					</uni-forms-item>
+					<uni-forms-item name="FactoryCode" :label-width="80" label="宸ュ巶缂栫爜:">
+						<uni-easyinput v-model="scanData.FactoryCode" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item name="SkuCode" :label-width="80" label="鐗╂枡缂栫爜:">
+						<uni-easyinput v-model="scanData.SkuCode" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item name="TrackLot" :label-width="80" label="鎵规鍙�:">
+						<uni-easyinput v-model="scanData.TrackLot" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item name="OrderCode" :label-width="80" label="璁㈠崟鍙�:">
+						<uni-easyinput v-model="scanData.OrderCode" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item name="Pallet"  :label-width="80" label="鎵樺彿:">
+						<uni-easyinput v-model="scanData.Pallet" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item name="Quantity" :label-width="80"  label="涓婃枡鏁伴噺:">
+						<uni-number-box v-model="scanData.Quantity" :min="0" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item name="feedPerson" :label-width="80" label="涓婃枡浜哄憳:">
+						<uni-data-select :localdata="feederLsit" @change="Handlefeeder" v-model="scanData.feedPerson" />
+					</uni-forms-item>
+
+				</uni-group>
+			</uni-forms>
+		</view>
+		<pdaScan></pdaScan>
+
+	</view>
+</template>
+
+<script>
+	import pdaScan from "@/components/mes/pdaScan.vue"
+	export default {
+		components: {
+			pdaScan
+		},
+		data() {
+			return {
+				feederLsit: [],
+				loading: false,
+				msgList1: [],
+				scanData: {
+					feedNum: '',
+					FactoryCode: '',
+					SkuCode: '',
+					TrackLot: '',
+					OrderCode: '',
+					Pallet: '',
+					Quantity: 0,
+					feedPerson: ''
+				},
+
+				isFirstScan: true,
+				lastScanInfo: null, // 娣诲姞涓�涓彉閲忔潵瀛樺偍涓婃鎵爜鐨勪俊鎭�
+				NavBarColor: this.NavBarColor,
+				url: {
+					getUser: 'sys/user/getUserById',
+					out: "/mom/partTakeRollingDetail/outstock"
+				},
+				msg1Count: ""
+
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 95
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+		onShow() {
+			let that = this
+			uni.$off('scancodedate') // 姣忔杩涙潵鍏� 绉婚櫎鍏ㄥ眬鑷畾涔変簨浠剁洃鍚櫒
+			uni.$on('scancodedate', function(data) {
+				console.log(data.code)
+				let str = data.code;
+				that.scanData.feedNum = str;
+				// 瑙f瀽鎵爜鏁版嵁
+				const pairs = str.split('#');
+				const result = {};
+				pairs.forEach(pair => {
+					const [key, value] = pair.split('=');
+					if (key && value !== undefined) {
+						result[key] = value;
+					}
+				});
+
+				// 灏嗚В鏋愮粨鏋滆祴鍊肩粰scanData瀵硅薄
+				that.scanData.FactoryCode = result.FactoryCode || '';
+				that.scanData.SkuCode = result.SkuCode || '';
+				that.scanData.TrackLot = result.TrackLot || '';
+				that.scanData.OrderCode = result.OrderCode || '';
+				that.scanData.Pallet = result.Pallet || '';
+				that.scanData.Quantity = result.Quantity ? parseInt(result.Quantity) : 0;
+			})
+		},
+		created() {
+			this.scanData.sponsor = uni.getStorageSync("userName");
+		},
+		methods: {
+			Handlefeeder(e) {
+				console.log(e)
+			}
+		},
+	}
+</script>
+
+<style>
+	.titles {
+		margin-left: 10px;
+	}
+
+	.first_tab {
+		background-color: #fff;
+		border-radius: 10rpx;
+		box-shadow: 2rpx 2rpx 2rpx 2rpx #eeeeee;
+		border: 2rpx solid #ccc;
+		width: 100%-40rpx;
+		margin: 10px;
+		padding: 5px;
+	}
+
+	/deep/.uni-numbox__value {
+		width: 80px;
+	}
+
+	/deep/ .is-disabled {
+		color: black !important;
+	}
+
+	/deep/.uni-easyinput__content-textarea {
+		position: relative;
+		overflow: hidden;
+		flex: 1;
+		line-height: 1.5;
+		font-size: 14px;
+		padding-top: 6px;
+		padding-bottom: 10px;
+		height: 20px;
+		/* #ifndef APP-NVUE */
+		min-height: 20px;
+		width: auto;
+		/* #endif */
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/production/materialLoading/materialLoading.vue b/pages/eam/production/materialLoading/materialLoading.vue
new file mode 100644
index 0000000..5772e72
--- /dev/null
+++ b/pages/eam/production/materialLoading/materialLoading.vue
@@ -0,0 +1,443 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">涓婃枡</block>
+		</cu-custom>
+
+		<!-- 楠ㄦ灦灞� -->
+		<view v-if="loading" class="skeleton-container">
+			<view class="skeleton-group">
+				<view class="skeleton-divider"></view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+			</view>
+			<view class="skeleton-button"></view>
+		</view>
+
+		<!-- 瀹為檯鍐呭 -->
+		<view v-else class="container">
+			<uni-forms ref="form" :modelValue="formData" :rules="formRules" validate-trigger="bind"
+				err-show-type="undertext">
+				<uni-group top="1">
+					<view class="divider"><text>涓婃枡淇℃伅</text></view>
+					<uni-forms-item :required="true" :label-width="80" name="workOrderNumber" label="鐗╂枡缂栫爜:">
+						<uni-easyinput v-model="formData.workOrderNumber" :disabled="isScan" placeholder="璇疯緭鍏�/鎵爜璇嗗埆"
+							@blur="handleInputComplete" />
+					</uni-forms-item>
+					<uni-forms-item :required="true" :label-width="80" name="materialCode" label="鐗╂枡鍚嶇О:">
+						<uni-easyinput v-model="formData.materialCode" placeholder="璇疯緭鍏�/鎵爜璇嗗埆" />
+					</uni-forms-item>
+
+					<uni-forms-item :required="true" :label-width="80" name="materialDescription" label="鎵规鍙� :">
+						<uni-easyinput v-model="formData.materialDescription" placeholder="璇疯緭鍏�/鎵爜璇嗗埆" />
+					</uni-forms-item>
+					<uni-forms-item :required="true" :label-width="80" name="plannedQuantity" label="鏁伴噺:">
+						<uni-easyinput v-model="formData.plannedQuantity" placeholder="璇疯緭鍏�/鎵爜璇嗗埆" />
+					</uni-forms-item>
+					<uni-forms-item :required="true" :label-width="80" name="plannedQuantity" label="灏哄:">
+						<uni-easyinput v-model="formData.plannedQuantity" placeholder="璇疯緭鍏�/鎵爜璇嗗埆" />
+					</uni-forms-item>
+
+
+
+				</uni-group>
+			</uni-forms>
+
+			<view class="padding flex flex-direction">
+				<view class="flex-sub bg-blue padding-sm margin-xl radius text-sm text-center text-white"
+					@click.stop="ProductionTask()" hover-class="is-hover">纭畾</view>
+			</view>
+		</view>
+
+		<pdaScanVue></pdaScanVue>
+	</view>
+</template>
+
+<script>
+	import pdaScanVue from "@/components/mes/pdaScan.vue";
+	import QRCode from 'qrcode';
+
+	export default {
+		components: {
+			pdaScanVue
+		},
+		data() {
+			return {
+				isScan: false,
+				loading: true,
+				isShow: false,
+				isSubmitting: false, // 闃查噸澶嶆彁浜�
+				SpareList: [{
+						text: "鏄�",
+						value: 1
+					},
+					{
+						text: "鍚�",
+						value: 0
+					}
+				],
+				scrollLeft: 0,
+				formData: {
+					workOrderNumber: '',
+					materialCode: '',
+					materialDescription: '',
+					plannedQuantity: '',
+				},
+				formRules: {
+					workOrderNumber: [{
+							required: true,
+							message: '璇疯緭鍏ョ墿鏂欑紪鐮�',
+							trigger: 'blur'
+						},
+						{
+							pattern: /^[A-Za-z0-9]{6,20}$/, // 绀轰緥锛氫粎鍏佽6-20浣嶅瓧姣�/鏁板瓧
+							message: '鐗╂枡缂栫爜闇�涓�6-20浣嶅瓧姣嶆垨鏁板瓧',
+							trigger: 'blur'
+						}
+					]
+				},
+				NavBarColor: this.NavBarColor,
+				url: {
+					upload: "/eam/sysFiles/batch_upload",
+					stallList: "/eam/eamRepairOrder/queryById",
+					getEquipmentList: 'eam/equipment/list',
+					approval: '/eam/eamRepairOrder/perform'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				msg1Count: 0
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 160
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+		onShow() {
+			var that = this
+			uni.$off('scancodedate') // 姣忔杩涙潵鍏� 绉婚櫎鍏ㄥ眬鑷畾涔変簨浠剁洃鍚櫒  
+			uni.$on('scancodedate', function(data) {
+				that.isScan = true
+				console.log(data.code)
+				let code = data.code;
+				/**
+				 * 鑾峰彇鐗╂枡绫诲瀷
+				 */
+				that.sacanHandel(code)
+			})
+
+		},
+		created() {
+			this.loading = false;
+		},
+		methods: {
+			sacanHandel(code) {
+				this.$http.get(this.url.approval).then(res => {
+					if (res.data.success) {
+						console.log("res", res.data)
+						/**
+						 * 鍒ゆ柇鐗╂枡绫诲瀷
+						 * 缁檉rom琛ㄥ崟璧嬪��
+						 * 淇濆瓨搴撳瓨淇℃伅搴撳瓨id
+						 * 鏍规嵁鐗╂枡绫诲瀷鏄惁鏄剧ず鐗规畩灞炴��
+						 */
+					}
+				}).catch(() => {
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+			},
+			// 鐗╂枡缂栫爜杈撳叆瀹屾垚锛堝け鍘荤劍鐐癸級瑙﹀彂鐨勯�昏緫
+			handleInputComplete() {
+				// 1. 寮哄埗鍘婚櫎杈撳叆鍊煎墠鍚庢墍鏈夌┖鏍硷紙鍖呮嫭澶氫釜绌烘牸銆佸叏瑙掔┖鏍硷級
+				const rawValue = this.formData.workOrderNumber || '';
+				const materialCode = rawValue.replace(/\s+/g, ''); // 鐢ㄦ鍒欏幓闄ゆ墍鏈夌┖鐧藉瓧绗︼紙绌烘牸銆佹崲琛岀瓑锛�
+
+				// 2. 鏃犳晥鍊兼嫤鎴細鍘荤┖鏍煎悗涓虹┖ 鈫� 鐩存帴鎻愮ず锛屼笉瑙﹀彂鍚庣画閫昏緫
+				if (!materialCode) {
+					uni.showToast({
+						title: '璇疯緭鍏ユ湁鏁堢殑鐗╂枡缂栫爜锛堜笉鑳戒负绌猴級',
+						icon: 'none',
+						duration: 1500
+					});
+					// 鍙�夛細娓呯┖杈撳叆妗嗙殑绾┖鏍煎唴瀹癸紝閬垮厤鐢ㄦ埛璇互涓鸿緭鍏ユ湁鏁�
+					this.formData.workOrderNumber = '';
+					return; // 缁堟鍚庣画娴佺▼
+				}
+
+				// 3. 鏃犳晥鍊煎凡鎺掗櫎锛屾洿鏂拌〃鍗曞�间负鍘荤┖鏍煎悗鐨勬湁鏁堝唴瀹癸紙淇濇寔琛ㄥ崟鏄剧ず鏁存磥锛�
+				this.formData.workOrderNumber = materialCode;
+				console.log('褰撳墠鏈夋晥鐗╂枡缂栫爜:', materialCode);
+
+				// 4. 鎵ц鍘熸湁鏍¢獙锛堟牸寮忔槸鍚︾鍚�6-20浣嶅瓧姣�/鏁板瓧锛�
+				this.$refs.form.validateField('workOrderNumber', (errorMsg, isValid) => {
+					console.log('鏍煎紡鏍¢獙缁撴灉:', isValid ? '閫氳繃' : '澶辫触', '閿欒淇℃伅:', errorMsg);
+
+					if (isValid) {
+						// 5. 鏍¢獙閫氳繃 鈫� 瑙﹀彂鎺ュ彛鏌ヨ
+						this.requestMaterialInfo(materialCode);
+					} else if (errorMsg) {
+						// 鏍煎紡鏍¢獙澶辫触 鈫� 鎻愮ず鍏蜂綋閿欒锛堝鈥滈渶6-20浣嶅瓧姣�/鏁板瓧鈥濓級
+						uni.showToast({
+							title: errorMsg,
+							icon: 'none',
+							duration: 1500
+						});
+					}
+				});
+			},
+			requestMaterialInfo(materialCode) {
+				console.log("鎴戞墽琛屼簡")
+				uni.showLoading({
+					title: '鏌ヨ涓�...'
+				})
+				this.$http.get(this.url.approval).then(res => {
+					if (res.data.success) {
+						console.log("res", res.data)
+						/**
+						 * 鍒ゆ柇鐗╂枡绫诲瀷
+						 * 缁檉rom琛ㄥ崟璧嬪��
+						 * 淇濆瓨搴撳瓨淇℃伅搴撳瓨id
+						 * 鏍规嵁鐗╂枡绫诲瀷鏄惁鏄剧ず鐗规畩灞炴��
+						 */
+					}
+				}).catch(() => {
+					uni.hideLoading();
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+			},
+			async ProductionTask() {
+				// 闃叉閲嶅鎻愪氦
+				if (this.isSubmitting) {
+					uni.showToast({
+						icon: "none",
+						title: "姝e湪鎻愪氦涓紝璇峰嬁閲嶅鐐瑰嚮",
+						duration: 2000
+					});
+					return;
+				}
+
+				uni.showLoading({
+					mask: true,
+					title: "鎻愪氦涓�..."
+				});
+
+				try {
+					this.isSubmitting = true;
+					// 鍙戦�佹姤宸ヨ姹�
+					const response = await this.$http.post(this.url.approval, {
+						workOrderNumber: this.formData.workOrderNumber,
+						materialCode: this.formData.materialCode,
+
+						plannedQuantity: this.formData.plannedQuantity,
+						inspectionOrderNumber: this.formData.inspectionOrderNumber,
+
+					});
+
+					if (response.data.success) {
+						uni.showToast({
+							icon: "success",
+							title: '鎻愪氦鎴愬姛',
+							duration: 2000
+						});
+
+						// 寤惰繜璺宠浆
+						await new Promise(resolve => setTimeout(resolve, 2000));
+
+						this.$Router.replaceAll({
+							name: 'qualityInspection'
+						});
+					} else {
+						uni.showModal({
+							title: "鎻愪氦澶辫触",
+							content: response.data.message || "鏈嶅姟鍣ㄥ鐞嗗け璐ワ紝璇风◢鍚庨噸璇�",
+							confirmText: '纭畾',
+							showCancel: false,
+							icon: "none"
+						});
+					}
+				} catch (error) {
+					// 閿欒澶勭悊
+					if (error.errMsg) {
+						uni.showToast({
+							icon: "none",
+							title: error,
+							duration: 2000
+						});
+					} else {
+						console.error("璇锋眰澶辫触:", error);
+						let errorMessage = "缃戠粶璇锋眰澶辫触";
+						if (error.errMsg) {
+							if (error.errMsg.includes("timeout")) {
+								errorMessage = "璇锋眰瓒呮椂锛岃妫�鏌ョ綉缁滆繛鎺�";
+							} else if (error.errMsg.includes("fail")) {
+								errorMessage = "缃戠粶杩炴帴澶辫触锛岃妫�鏌ョ綉缁滆缃�";
+							}
+						}
+						uni.showToast({
+							icon: "none",
+							title: errorMessage,
+							duration: 3000
+						});
+					}
+				} finally {
+					this.isSubmitting = false;
+					uni.hideLoading();
+				}
+			},
+		}
+	}
+</script>
+
+<style>
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+
+	.divider {
+		display: flex;
+		font-weight: bold;
+		align-items: center;
+		text-align: center;
+		color: #1E90FF;
+		font-size: 24rpx;
+		margin: 20px 0;
+	}
+
+	.divider::before,
+	.divider::after {
+		content: '';
+		flex: 1;
+		border-bottom: 1px solid gray;
+		margin: 0 16px;
+	}
+
+	.divider text {
+		white-space: nowrap;
+	}
+
+	.content {
+		margin-top: 5px;
+	}
+
+	.content scroll-view {
+		scrollIndicator: "none"
+	}
+
+	.popupView {
+		margin-top: 45px;
+		height: auto;
+	}
+
+	/* 楠ㄦ灦灞忔牱寮� */
+	.skeleton-container {
+		padding: 20rpx;
+	}
+
+	.skeleton-group {
+		margin-bottom: 40rpx;
+	}
+
+	.skeleton-divider {
+		height: 40rpx;
+		width: 300rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-bottom: 30rpx;
+	}
+
+	.skeleton-item {
+		display: flex;
+		align-items: center;
+		margin-bottom: 30rpx;
+	}
+
+	.skeleton-label {
+		width: 160rpx;
+		height: 40rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-right: 20rpx;
+	}
+
+	.skeleton-input {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+
+	.skeleton-select {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+
+	.skeleton-datetime {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+
+	.skeleton-button {
+		width: 90%;
+		height: 80rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 10rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin: 40rpx auto;
+	}
+
+	@keyframes skeleton-loading {
+		0% {
+			background-position: 100% 50%;
+		}
+
+		100% {
+			background-position: 0 50%;
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/production/partBlanking/partBlanking.vue b/pages/eam/production/partBlanking/partBlanking.vue
new file mode 100644
index 0000000..8183fd0
--- /dev/null
+++ b/pages/eam/production/partBlanking/partBlanking.vue
@@ -0,0 +1,22 @@
+<template>
+	<view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style>
+
+</style>
diff --git a/pages/eam/production/process/process.vue b/pages/eam/production/process/process.vue
new file mode 100644
index 0000000..96ae12f
--- /dev/null
+++ b/pages/eam/production/process/process.vue
@@ -0,0 +1,368 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">宸ヨ壓鐐规</block>
+
+		</cu-custom>
+
+
+		<view class="container">
+
+			<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+				<!-- 鍒楄〃淇℃伅寮�濮� -->
+				<view class="content" style="margin: 10px;">
+					<view class="check-list-container">
+						<view class="list-item" v-for="(item, index) in checkList" :key="index">
+							<!-- 閮ㄤ欢淇℃伅 -->
+
+
+							<!-- 璇︾粏淇℃伅 -->
+							<view class="item-details">
+								<view class="detail-row">
+									<text class="label">宸ヨ壓鍙傛暟缂栧彿:</text>
+									<text class="value">{{ item.paramCode}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">宸ヨ壓鍙傛暟:</text>
+									<text class="value">{{ item.paramName }}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鍚堟牸鑼冨洿:</text>
+									<text class="value">{{ item.availableQty }}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鍙傛暟鍊�:</text>
+									<text class="value"
+										:class="{'warning-text': item.remainQty < 0}">{{ item.paramValue }}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">鍒ゅ畾:</text>
+									<text class="value"
+										:class="{'warning-text': item.remainQty < 0}">{{ item.judgment }}</text>
+								</view>
+							</view>
+
+
+						</view>
+					</view>
+					<!-- 搴曢儴鎿嶄綔鏍� -->
+					<view class="action-bar">
+						<button class="operation-btn" @click="handleLock">纭畾</button>
+						<button class="operation-btn" @click="handleNotice">鍙栨秷</button>
+					</view>
+				</view>
+			</mescroll-uni>
+		</view>
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				checkList: [{
+						paramCode: '001',
+						paramName: '杞��',
+						validRange: '',
+						paramValue: '',
+						judgment: '鍚堟牸'
+					},
+					{
+						paramCode: '002',
+						paramName: '杩涚粰',
+						validRange: '',
+						paramValue: '',
+						judgment: '鍚堟牸'
+					},
+					{
+						paramCode: '003',
+						paramName: '鍚冨垁閲�',
+						validRange: '',
+						paramValue: '',
+						judgment: '鍚堟牸'
+					},
+					{
+						paramCode: '004',
+						paramName: '鍊嶇巼',
+						validRange: '',
+						paramValue: '',
+						judgment: '鍚堟牸'
+					}
+				],
+				scrollLeft: 0,
+				formData: {
+					num: '',
+					type: ''
+				},
+				NavBarColor: this.NavBarColor,
+				activeColor: '#5277A6',
+				url: {
+					flowType: "/sys/dict/getDictItems/flow_type",
+					stallList: "/assign/flow/toTaskBySelf"
+				},
+
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10 // 姣忛〉鏁版嵁鐨勬暟閲�
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				typeList: [],
+				msgList: [], //鍒楄〃鏁版嵁
+				announcement1: [],
+				msg1Count: 0,
+				msg2Count: 0,
+				msg1Title: ""
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 50
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+
+		onShow() {
+			if (this.mescroll) {
+				this.mescroll.resetUpScroll()
+			}
+		},
+
+		created() {},
+		methods: {
+			upCallback(page) {
+				this.$http.get(this.url.stallList, {
+					params: {
+						pageNo: page.num,
+						pageSize: page.size,
+						order: 'desc',
+						column: 'createTime'
+					},
+				}).then(res => {
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+				})
+
+			},
+
+
+
+
+
+
+
+
+
+			// 閿佸畾鎿嶄綔
+			handleLock() {
+				uni.showToast({
+					title: '鎿嶄綔鎵ц涓�...',
+					icon: 'loading'
+				});
+
+				uni.navigateBack(1);
+
+			},
+
+			// 閫氱煡棰嗘枡鎿嶄綔
+			handleNotice() {
+				uni.navigateBack(1);
+			},
+
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+		},
+
+	}
+</script>
+
+<style>
+	/* 鍒楄〃瀹瑰櫒鏍峰紡 */
+	.check-list-container {
+		margin-bottom: 120rpx;
+		/* 涓哄簳閮ㄦ搷浣滄爮鐣欏嚭绌洪棿 */
+	}
+
+	/* 鍒楄〃椤规牱寮� */
+	.list-item {
+		background-color: #fff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+
+	/* 椤瑰ご閮ㄦ牱寮� */
+	.item-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 20rpx;
+		padding-bottom: 15rpx;
+		border-bottom: 1rpx solid #eee;
+	}
+
+	.part-code {
+		font-size: 32rpx;
+		font-weight: bold;
+		color: #333;
+	}
+
+	.warehouse-tag {
+		font-size: 24rpx;
+		color: #007AFF;
+		background-color: #e8f4ff;
+		padding: 6rpx 12rpx;
+		border-radius: 8rpx;
+	}
+
+	/* 璇︾粏淇℃伅鏍峰紡 */
+	.item-details {
+		margin-bottom: 20rpx;
+	}
+
+	.detail-row {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 15rpx;
+	}
+
+	.detail-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.label {
+		font-size: 28rpx;
+		color: #666;
+		flex: 1;
+	}
+
+	.value {
+		font-size: 28rpx;
+		color: #333;
+		flex: 1;
+		text-align: right;
+	}
+
+	.warning-text {
+		color: #ff6347;
+		font-weight: bold;
+	}
+
+	/* 鍙紪杈戞牱寮� */
+	.editable {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+	}
+
+	.edit-input {
+		border: 1rpx solid #007AFF;
+		border-radius: 8rpx;
+		padding: 10rpx;
+		width: 120rpx;
+		text-align: right;
+		font-size: 28rpx;
+	}
+
+	.edit-icon {
+		margin-left: 10rpx;
+		color: #007AFF;
+		font-size: 24rpx;
+	}
+
+	/* 鎿嶄綔鎸夐挳鏍峰紡 */
+	.item-actions {
+		display: flex;
+		justify-content: flex-end;
+		gap: 20rpx;
+	}
+
+	.action-btn {
+		padding: 12rpx 24rpx;
+		font-size: 13rpx;
+		border-radius: 8rpx;
+		border: none;
+		min-width: 60rpx;
+	}
+
+	.edit-btn {
+		background-color: #007AFF;
+		color: #fff;
+	}
+
+	.delete-btn {
+		background-color: #ff6347;
+		color: #fff;
+	}
+
+	/* 搴曢儴鎿嶄綔鏍忔牱寮� */
+	.action-bar {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #fff;
+		padding: 20rpx;
+		display: flex;
+		justify-content: space-around;
+		box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
+		z-index: 999;
+	}
+
+	.operation-btn {
+		padding: 20rpx 40rpx;
+		font-size: 22rpx;
+		border-radius: 12rpx;
+		background-color: #007AFF;
+		color: #fff;
+		border: none;
+		flex: 1;
+		margin: 0 10rpx;
+	}
+</style>
diff --git a/pages/eam/production/record/record.vue b/pages/eam/production/record/record.vue
new file mode 100644
index 0000000..69f8cc4
--- /dev/null
+++ b/pages/eam/production/record/record.vue
@@ -0,0 +1,876 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">鎿嶄綔璁板綍</block>
+		</cu-custom>
+		<view class="container">
+			<view class="solid-bottom">
+				<scroll-view scroll-x class="bg-white nav text-center ">
+					<!-- <view class="flex text-center justify-around"> -->
+					<view class="cu-item" :class="item.value==TabCur?'text-blue cur':''" v-for="(item,index) in tabs"
+						:key="index" @tap="tabSelect" :data-id="item.value">
+						{{item.title}}
+					</view>
+				</scroll-view>
+			</view>
+
+
+			<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+				<view class="production-container">
+					<teleport v-if="TabCur==0">
+						<view class="list-item" v-for="(item, index) in mockBillList" :key="index">
+							<!-- 榻愬妫�鏌� -->
+							<view class="item-details">
+								<view class="detail-row">
+									<text class="label">宸ュ崟鍙�:</text>
+									<text class="value">{{item.workOrderCode}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鐗╂枡缂栧彿:</text>
+									<text class="value">{{item.materialNumber}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鐗╂枡鍚嶇О:</text>
+									<text class="value">{{item.materialName}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">闇�姹傛暟閲�:</text>
+									<text class="value" style="color: #00FF00;">
+										{{item.requiredQuantity}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">瀹為檯鏁伴噺:</text>
+									<text class="value" style="color: #00FF00;">{{item.actualQuantity}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">鏄惁榻愬:</text>
+									<text class="value" v-if="item.checkFlag==='0'" style="color: red;">鍚�</text>
+									<text class="value" v-else style="color: red;">鏄�</text>
+								</view>
+							</view>
+						</view>
+					</teleport>
+
+
+					<teleport v-if="TabCur==1">
+						<view class="list-item" v-for="(item, index) in checkList" :key="index">
+							<!-- 榻愬妫�鏌� -->
+							<view class="item-details">
+								<view class="detail-row">
+									<text class="label">宸ヨ壓鍙傛暟缂栧彿:</text>
+									<text class="value">{{ item.paramCode}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">宸ヨ壓鍙傛暟:</text>
+									<text class="value">{{ item.paramName}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鍚堟牸鑼冨洿:</text>
+									<text class="value">{{ item.availableQty}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鍙傛暟鍊�:</text>
+									<text class="value">{{ item.paramValue}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">鍒ゅ畾:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+							</view>
+						</view>
+					</teleport>
+
+
+
+					<teleport v-if="TabCur==2">
+						<view class="container">
+							<!-- 娴獥閬僵灞� -->
+							<view v-if="showPreview" class="overlay" @tap.stop="closePreview">
+								<view class="modal">
+									<!-- 鍏抽棴鎸夐挳 -->
+									<text class="close-btn" @tap.stop="showPreview = false">&times;</text>
+									<!-- 鍥剧墖灞曠ず -->
+									<image :src="previewImageSrc" mode="aspectFit" class="preview-image"
+										@error="handleImageError" :show-menu-by-longpress="false" />
+								</view>
+							</view>
+							<uni-forms ref="form" :modelValue="formData" validate-trigger="bind"
+								err-show-type="undertext">
+								<uni-group top="1">
+									<view class="divider"><text>鍩烘湰淇℃伅</text></view>
+									<!-- <view class="text-gray margin-bottom-lg">鈥斺�斺�斺�斺�斺�斺�斺�斺�斺�� 鍩烘湰淇℃伅 鈥斺�斺�斺�斺�斺�斺�斺�斺�斺��</view> -->
+									<uni-forms-item :label-width="80" name="num" label="宸ュ崟鍙�:">
+										<uni-easyinput v-model="formData.orderNum" :disabled="true" />
+									</uni-forms-item>
+									<uni-forms-item :label-width="80" name="num" label="璁惧缂栧彿:">
+										<uni-easyinput v-model="formData.num" :disabled="true" />
+									</uni-forms-item>
+
+									<uni-forms-item :label-width="80" name="remark" label="鐐规鏃ユ湡:">
+										<uni-easyinput v-model="formData.inspectionDate" :disabled="true" />
+									</uni-forms-item>
+									<uni-forms-item :label-width="80" name="outNum" label="鐐规浜�:">
+										<uni-easyinput v-model="formData.operator" :disabled="true" />
+									</uni-forms-item>
+
+									<uni-forms-item :label-width="80" name="formData.remark" label="澶囨敞:">
+										<uni-easyinput v-model="formData.remark" :disabled="true" />
+									</uni-forms-item>
+									<uni-forms-item :label-width="80" name="outNum" label="鐐规鍥剧墖:">
+										<uni-file-picker limit="9" :value="fileLists" :image-styles="imageStyles"
+											:sourceType="sourceType" @select="select" @progress="progress"
+											@success="success" @fail="fail" @delete="deletea" :readonly="readonly" />
+									</uni-forms-item>
+									<uni-forms-item name="outNum" :label-width="80" label="浣滀笟鎸囧:">
+										<button class="cu-btn  bg-blue" @tap="showPreview = true">鏌ョ湅</button>
+									</uni-forms-item>
+								</uni-group>
+							</uni-forms>
+
+							<!-- <view class="text-gray margin-bottom-lg">鈥斺�斺�斺�斺�斺�斺�斺�斺�斺�� 淇濆吇椤逛俊鎭� 鈥斺�斺�斺�斺�斺�斺�斺�斺�斺��</view> -->
+							<view class="divider"><text>淇濆吇椤逛俊鎭�</text></view>
+							<uni-collapse>
+								<uni-collapse-item :show-animation="true" :accordion="true" title="鏌ョ湅淇濆吇椤�"
+									:border="false" title-border="none">
+									<uni-card margin="10px" spacing="1px"
+										v-for="(item,index) in partTakeAdviceDetailList" :key="index">
+
+
+										<view class="flex">
+											<view class="flex-sub text-light bg-white padding-xs margin-xs radius">琛屽彿:
+											</view>
+											<view class="flex-sub bg-white padding-xs margin-xs radius text-right">
+												{{index+1}}
+											</view>
+										</view>
+										<view class="flex">
+											<view class="flex-sub text-light bg-white padding-xs margin-xs radius">淇濆吇椤�:
+											</view>
+											<view
+												class="flex-sub bg-white padding-xs margin-xs text-bold radius text-right">
+												{{item.itemName}}
+											</view>
+										</view>
+
+										<view class="flex">
+											<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">
+												淇濆吇瑕佹眰:
+											</view>
+											<view class="flex-sub bg-white padding-xs margin-xs radius text-right">
+												{{item.itemDemand}}
+											</view>
+										</view>
+										<view class="flex">
+											<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">
+												鐐规缁撴灉:
+											</view>
+											<view class="flex-sub bg-white padding-xs     text-right margin-xs radius">
+												<uni-data-select :localdata="item.restle"
+													v-model="item.inspectionResult" @change="handleCode($event, index)"
+													:disabled="item.istrue" />
+											</view>
+										</view>
+										<view class="flex">
+											<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">
+												寮傚父鏄惁鎶ヤ慨:
+											</view>
+											<view class="flex-sub bg-white padding-xs     text-right margin-xs radius">
+												<uni-data-select :localdata="item.type"
+													@change="handleType($event, index)" v-model="item.reportFlag"
+													:disabled="item.istrue" />
+											</view>
+										</view>
+
+
+										<view class="flex">
+											<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">
+												寮傚父鎻忚堪:
+											</view>
+											<view class="flex-sub bg-white padding-xs     text-right margin-xs radius">
+												<uni-easyinput v-model="item.exceptionDescription"
+													:disabled="item.istrue" />
+											</view>
+										</view>
+									</uni-card>
+								</uni-collapse-item>
+							</uni-collapse>
+
+
+							<view class="padding flex flex-direction">
+								<view
+									class="flex-sub bg-blue padding-sm margin-xl radius text-sm text-center text-white"
+									@click.stop="ProductionTask()" hover-class="is-hover">纭畾</view>
+							</view>
+						</view>
+					</teleport>
+
+
+
+
+					<teleport v-if="TabCur==3">
+						<view class="container">
+							<uni-forms ref="form" :modelValue="formData" validate-trigger="bind"
+								err-show-type="undertext">
+								<uni-group top="1">
+									<uni-forms-item :label-width="100" name="remark" label="鏂囦欢鍚嶇О:">
+										<uni-easyinput v-model="formData.equipmentName" />
+									</uni-forms-item>
+									<uni-forms-item :label-width="100" name="outNum" label="璁惧鏂囨。:">
+										<uni-file-picker v-model="fileLists" :extension="['.pdf']" @fail="uploadFail"
+											:list-styles="listStyles" :delIcon="del" :max-count="5" file-mediatype="all"
+											@downloadFile="downloadFile" @select="onFileSelect" @delete="onFileDelete">
+											<button size="mini" type="primary">鐐瑰嚮涓婁紶</button>
+										</uni-file-picker>
+									</uni-forms-item>
+									<!-- 鏂板锛氭牎楠岀粨鏋滃崟閫夋 -->
+									<uni-forms-item name="result" :label-width="100" label="妫�楠岀粨鏋�:">
+										<radio-group @change="radioChange">
+											<label style="margin-right: 20rpx;">
+												<radio :checked="formData.result=='qualified'" value="qualified" />鍚堟牸
+											</label>
+
+											<label style="margin-right: 20rpx;">
+												<radio :checked="formData.result=='unqualified'" value="unqualified" />
+												涓嶅悎鏍�
+											</label>
+										</radio-group>
+									</uni-forms-item>
+								</uni-group>
+							</uni-forms>
+
+							<view class="file-list margin-sm">
+								<view class="file-item" v-for="(file, index) in this.selectedFiles" :key="index">
+									<view class="file-icon">
+										<!-- 鏂囦欢鍥炬爣 -->
+										<image src="/static/icon_file.png"
+											style="height: 25px;  width: 25px; margin-right: 10px;" mode='aspectFit'
+											class="zai-logo "></image>
+									</view>
+									<view class="file-name">
+										<!-- 鏂囦欢鍚� -->
+										{{ file.fileName }}
+									</view>
+									<view class="file-actions">
+										<!-- 涓嬭浇鎸夐挳 -->
+										<image v-show="showBtn" src="/static/icon_down.png" @click="downloadFile(file)"
+											style="height: 25px;  width: 25px; margin-right: 10px;"></image>
+									</view>
+								</view>
+							</view>
+
+							<view class="padding flex flex-direction">
+								<view
+									class="flex-sub bg-blue padding-sm margin-xl radius text-sm text-center text-white"
+									@click.stop="ProductionTask()" hover-class="is-hover">纭畾</view>
+							</view>
+						</view>
+					</teleport>
+
+
+
+					<teleport v-if="TabCur==4">
+						<view class="list-item" v-for="(item, index) in checkList" :key="index">
+							<!-- 榻愬妫�鏌� -->
+							<view class="item-details">
+								<view class="detail-row">
+									<text class="label">鎵规鍙�:</text>
+									<text class="value">{{ item.paramCode}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鐗╂枡缂栫爜:</text>
+									<text class="value">{{ item.paramName}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鐗╂枡鎻忚堪:</text>
+									<text class="value">{{ item.availableQty}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">涓婃枡鏃堕棿:</text>
+									<text class="value">{{ item.paramValue}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">涓婃枡鏁伴噺:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">涓婃枡浜哄憳:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+							</view>
+						</view>
+					</teleport>
+
+
+					<!-- 琛ㄥご锛堝叡鐢ㄦ牱寮忥級 -->
+
+
+				</view>
+			</mescroll-uni>
+		</view>
+	</view>
+</template>
+
+<script>
+	const tabs = [{
+			title: '榻愬妫�鏌�',
+			value: 0
+		}, {
+			title: '宸ヨ壓鐐规',
+			value: 1
+		},
+		{
+			title: '璁惧鐐规',
+			value: 2
+		},
+		{
+			title: '鏍蜂欢鏍¢獙',
+			value: 3
+		},
+		{
+			title: '涓婃枡璁板綍',
+			value: 4
+		}
+	];
+	import configService from "@/common/service/config.service.js";
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				mockBillList:[],
+				previewImageSrc: '',
+				ipAndPort: configService.staticURL,
+				fileLists: [],
+				// 涓婁紶鍥剧墖鐨勬牱寮�
+				imageStyles: {
+					width: 90,
+					height: 90,
+				},
+				sourceType: ['album', 'camera'],
+				ScanData: {
+					typeName: '',
+					handlingType: [{
+							text: "閫氳繃",
+							value: "1"
+						},
+						{
+							text: "椹冲洖",
+							value: "2"
+						}
+					],
+					handlingSuggestion: ''
+				},
+				formData: {
+					num: '',
+					avatar: [],
+					orderNum: '',
+					operator: '',
+					inspectionDate: ''
+
+				},
+				checkList: [{
+						paramCode: '001',
+						paramName: '杞��',
+						validRange: '',
+						paramValue: '',
+						judgment: '鍚堟牸'
+					},
+					{
+						paramCode: '002',
+						paramName: '杩涚粰',
+						validRange: '',
+						paramValue: '',
+						judgment: '鍚堟牸'
+					},
+					{
+						paramCode: '003',
+						paramName: '鍚冨垁閲�',
+						validRange: '',
+						paramValue: '',
+						judgment: '鍚堟牸'
+					},
+					{
+						paramCode: '004',
+						paramName: '鍊嶇巼',
+						validRange: '',
+						paramValue: '',
+						judgment: '鍚堟牸'
+					}
+				],
+				tabs,
+				TabCur: 0,
+				scrollLeft: 0,
+				NavBarColor: this.NavBarColor,
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10, // 姣忛〉鏁版嵁鐨勬暟閲�
+
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				url: {
+					upload: "/eam/sysFiles/batch_upload",
+					delete: "/pm/arrivalAdvice/delete",
+					sub: "/pm/arrivalAdvice/issue",
+					list: "/pm/arrivalAdvice/list",
+					sub1:'mes/mesKittingCompletenessCheck/queryCompletenessCheckByWorkOrderId' 
+				},
+				placeholderStyle: "color:#2979FF;font-size:14px",
+				current: 0,
+				colorIndex: 0,
+				activeColor: '#5277A6',
+				msgList: [], //鍒楄〃鏁版嵁
+				announcementList: [],
+			}
+		},
+
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 100
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+
+		methods: {
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+
+			upCallback() {
+				//鑱旂綉鍔犺浇鏁版嵁
+				console.log("tabindex", this.TabCur)
+				let keyword = this.TabCur
+				if (keyword == 0) {
+					this.$http.get(this.url.sub1, {
+						params: {
+							workOrderId:"1960585092127371266"
+							
+						}
+					}).then(res => {
+						//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+						this.announcement1 = res.data.result.records
+						if (res.data.success) {
+							this.mockBillList=res.data.result
+						}
+					}).catch(() => {
+						//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					})
+				} else if (keyword == 1) {
+					this.$http.get(this.url.list, {
+						params: {
+							pageSize: page.size,
+							order: "desc",
+							column: "createTime",
+							type: 2,
+							status: 1
+						}
+					}).then(res => {
+						//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+						this.announcement2 = res.data.result.records
+						this.mescroll.endSuccess(this.announcement2.length, this.msgCount);
+
+						//璁剧疆鍒楄〃鏁版嵁
+						if (res.data.success) {
+							console.log("res sys", res.data)
+							this.msg2Count = res.data.result.total
+							this.msg2Title = "閫氱煡(" + res.data.result.total + ")";
+
+							for (let item of this.announcement2) {
+								this.msgList.push(item)
+							}
+						}
+						if (page.num == 1) {
+							this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+							this.msgList = this.msgList.concat(this.announcement2); //杩藉姞鏂版暟鎹�
+						}
+					}).catch(() => {
+						//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					})
+				} else if (keyword == 2) {
+
+					this.$http.get(this.url.list, {
+						params: {
+							pageSize: page.size,
+							order: "desc",
+							column: "createTime",
+							type: 2,
+							status: 2
+						}
+					}).then(res => {
+						//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+						this.announcement2 = res.data.result.records
+						this.mescroll.endSuccess(this.announcement2.length, this.msgCount);
+
+						//璁剧疆鍒楄〃鏁版嵁
+						if (res.data.success) {
+							console.log("res sys", res.data)
+							this.msg2Count = res.data.result.total
+							this.msg2Title = "閫氱煡(" + res.data.result.total + ")";
+
+							for (let item of this.announcement2) {
+								this.msgList.push(item)
+							}
+						}
+						if (page.num == 1) {
+							this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+							this.msgList = this.msgList.concat(this.announcement2); //杩藉姞鏂版暟鎹�
+						}
+					}).catch(() => {
+						//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					})
+
+				}
+
+			},
+			tabSelect(e) {
+				this.TabCur = e.currentTarget.dataset.id;
+				this.scrollLeft = (e.currentTarget.dataset.id - 1) * 60;
+				this.msgList = [] // 鍏堢疆绌哄垪琛�,鏄剧ず鍔犺浇杩涘害
+				this.mescroll.resetUpScroll() // 鍐嶅埛鏂板垪琛ㄦ暟鎹�
+			},
+
+
+
+			ListTouchStart(e) {
+				this.listTouchStart = e.touches[0].pageX
+			},
+
+			// ListTouch璁$畻鏂瑰悜
+			ListTouchMove(e) {
+				this.listTouchDirection = e.touches[0].pageX - this.listTouchStart > 0 ? 'right' : 'left'
+			},
+
+			// ListTouch璁$畻婊氬姩
+			ListTouchEnd(e) {
+				if (this.listTouchDirection == 'left') {
+					this.modalName = e.currentTarget.dataset.target
+				} else {
+					this.modalName = null
+				}
+				this.listTouchDirection = null
+			},
+
+			/**
+			 * 淇濆吇椤�
+			 */
+			getList() {
+				this.$http.get(this.url.BaoList, {
+					params: {
+						orderId: this.id
+					},
+
+				}).then(res => {
+					this.partTakeAdviceDetailList = res.data.result;
+					const restle = [];
+					this.partTakeAdviceDetailList.forEach(item => {
+						item.restle = [{
+								text: "姝e父",
+								value: '1'
+							},
+							{
+								text: "寮傚父",
+								value: '2'
+							}
+						]; // 鏂板瓧娈碉紝鍊间负涓�涓┖鏁扮粍
+						item.type = [{
+								text: "鍚�",
+								value: "0"
+							},
+							{
+								text: "鏄�",
+								value: "1"
+							}
+						]; // 鏂板瓧娈碉紝鍊间负涓�涓┖鏁扮粍
+						item.istrue = true;
+					});
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data.result)
+
+					}
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+				})
+			},
+			handleImageError(e) {
+				const icon_prefix = "/static/";
+				this.previewImageSrc = icon_prefix + "icn_erro.png"
+			},
+			/**
+			 * 浣滀笟鎸囧涔�
+			 */
+			getStandardFile() {
+				this.$http.get(this.url.getStandardFile, {
+					params: {
+						id: this.standardId
+					}
+				}).then(res => {
+					if (res.data.success) {
+						console.log("res", res.data.result);
+						const referenceFileStr = res.data.result.referenceFile;
+
+						// 鍒ゆ柇鏄惁瀛樺湪 referenceFile 骞惰繘琛岃В鏋�
+						if (referenceFileStr) {
+							try {
+								const referenceFileObj = JSON.parse(referenceFileStr);
+								const filePath = `${this.ipAndPort}${referenceFileObj.filePath}`;
+								this.previewImageSrc = filePath;
+								console.log('previewImageSrc:', this.previewImageSrc);
+							} catch (e) {
+								console.error("referenceFile 瑙f瀽澶辫触", e);
+								this.previewImageSrc = '';
+							}
+						} else {
+							console.warn("referenceFile 涓嶅瓨鍦�");
+							this.previewImageSrc = '';
+						}
+					}
+				}).catch(err => {
+					console.error("缃戠粶璇锋眰澶辫触", err);
+					// 鑱旂綉澶辫触, 缁撴潫鍔犺浇
+				});
+			},
+
+			select(e) {
+				const tempFilePaths = e.tempFilePaths;
+				uni.showLoading({
+					title: '涓婁紶涓�...'
+				});
+				const uploadPromises = tempFilePaths.map((filePath, index) => {
+					return new Promise((resolve, reject) => {
+						this.$http.upload(this.url.upload, {
+								filePath: filePath,
+								name: 'file'
+							})
+							.then(uploadRes => {
+								// 鍋囪鏈嶅姟鍣ㄨ繑鍥炵殑缁撴灉涓寘鍚枃浠惰矾寰�
+								const serverFilePath = uploadRes.data.result[0];
+								this.formData.avatar.push(serverFilePath);
+								resolve(uploadRes); // 杩斿洖缁撴灉缁� Promise.all
+							})
+							.catch(err => {
+								console.error(`鍥剧墖 ${index + 1} 涓婁紶澶辫触:`, err);
+								reject(err);
+							});
+					});
+				});
+
+				Promise.all(uploadPromises)
+					.then(() => {
+						uni.hideLoading();
+						uni.showToast({
+							title: '鍏ㄩ儴涓婁紶鎴愬姛'
+						});
+					})
+					.catch(err => {
+						uni.hideLoading();
+						uni.showToast({
+							title: '閮ㄥ垎涓婁紶澶辫触',
+							icon: 'none'
+						});
+						console.error('涓婁紶寮傚父:', err);
+					});
+			},
+			// 鍒犻櫎
+			deletea(e) {
+				console.log('鍒犻櫎鍥剧墖', e);
+			}
+		}
+	}
+</script>
+
+<style>
+	<style scoped>
+
+	/* 鍒楄〃瀹瑰櫒鏍峰紡 */
+	.check-list-container {
+		margin-bottom: 120rpx;
+		/* 涓哄簳閮ㄦ搷浣滄爮鐣欏嚭绌洪棿 */
+	}
+
+	/* 鍒楄〃椤规牱寮� */
+	.list-item {
+		background-color: #fff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin: 10px;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+
+	/* 椤瑰ご閮ㄦ牱寮� */
+	.item-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 20rpx;
+		padding-bottom: 15rpx;
+		border-bottom: 1rpx solid #eee;
+	}
+
+	.part-code {
+		font-size: 32rpx;
+		font-weight: bold;
+		color: #333;
+	}
+
+	.warehouse-tag {
+		font-size: 24rpx;
+		color: #007AFF;
+		background-color: #e8f4ff;
+		padding: 6rpx 12rpx;
+		border-radius: 8rpx;
+	}
+
+	/* 璇︾粏淇℃伅鏍峰紡 */
+	.item-details {
+		margin-bottom: 20rpx;
+	}
+
+	.detail-row {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 15rpx;
+	}
+
+	.detail-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.label {
+		font-size: 28rpx;
+		color: #666;
+		flex: 1;
+	}
+
+	.value {
+		font-size: 28rpx;
+		color: #333;
+		flex: 1;
+		text-align: right;
+	}
+
+	.warning-text {
+		color: #ff6347;
+		font-weight: bold;
+	}
+
+	/* 鍙紪杈戞牱寮� */
+	.editable {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+	}
+
+	.edit-input {
+		border: 1rpx solid #007AFF;
+		border-radius: 8rpx;
+		padding: 10rpx;
+		width: 120rpx;
+		text-align: right;
+		font-size: 28rpx;
+	}
+
+	.edit-icon {
+		margin-left: 10rpx;
+		color: #007AFF;
+		font-size: 24rpx;
+	}
+
+	/* 鎿嶄綔鎸夐挳鏍峰紡 */
+	.item-actions {
+		display: flex;
+		justify-content: flex-end;
+		gap: 20rpx;
+	}
+
+	.action-btn {
+		padding: 12rpx 24rpx;
+		font-size: 13rpx;
+		border-radius: 8rpx;
+		border: none;
+		min-width: 60rpx;
+	}
+
+	.edit-btn {
+		background-color: #007AFF;
+		color: #fff;
+	}
+
+	.delete-btn {
+		background-color: #ff6347;
+		color: #fff;
+	}
+
+	.divider {
+		display: flex;
+		align-items: center;
+		text-align: center;
+		color: gray;
+		/* 鏂囧瓧棰滆壊 */
+		margin: 20px 0;
+		/* 涓婁笅闂磋窛 */
+	}
+
+	.divider::before,
+	.divider::after {
+		content: '';
+		flex: 1;
+		border-bottom: 1px solid gray;
+		/* 妯嚎棰滆壊 */
+		margin: 0 16px;
+		/* 妯嚎涓庢枃瀛椾箣闂寸殑闂磋窛 */
+	}
+
+	.divider text {
+		white-space: nowrap;
+		/* 闃叉鏂囧瓧鎹㈣ */
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/production/report/report.vue b/pages/eam/production/report/report.vue
new file mode 100644
index 0000000..c603703
--- /dev/null
+++ b/pages/eam/production/report/report.vue
@@ -0,0 +1,526 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">鎶ュ伐</block>
+			<block slot="right">
+				<view @click="printHandel">
+					<image class="search" src="/static/icon_dayin.png" style="width: 25px; height: 25px;" alt="鎵撳嵃鎸夐挳" />
+				</view>
+			</block>
+		</cu-custom>
+		
+		<!-- 楠ㄦ灦灞� -->
+		<view v-if="loading" class="skeleton-container">
+			<view class="skeleton-group">
+				<view class="skeleton-divider"></view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+			</view>
+			
+			<view class="skeleton-group">
+				<view class="skeleton-divider"></view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-datetime"></view>
+				</view>
+			</view>
+			
+			<view class="skeleton-button"></view>
+		</view>
+		
+		<!-- 瀹為檯鍐呭 -->
+		<view v-else class="container">
+			<uni-forms 
+				ref="form" 
+				:modelValue="formData" 
+				:rules="rules" 
+				validate-trigger="bind" 
+				err-show-type="undertext">
+				<uni-group top="1">
+					<view class="divider"><text>宸ュ崟淇℃伅</text></view>
+					<uni-forms-item :label-width="100" name="workOrderNumber" label="鍗曟嵁缂栧彿:">
+						<uni-easyinput v-model="formData.workOrderNumber" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="materialCode" label="鐗╂枡缂栫爜:">
+						<uni-easyinput v-model="formData.materialCode" :disabled="true" />
+					</uni-forms-item>
+
+					<uni-forms-item :label-width="100" name="materialDescription" label="鐗╂枡鎻忚堪:">
+						<uni-easyinput v-model="formData.materialDescription" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="璁″垝鏁伴噺:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+
+					<view class="divider"><text>鎶ュ伐淇℃伅</text></view>
+
+					<uni-forms-item  :label-width="140" required name="inspectionOrderNumber"
+						label="鎶ュ伐鍗曞彿:">
+						<uni-easyinput v-model="formData.inspectionOrderNumber" placeholder="绯荤粺鐢熸垚" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="process" label="浠撳簱">
+						<uni-data-select v-model="formData.process" :localdata="SpareList" @change="changeisSpareList"
+							placeholder="璇烽�夋嫨" />
+					</uni-forms-item>
+					<uni-forms-item  :label-width="140" required name="inspectionQuantity" label="鎶ュ伐鏁伴噺:">
+						<uni-number-box v-model="formData.inspectionQuantity"  />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="inspectionPlan" label="妫�楠屼汉鍛�">
+						<uni-data-select v-model="formData.inspectionPlan" :localdata="SpareList"
+							@change="changeisSpareList" placeholder="璇烽�夋嫨" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="inspectionTime" label="鎶ュ伐鏃堕棿">
+						<uni-datetime-picker type="datetime" v-model="formData.inspectionTime" />
+					</uni-forms-item>
+				</uni-group>
+			</uni-forms>
+
+			<view class="padding flex flex-direction">
+				<view class="flex-sub bg-blue padding-sm margin-xl radius text-sm text-center text-white"
+					@click.stop="ProductionTask()" hover-class="is-hover">纭畾</view>
+			</view>
+		</view>
+		
+		<pdaScanVue></pdaScanVue>
+	</view>
+</template>
+
+<script>
+	import pdaScanVue from "@/components/mes/pdaScan.vue";
+	import QRCode from 'qrcode';
+
+	export default {
+		components: {
+			pdaScanVue
+		},
+		data() {
+			return {
+				loading: true,
+				isShow: false,
+				isSubmitting: false, // 闃查噸澶嶆彁浜�
+				SpareList: [{
+						text: "鏄�",
+						value: 1
+					},
+					{
+						text: "鍚�",
+						value: 0
+					}
+				],
+				scrollLeft: 0,
+				formData: {
+					workOrderNumber: '1111111',
+					materialCode: '120008194',
+					materialDescription: '涓変唬杞瘋杞存壙鍗曞厓\\G3-487',
+					plannedQuantity: '200',
+					inspectionOrderNumber: '',
+					process: '',
+					inspectionType: '',
+					inspectionQuantity: '',
+					inspectionPlan: '',
+					inspectionTime: '',
+					// 鏂板瀛楁鐢ㄤ簬鏍囩鏁版嵁
+					productName: '椹卞姩杞存�绘垚',
+					palletNo: 'PAL20250822001',
+					produceDate: '',
+					workshop: '瑁呴厤杞﹂棿3鍙风嚎'
+				},
+				// 琛ㄥ崟楠岃瘉瑙勫垯
+				rules: {
+					process: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨宸ュ簭'
+						}]
+					},
+					inspectionType: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠岀被鍨�'
+						}]
+					},
+					inspectionPlan: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠屾柟妗�'
+						}]
+					},
+					inspectionTime: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠屾椂闂�'
+						}]
+					},
+					inspectionQuantity: {
+						rules: [{
+							required: true,
+							errorMessage: '璇疯緭鍏ラ�佹鏁伴噺'
+						}, {
+							format: 'number',
+							errorMessage: '閫佹鏁伴噺蹇呴』涓烘暟瀛�'
+						}]
+					}
+				},
+				NavBarColor: this.NavBarColor,
+				url: {
+					upload: "/eam/sysFiles/batch_upload",
+					stallList: "/eam/eamRepairOrder/queryById",
+					getEquipmentList: 'eam/equipment/list',
+					approval: '/eam/eamRepairOrder/perform'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				msg1Count: 0
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 160
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+		mounted() {
+			/**
+			 * 涓婃枡涓嬫枡鏍规嵁鐗╂枡绫诲瀷鍒ゆ柇锛堥澶栦俊鎭�)---鎵爜/鎵嬪姩杈撳叆 ---锛堟墜鍔ㄨ緭鍏ヨ皟鐢ㄦ帴鍙h繑鍥炲簱瀛樹俊鎭級  鎵爜淇℃伅鎻愪氦鍚庣锛屽湪閲嶆柊璧嬪�� 鍒ゆ柇鐗╂枡绫诲瀷- 鏄剧ず鐗规畩灞炴�у�硷紝 搴撳瓨淇℃伅涔熻淇濆瓨
+			 */
+			const currentLineType = this.$store.getters.currentLineType;
+			console.log('褰撳墠浜х嚎绫诲瀷锛�', currentLineType);
+			/**
+			 * 瑁呴厤	ASSEMBLE
+			 * 鍐呮硶鍏癐NNERFLANGE
+			 * 澶栨硶鍏癘UTERFLANGE
+			 * 鐑鐞咹EATTREATMENT
+			 */
+		},
+		created() {
+			// 鍒濆鍖栫敓浜ф棩鏈熶负褰撳墠鏃ユ湡
+			this.formData.produceDate = this.formatDate(new Date());
+			
+			// 妯℃嫙鏁版嵁鍔犺浇
+			setTimeout(() => {
+				this.loading = false;
+			}, 1000);
+		},
+		methods: {
+			// 鏍煎紡鍖栨棩鏈�
+			formatDate(date) {
+				const year = date.getFullYear();
+				const month = String(date.getMonth() + 1).padStart(2, '0');
+				const day = String(date.getDate()).padStart(2, '0');
+				return `${year}-${month}-${day}`;
+			},
+			
+			// 鐐瑰嚮鎵撳嵃鎸夐挳锛氱敓鎴怘TML棰勮骞惰烦杞�
+			async printHandel() {
+				// 1. 楠岃瘉琛ㄥ崟淇℃伅
+				if (!this.formData.inspectionQuantity || !this.formData.process) {
+					uni.showToast({
+						title: '璇峰厛濉啓鎶ュ伐鏁伴噺鍜屼粨搴撲俊鎭�',
+						icon: 'none',
+						duration: 2000
+					});
+					return;
+				}
+			
+				try {
+					uni.showLoading({ title: '鐢熸垚棰勮涓�...' });
+					
+					// 2. 鏀堕泦鎵撳嵃鏁版嵁
+					const tagData = this.getReportPrintData();
+					
+					// 3. 璺宠浆鑷抽瑙堥〉锛屽苟鎼哄甫鎵撳嵃鏁版嵁
+					await uni.navigateTo({
+						url: `/pages/finished-product-preview/finished-product-preview?tagData=${encodeURIComponent(JSON.stringify(tagData))}`
+					});
+					
+					uni.hideLoading();
+				} catch (error) {
+					uni.hideLoading();
+					console.error('鐢熸垚棰勮澶辫触:', error);
+					uni.showToast({ title: '棰勮鐢熸垚澶辫触', icon: 'none' });
+				}
+			},
+
+			// 鐢熸垚鎴愬搧鎵樻爣绛炬暟鎹紙浼樺寲鍚庯級
+		getReportPrintData() {
+		  const { formData } = this;
+		  return {
+			  
+			    material: '120034535',
+			    batch: '25098814',
+			    model: 'G3-2B259',
+			    quantity: 216,
+			    inspectDate: '20250408',
+			    inspector: '鐜嬬京/鍚堟牸',
+			    date: '2025.08.22'
+			  
+		 //    batchNo: "25158878",
+		 //    productModel:  "涓変唬杞瘋杞存壙鍗曞厓\\G3-639", 
+		 //    palletNo:  "11236979",  
+		 //    quantity:  "107",
+		 //    workshop:  "3003",  
+		 //    code: "1200143912506070086",
+			// planNum:"10016456466565"
+		  };
+		},
+
+			changeisSpareList(e) {
+				this.formData.isSpare = e;
+			},
+
+			async ProductionTask() {
+				// 闃叉閲嶅鎻愪氦
+				if (this.isSubmitting) {
+					uni.showToast({
+						icon: "none",
+						title: "姝e湪鎻愪氦涓紝璇峰嬁閲嶅鐐瑰嚮",
+						duration: 2000
+					});
+					return;
+				}
+
+				uni.showLoading({
+					mask: true,
+					title: "鎻愪氦涓�..."
+				});
+
+				try {
+					// 琛ㄥ崟楠岃瘉
+					await this.$refs.form.validate();
+
+					this.isSubmitting = true;
+
+					// 鍙戦�佹姤宸ヨ姹�
+					const response = await this.$http.post(this.url.approval, {
+						workOrderNumber: this.formData.workOrderNumber,
+						materialCode: this.formData.materialCode,
+						materialDescription: this.formData.materialDescription,
+						plannedQuantity: this.formData.plannedQuantity,
+						inspectionOrderNumber: this.formData.inspectionOrderNumber,
+						process: this.formData.process,
+						inspectionType: this.formData.inspectionType,
+						inspectionQuantity: this.formData.inspectionQuantity,
+						inspectionPlan: this.formData.inspectionPlan,
+						inspectionTime: this.formData.inspectionTime
+					});
+
+					if (response.data.success) {
+						uni.showToast({
+							icon: "success",
+							title: '鎻愪氦鎴愬姛',
+							duration: 2000
+						});
+
+						// 寤惰繜璺宠浆
+						await new Promise(resolve => setTimeout(resolve, 2000));
+
+						this.$Router.replaceAll({
+							name: 'qualityInspection'
+						});
+					} else {
+						uni.showModal({
+							title: "鎻愪氦澶辫触",
+							content: response.data.message || "鏈嶅姟鍣ㄥ鐞嗗け璐ワ紝璇风◢鍚庨噸璇�",
+							confirmText: '纭畾',
+							showCancel: false,
+							icon: "none"
+						});
+					}
+				} catch (error) {
+					// 閿欒澶勭悊
+					if (error.errMsg) {
+						uni.showToast({
+							icon: "none",
+							title: error,
+							duration: 2000
+						});
+					} else {
+						console.error("璇锋眰澶辫触:", error);
+						let errorMessage = "缃戠粶璇锋眰澶辫触";
+						if (error.errMsg) {
+							if (error.errMsg.includes("timeout")) {
+								errorMessage = "璇锋眰瓒呮椂锛岃妫�鏌ョ綉缁滆繛鎺�";
+							} else if (error.errMsg.includes("fail")) {
+								errorMessage = "缃戠粶杩炴帴澶辫触锛岃妫�鏌ョ綉缁滆缃�";
+							}
+						}
+						uni.showToast({
+							icon: "none",
+							title: errorMessage,
+							duration: 3000
+						});
+					}
+				} finally {
+					this.isSubmitting = false;
+					uni.hideLoading();
+				}
+			},
+		}
+	}
+</script>
+
+<style>
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+
+	.divider {
+		display: flex;
+		font-weight: bold;
+		align-items: center;
+		text-align: center;
+		color: #1E90FF;
+		font-size: 24rpx;
+		margin: 20px 0;
+	}
+
+	.divider::before,
+	.divider::after {
+		content: '';
+		flex: 1;
+		border-bottom: 1px solid gray;
+		margin: 0 16px;
+	}
+
+	.divider text {
+		white-space: nowrap;
+	}
+
+	.content {
+		margin-top: 5px;
+	}
+
+	.content scroll-view {
+		scrollIndicator: "none"
+	}
+
+	.popupView {
+		margin-top: 45px;
+		height: auto;
+	}
+	
+	/* 楠ㄦ灦灞忔牱寮� */
+	.skeleton-container {
+		padding: 20rpx;
+	}
+	
+	.skeleton-group {
+		margin-bottom: 40rpx;
+	}
+	
+	.skeleton-divider {
+		height: 40rpx;
+		width: 300rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-bottom: 30rpx;
+	}
+	
+	.skeleton-item {
+		display: flex;
+		align-items: center;
+		margin-bottom: 30rpx;
+	}
+	
+	.skeleton-label {
+		width: 160rpx;
+		height: 40rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-right: 20rpx;
+	}
+	
+	.skeleton-input {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-select {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-datetime {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-button {
+		width: 90%;
+		height: 80rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 10rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin: 40rpx auto;
+	}
+	
+	@keyframes skeleton-loading {
+		0% {
+			background-position: 100% 50%;
+		}
+		100% {
+			background-position: 0 50%;
+		}
+	}
+</style>
diff --git a/pages/eam/production/sample/sample.vue b/pages/eam/production/sample/sample.vue
new file mode 100644
index 0000000..c3f94ed
--- /dev/null
+++ b/pages/eam/production/sample/sample.vue
@@ -0,0 +1,358 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">鏍蜂欢鏍¢獙</block>
+		</cu-custom>
+		<view class="container">
+			<uni-forms ref="form" :modelValue="formData" validate-trigger="bind" err-show-type="undertext">
+				<uni-group top="1">
+					<uni-forms-item :label-width="100" name="remark" label="鏂囦欢鍚嶇О:">
+						<uni-easyinput v-model="formData.equipmentName" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="outNum" label="璁惧鏂囨。:">
+						<uni-file-picker v-model="fileLists" :extension="['.pdf']" @fail="uploadFail"
+							:list-styles="listStyles" :delIcon="del" :max-count="5" file-mediatype="all"
+							@downloadFile="downloadFile" @select="onFileSelect" @delete="onFileDelete">
+							<button size="mini" type="primary">鐐瑰嚮涓婁紶</button>
+						</uni-file-picker>
+					</uni-forms-item>
+					<!-- 鏂板锛氭牎楠岀粨鏋滃崟閫夋 -->
+					<uni-forms-item name="result" :label-width="100" label="妫�楠岀粨鏋�:">
+						<radio-group @change="radioChange">
+							<label style="margin-right: 20rpx;">
+								<radio :checked="formData.result=='qualified'" value="qualified"/>鍚堟牸
+							</label>
+
+							<label style="margin-right: 20rpx;">
+								<radio :checked="formData.result=='unqualified'" value="unqualified"/>涓嶅悎鏍�
+							</label>
+
+
+						</radio-group>
+					</uni-forms-item>
+
+
+				</uni-group>
+			</uni-forms>
+			
+			<view class="file-list margin-sm">
+				<view class="file-item" v-for="(file, index) in this.selectedFiles" :key="index">
+					<view class="file-icon">
+						<!-- 鏂囦欢鍥炬爣 -->
+						<image src="/static/icon_file.png" style="height: 25px;  width: 25px; margin-right: 10px;"
+							mode='aspectFit' class="zai-logo "></image>
+					</view>
+					<view class="file-name">
+						<!-- 鏂囦欢鍚� -->
+						{{ file.fileName }}
+					</view>
+					<view class="file-actions">
+						<!-- 涓嬭浇鎸夐挳 -->
+						<image v-show="showBtn" src="/static/icon_down.png" @click="downloadFile(file)"
+							style="height: 25px;  width: 25px; margin-right: 10px;"></image>
+					</view>
+				</view>
+			</view>
+			
+			<!-- 搴曢儴鎿嶄綔鏍� -->
+			<view class="action-bar">
+				<button class="operation-btn" @click="handleLock">閿佸畾</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		saveAs
+	} from 'file-saver'; // 寮曞叆 file-saver 搴�
+	export default {
+		data() {
+			return {
+				listStyles: {
+					"borderStyle": {
+						"width": "0", // 杈规瀹藉害
+					},
+					"border": false, // 鏄惁鏄剧ず杈规
+					"dividline": false
+				},
+				formData: {
+					equipmentName: '',
+					result: ''
+				},
+				fileLists: [],
+				NavBarColor: this.NavBarColor,
+				url: {
+					stallList: "/eam/equipment/queryById",
+					add: 'eam/equipmentAttachment/add',
+					upload: "/eam/sysFiles/batch_upload",
+					downloadFile: 'eam/equipmentAttachment/downloadFile'
+				},
+				id: '',
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				msg1Count: 0,
+				msg2Count: 0,
+				msg1Title: ""
+			}
+		},
+
+		computed: {
+			authList() {
+				return this.$store.getters.getAuth || []
+			},
+			top() {
+				return this.CustomBar * 2 + 160
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+		onUnload() {
+			this.id = null;
+			this.formData = {}; // 娓呯┖鏁版嵁
+			this.fileLists = [];
+		},
+
+
+		created() {
+			this.getFileList();
+		},
+		methods: {
+
+			authIncludes(code) {
+				return this.authList.some(auth => auth.action === code)
+			},
+			downloadFile(item) {
+				uni.showModal({
+					title: '鎻愮ず',
+					content: '纭瑕佷笅杞藉悧',
+					cancelText: '鍙栨秷',
+					confirmText: '纭',
+					success: res => {
+						if (res.confirm) {
+							this.downFile(item)
+						}
+					}
+				})
+
+			},
+
+
+			downFile(item) {
+				this.$http.download(this.url.downloadFile, {
+					params: {
+						id: item.id
+					},
+					responseType: 'blob' // 纭繚鍝嶅簲绫诲瀷涓� blob
+				}).then(response => {
+					console.log('Response:', response); // 鏌ョ湅瀹屾暣鍝嶅簲缁撴瀯
+
+					// 鑾峰彇 tempFilePath锛圔lob URL锛�
+					const tempFilePath = response.tempFilePath;
+
+					if (!tempFilePath) {
+						uni.showToast({
+							title: '鏂囦欢涓嬭浇澶辫触',
+							icon: 'none'
+						});
+						return;
+					}
+
+					let fileName = item.fileName;
+
+					// 鍒涘缓 <a> 鏍囩骞惰Е鍙戜笅杞�
+					const link = document.createElement('a');
+					link.href = tempFilePath;
+					link.setAttribute('download', fileName);
+					link.style.display = 'none';
+
+					document.body.appendChild(link);
+					link.click();
+
+					// 娓呯悊璧勬簮
+					document.body.removeChild(link);
+
+				}).catch(err => {
+					console.error('Download error:', err);
+					uni.showToast({
+						title: '鏂囦欢涓嬭浇澶辫触',
+						icon: 'none'
+					});
+				});
+			},
+			getFileList() {
+				this.$http.get(this.url.fileList, {
+					params: {
+						equipmentId: this.id,
+						pageNo: 1,
+						pageSize: 999,
+						column: 'createTime',
+						order: 'desc'
+					},
+				}).then(res => {
+					if (res.data.success) {
+						this.selectedFiles = res.data.result.records || [];
+
+					}
+				}).catch(() => {
+					uni.showToast({
+						title: '鑾峰彇鏂囦欢鍒楄〃澶辫触',
+						icon: 'none'
+					});
+				});
+			},
+			uploadFail(e) {
+				console.log('涓婁紶澶辫触锛�', e)
+			},
+
+
+			onFileSelect(e) {
+				const tempFilePaths = e.tempFilePaths;
+
+				uni.showLoading({
+					title: '涓婁紶涓�...'
+				});
+
+				const uploadPromises = tempFilePaths.map((filePath, index) => {
+					return new Promise((resolve, reject) => {
+						this.$http.upload(this.url.upload, {
+								filePath: filePath,
+								name: 'file'
+							})
+							.then(uploadRes => {
+								const serverFile = uploadRes.data.result[0];
+								console.log(serverFile);
+								// 鎻愬彇fileSuffix骞舵嫾鎺�
+								if (serverFile.fileSuffix && serverFile.fileName && !serverFile
+									.fileName.includes('.')) {
+									serverFile.fileName += '.' + serverFile.fileSuffix;
+								}
+								this.fileLists = [];
+								// 闃叉閲嶅娣诲姞锛堟牴鎹� id 鎴� fileName 鍒ゆ柇锛�
+								if (!this.fileLists.some(file => file.id === serverFile.id)) {
+									this.fileLists.push(serverFile);
+								}
+								resolve();
+							})
+							.catch(err => {
+								console.error(`鏂囦欢 ${index + 1} 涓婁紶澶辫触`, err);
+								uni.showToast({
+									title: `绗� ${index + 1} 涓枃浠朵笂浼犲け璐,
+									icon: 'none'
+								});
+								reject(err);
+							});
+					});
+				});
+
+				Promise.all(uploadPromises)
+					.then(() => {
+						uni.hideLoading();
+						uni.showToast({
+							title: '鍏ㄩ儴涓婁紶鎴愬姛锛屾鍦ㄦ彁浜�...'
+						});
+						this.submitFileList(); // 鑷姩鎻愪氦鎵�鏈夋枃浠�
+					})
+					.catch(() => {
+						uni.hideLoading();
+						uni.showToast({
+							title: '閮ㄥ垎涓婁紶澶辫触',
+							icon: 'none'
+						});
+					});
+			},
+			// 鏂囦欢鍒犻櫎鍥炶皟
+			onFileDelete(e) {
+				console.log('鍒犻櫎鏂囦欢:', e.index);
+			},
+
+			// 鍒犻櫎鍗曚釜鏂囦欢
+			deleteFile(index) {
+				this.fileLists.splice(index, 1);
+			},
+
+
+			submitFileList() {
+				if (!this.fileLists.length) {
+					uni.showToast({
+						title: '娌℃湁鍙彁浜ょ殑鏂囦欢',
+						icon: 'none'
+					});
+					return;
+				}
+				console.log(this.fileLists)
+				this.$http.post(this.url.add, {
+					equipmentId: this.id,
+					fileList: this.fileLists
+				}).then(res => {
+					if (res.data.success) {
+						uni.showToast({
+							title: '鎻愪氦鎴愬姛'
+						});
+						this.getFileList();
+					} else {
+						uni.showToast({
+							title: '鎻愪氦澶辫触',
+							icon: 'none'
+						});
+					}
+				}).catch(err => {
+					uni.showToast({
+						title: '鎻愪氦寮傚父',
+						icon: 'none'
+					});
+					console.error('鎻愪氦澶辫触:', err);
+				});
+			},
+		},
+
+	}
+</script>
+
+<style>
+	
+	/* 搴曢儴鎿嶄綔鏍忔牱寮� */
+	.action-bar {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #fff;
+		padding: 20rpx;
+		display: flex;
+		justify-content: space-around;
+		box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
+		z-index: 999;
+	}
+	
+	.operation-btn {
+		padding: 20rpx 40rpx;
+		font-size: 22rpx;
+		border-radius: 12rpx;
+		background-color: #007AFF;
+		color: #fff;
+		border: none;
+		flex: 1;
+		margin: 0 10rpx;
+	}
+
+
+
+	.content {
+		margin-top: 5px;
+	}
+
+	.content scroll-view {
+		scrollIndicator: "none"
+	}
+
+</style>
\ No newline at end of file
diff --git a/pages/eam/quality/checkItem/checkItem.vue b/pages/eam/quality/checkItem/checkItem.vue
new file mode 100644
index 0000000..e224fd4
--- /dev/null
+++ b/pages/eam/quality/checkItem/checkItem.vue
@@ -0,0 +1,468 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">妫�楠岄」</block>
+		</cu-custom>
+
+		<!-- 楠ㄦ灦灞� -->
+		<view v-if="loading" class="skeleton-container">
+			<view class="skeleton-list">
+				<!-- 閲嶅娓叉煋澶氫釜涓垪琛ㄩ」楠ㄦ灦 -->
+				<view class="skeleton-item" v-for="n in 4" :key="n">
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-action-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-button"></view>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<!-- 瀹為檯鍐呭 -->
+		<view v-else class="container">
+			<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+				<!-- 鍒楄〃淇℃伅寮�濮� -->
+				<view class="content" style="margin: 10px;">
+					<view class="check-list-container">
+						<view class="list-item" v-for="(item, index) in checkList" :key="index">
+							<!-- 璇︾粏淇℃伅 -->
+							<view class="item-details">
+								<view class="detail-row">
+									<text class="label">妫�楠岄」缂栫爜:</text>
+									<text class="value">{{ item.paramCode}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">妫�楠岄」鍚嶇О:</text>
+									<text class="value">{{ item.paramName }}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">妫�楠岄」宸ュ叿:</text>
+									<text class="value">{{ item.availableQty }}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鎶�鏈姹�:</text>
+									<text class="value">{{ item.paramValue}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">鏈�澶у��:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">鏈�灏忓��:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">鍚堟牸鏁伴噺:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">涓嶅悎鏍兼暟閲�:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+							</view>
+
+							<view class="detail-row">
+								<view class="label">鎿嶄綔:</view>
+								<view class="flex-sub bg-blue padding-xs margin-xs radius text-sm text-center"
+									@click.stop="handleStartWork(item)" hover-class="is-hover">妫�楠�</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</mescroll-uni>
+		</view>
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				loading: true, // 鎺у埗楠ㄦ灦灞忔樉绀�
+				checkList: [{
+						paramCode: '01',
+						paramName: '鍐呭緞',
+						validRange: '鍗″昂',
+						paramValue: '-',
+						judgment: '10mm'
+					},
+					{
+						paramCode: '01',
+						paramName: '鍐呭緞',
+						validRange: '鍗″昂',
+						paramValue: '-',
+						judgment: '10mm'
+					},
+					{
+						paramCode: '01',
+						paramName: '鍐呭緞',
+						validRange: '鍗″昂',
+						paramValue: '-',
+						judgment: '10mm'
+					},
+					{
+						paramCode: '01',
+						paramName: '鍐呭緞',
+						validRange: '鍗″昂',
+						paramValue: '-',
+						judgment: '10mm'
+					}
+				],
+				scrollLeft: 0,
+				formData: {
+					num: '',
+					type: ''
+				},
+				NavBarColor: this.NavBarColor,
+				activeColor: '#5277A6',
+				url: {
+					flowType: "/sys/dict/getDictItems/flow_type",
+					stallList: "/assign/flow/toTaskBySelf"
+				},
+
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10 // 姣忛〉鏁版嵁鐨勬暟閲�
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				typeList: [],
+				msgList: [], //鍒楄〃鏁版嵁
+				announcement1: [],
+				msg1Count: 0,
+				msg2Count: 0,
+				msg1Title: ""
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 50
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+		onShow() {
+			if (this.mescroll) {
+				this.mescroll.resetUpScroll()
+			}
+		},
+
+		created() {
+			// 妯℃嫙鏁版嵁鍔犺浇寤惰繜锛屾樉绀洪鏋跺睆
+			setTimeout(() => {
+				this.loading = false;
+			}, 1500);
+		},
+		methods: {
+			
+			handleStartWork(){
+				uni.navigateTo({
+					url:'/pages/eam/quality/productionInspection/productionInspection'
+				})
+			},
+			upCallback(page) {
+				this.$http.get(this.url.stallList, {
+					params: {
+						pageNo: page.num,
+						pageSize: page.size,
+						order: 'desc',
+						column: 'createTime'
+					},
+				}).then(res => {
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+				})
+
+			},
+
+			// 閿佸畾鎿嶄綔
+			handleLock() {
+				uni.showToast({
+					title: '鎿嶄綔鎵ц涓�...',
+					icon: 'loading'
+				});
+
+				uni.navigateBack(1);
+
+			},
+
+			// 閫氱煡棰嗘枡鎿嶄綔
+			handleNotice() {
+				uni.navigateBack(1);
+			},
+
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+		},
+
+	}
+</script>
+
+<style>
+	/* 鍒楄〃瀹瑰櫒鏍峰紡 */
+	.check-list-container {
+		margin-bottom: 120rpx;
+		/* 涓哄簳閮ㄦ搷浣滄爮鐣欏嚭绌洪棿 */
+	}
+
+	/* 鍒楄〃椤规牱寮� */
+	.list-item {
+		background-color: #fff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+
+	/* 璇︾粏淇℃伅鏍峰紡 */
+	.item-details {
+		margin-bottom: 20rpx;
+	}
+
+	.detail-row {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 15rpx;
+	}
+
+	.detail-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.label {
+		font-size: 28rpx;
+		color: #666;
+		flex: 1;
+	}
+
+	.value {
+		font-size: 28rpx;
+		color: #333;
+		flex: 1;
+		text-align: right;
+	}
+
+	.warning-text {
+		color: #ff6347;
+		font-weight: bold;
+	}
+
+	/* 鍙紪杈戞牱寮� */
+	.editable {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+	}
+
+	.edit-input {
+		border: 1rpx solid #007AFF;
+		border-radius: 8rpx;
+		padding: 10rpx;
+		width: 120rpx;
+		text-align: right;
+		font-size: 28rpx;
+	}
+
+	.edit-icon {
+		margin-left: 10rpx;
+		color: #007AFF;
+		font-size: 24rpx;
+	}
+
+	/* 鎿嶄綔鎸夐挳鏍峰紡 */
+	.item-actions {
+		display: flex;
+		justify-content: flex-end;
+		gap: 20rpx;
+	}
+
+	.action-btn {
+		padding: 12rpx 24rpx;
+		font-size: 13rpx;
+		border-radius: 8rpx;
+		border: none;
+		min-width: 60rpx;
+	}
+
+	.edit-btn {
+		background-color: #007AFF;
+		color: #fff;
+	}
+
+	.delete-btn {
+		background-color: #ff6347;
+		color: #fff;
+	}
+
+	/* 搴曢儴鎿嶄綔鏍忔牱寮� */
+	.action-bar {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #fff;
+		padding: 20rpx;
+		display: flex;
+		justify-content: space-around;
+		box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
+		z-index: 999;
+	}
+
+	.operation-btn {
+		padding: 20rpx 40rpx;
+		font-size: 22rpx;
+		border-radius: 12rpx;
+		background-color: #007AFF;
+		color: #fff;
+		border: none;
+		flex: 1;
+		margin: 0 10rpx;
+	}
+	
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+	
+	/* 楠ㄦ灦灞忔牱寮� */
+	.skeleton-container {
+		padding: 20rpx;
+	}
+	
+	.skeleton-list {
+		width: 100%;
+	}
+	
+	.skeleton-item {
+		background-color: #ffffff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+	
+	.skeleton-detail-row {
+		display: flex;
+		margin-bottom: 15rpx;
+	}
+	
+	.skeleton-label {
+		width: 200rpx;
+		height: 28rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-value {
+		flex: 1;
+		height: 28rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-left: 20rpx;
+	}
+	
+	.skeleton-action-row {
+		display: flex;
+		align-items: center;
+		margin-top: 10rpx;
+	}
+	
+	.skeleton-button {
+		width: 120rpx;
+		height: 50rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-left: 20rpx;
+	}
+	
+	@keyframes skeleton-loading {
+		0% {
+			background-position: 100% 50%;
+		}
+		100% {
+			background-position: 0 50%;
+		}
+	}
+</style>
diff --git a/pages/eam/quality/checkItemDetail/checkItemDetail.vue b/pages/eam/quality/checkItemDetail/checkItemDetail.vue
new file mode 100644
index 0000000..d16a6b6
--- /dev/null
+++ b/pages/eam/quality/checkItemDetail/checkItemDetail.vue
@@ -0,0 +1,492 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">妫�楠岄」</block>
+		</cu-custom>
+
+		<!-- 楠ㄦ灦灞� -->
+		<view v-if="loading" class="skeleton-container">
+			<view class="skeleton-list">
+				<!-- 閲嶅娓叉煋澶氫釜鍒楄〃椤归鏋� -->
+				<view class="skeleton-item" v-for="n in 4" :key="n">
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-action-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-button"></view>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<!-- 瀹為檯鍐呭 -->
+		<view v-else class="container">
+			<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+				<!-- 鍒楄〃淇℃伅寮�濮� -->
+				<view class="content" style="margin: 10px;">
+					<view class="check-list-container">
+						<view class="list-item" v-for="(item, index) in checkList" :key="index">
+							<!-- 璇︾粏淇℃伅 -->
+							<view class="item-details">
+								<view class="detail-row">
+									<text class="label">妫�楠岄」缂栫爜:</text>
+									<text class="value">{{ item.paramCode}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">妫�楠岄」鍚嶇О:</text>
+									<text class="value">{{ item.paramName }}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">妫�楠岄」宸ュ叿:</text>
+									<text class="value">{{ item.availableQty }}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鎶�鏈姹�:</text>
+									<text class="value">{{ item.paramValue}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">鏈�澶у��:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">鏈�灏忓��:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">鍚堟牸鏁伴噺:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">涓嶅悎鏍兼暟閲�:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+							</view>
+
+							<view class="detail-row">
+								<view class="label">鎿嶄綔:</view>
+								<view class="flex-sub bg-blue padding-xs margin-xs radius text-sm text-center"
+									@click.stop="handleStartWork(item)" hover-class="is-hover">妫�楠屾槑缁�</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</mescroll-uni>
+		</view>
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				loading: true, // 鎺у埗楠ㄦ灦灞忔樉绀�
+				checkList: [{
+						paramCode: '01',
+						paramName: '鍐呭緞',
+						validRange: '鍗″昂',
+						paramValue: '-',
+						judgment: '10mm'
+					},
+					{
+						paramCode: '01',
+						paramName: '鍐呭緞',
+						validRange: '鍗″昂',
+						paramValue: '-',
+						judgment: '10mm'
+					},
+					{
+						paramCode: '01',
+						paramName: '鍐呭緞',
+						validRange: '鍗″昂',
+						paramValue: '-',
+						judgment: '10mm'
+					},
+					{
+						paramCode: '01',
+						paramName: '鍐呭緞',
+						validRange: '鍗″昂',
+						paramValue: '-',
+						judgment: '10mm'
+					}
+				],
+				scrollLeft: 0,
+				formData: {
+					num: '',
+					type: ''
+				},
+				NavBarColor: this.NavBarColor,
+				activeColor: '#5277A6',
+				url: {
+					flowType: "/sys/dict/getDictItems/flow_type",
+					stallList: "/assign/flow/toTaskBySelf"
+				},
+
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10 // 姣忛〉鏁版嵁鐨勬暟閲�
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				typeList: [],
+				msgList: [], //鍒楄〃鏁版嵁
+				announcement1: [],
+				msg1Count: 0,
+				msg2Count: 0,
+				msg1Title: ""
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 50
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+
+		onShow() {
+			if (this.mescroll) {
+				this.mescroll.resetUpScroll()
+			}
+		},
+
+		created() {
+			// 妯℃嫙鏁版嵁鍔犺浇寤惰繜锛屾樉绀洪鏋跺睆
+			setTimeout(() => {
+				this.loading = false;
+			}, 1500);
+		},
+		methods: {
+			
+			handleStartWork(){
+				
+			uni.navigateTo({
+				url:'/pages/eam/quality/inspectionDetail/inspectionDetail'
+			})
+			},
+			upCallback(page) {
+				this.$http.get(this.url.stallList, {
+					params: {
+						pageNo: page.num,
+						pageSize: page.size,
+						order: 'desc',
+						column: 'createTime'
+					},
+				}).then(res => {
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+				})
+
+			},
+
+			// 閿佸畾鎿嶄綔
+			handleLock() {
+				uni.showToast({
+					title: '鎿嶄綔鎵ц涓�...',
+					icon: 'loading'
+				});
+
+				uni.navigateBack(1);
+
+			},
+
+			// 閫氱煡棰嗘枡鎿嶄綔
+			handleNotice() {
+				uni.navigateBack(1);
+			},
+
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+		},
+
+	}
+</script>
+
+<style>
+	/* 鍒楄〃瀹瑰櫒鏍峰紡 */
+	.check-list-container {
+		margin-bottom: 120rpx;
+		/* 涓哄簳閮ㄦ搷浣滄爮鐣欏嚭绌洪棿 */
+	}
+
+	/* 鍒楄〃椤规牱寮� */
+	.list-item {
+		background-color: #fff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+
+	/* 椤瑰ご閮ㄦ牱寮� */
+	.item-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 20rpx;
+		padding-bottom: 15rpx;
+		border-bottom: 1rpx solid #eee;
+	}
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+	.part-code {
+		font-size: 32rpx;
+		font-weight: bold;
+		color: #333;
+	}
+
+	.warehouse-tag {
+		font-size: 24rpx;
+		color: #007AFF;
+		background-color: #e8f4ff;
+		padding: 6rpx 12rpx;
+		border-radius: 8rpx;
+	}
+
+	/* 璇︾粏淇℃伅鏍峰紡 */
+	.item-details {
+		margin-bottom: 20rpx;
+	}
+
+	.detail-row {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 15rpx;
+	}
+
+	.detail-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.label {
+		font-size: 28rpx;
+		color: #666;
+		flex: 1;
+	}
+
+	.value {
+		font-size: 28rpx;
+		color: #333;
+		flex: 1;
+		text-align: right;
+	}
+
+	.warning-text {
+		color: #ff6347;
+		font-weight: bold;
+	}
+
+	/* 鍙紪杈戞牱寮� */
+	.editable {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+	}
+
+	.edit-input {
+		border: 1rpx solid #007AFF;
+		border-radius: 8rpx;
+		padding: 10rpx;
+		width: 120rpx;
+		text-align: right;
+		font-size: 28rpx;
+	}
+
+	.edit-icon {
+		margin-left: 10rpx;
+		color: #007AFF;
+		font-size: 24rpx;
+	}
+
+	/* 鎿嶄綔鎸夐挳鏍峰紡 */
+	.item-actions {
+		display: flex;
+		justify-content: flex-end;
+		gap: 20rpx;
+	}
+
+	.action-btn {
+		padding: 12rpx 24rpx;
+		font-size: 13rpx;
+		border-radius: 8rpx;
+		border: none;
+		min-width: 60rpx;
+	}
+
+	.edit-btn {
+		background-color: #007AFF;
+		color: #fff;
+	}
+
+	.delete-btn {
+		background-color: #ff6347;
+		color: #fff;
+	}
+
+	/* 搴曢儴鎿嶄綔鏍忔牱寮� */
+	.action-bar {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #fff;
+		padding: 20rpx;
+		display: flex;
+		justify-content: space-around;
+		box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
+		z-index: 999;
+	}
+
+	.operation-btn {
+		padding: 20rpx 40rpx;
+		font-size: 22rpx;
+		border-radius: 12rpx;
+		background-color: #007AFF;
+		color: #fff;
+		border: none;
+		flex: 1;
+		margin: 0 10rpx;
+	}
+	
+	/* 楠ㄦ灦灞忔牱寮� */
+	.skeleton-container {
+		padding: 20rpx;
+	}
+	
+	.skeleton-list {
+		width: 100%;
+	}
+	
+	.skeleton-item {
+		background-color: #ffffff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+	
+	.skeleton-detail-row {
+		display: flex;
+		margin-bottom: 15rpx;
+	}
+	
+	.skeleton-label {
+		width: 200rpx;
+		height: 28rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-value {
+		flex: 1;
+		height: 28rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-left: 20rpx;
+	}
+	
+	.skeleton-action-row {
+		display: flex;
+		align-items: center;
+		margin-top: 10rpx;
+	}
+	
+	.skeleton-button {
+		width: 120rpx;
+		height: 50rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-left: 20rpx;
+	}
+	
+	@keyframes skeleton-loading {
+		0% {
+			background-position: 100% 50%;
+		}
+		100% {
+			background-position: 0 50%;
+		}
+	}
+</style>
diff --git a/pages/eam/quality/defectiveProductReview/defectiveProductReview.vue b/pages/eam/quality/defectiveProductReview/defectiveProductReview.vue
new file mode 100644
index 0000000..fcc888b
--- /dev/null
+++ b/pages/eam/quality/defectiveProductReview/defectiveProductReview.vue
@@ -0,0 +1,587 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">涓嶅悎鏍煎搧瀹$悊</block>
+		</cu-custom>
+
+		<uni-search-bar placeholder="鐢熶骇鍗曞彿/鐗╂枡淇℃伅" @confirm="search" :focus="false" v-model="searchValue" @blur="blur"
+			@focus="focus" @input="input" @cancel="cancel" @clear="clear">
+		</uni-search-bar>
+		<view class="container">
+			<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+				<view class="production-container">
+					<view class="bill-table" v-for="(item, index) in mockBillList" :key="index">
+						<!-- 琛ㄥご锛堝叡鐢ㄦ牱寮忥級 -->
+						<view class="table-content">
+							<!-- 鍗曟嵁鍙疯 -->
+							<view class="table-row">
+								<text class="table-header">鍗曟嵁鍙凤細</text>
+								<text class="table-value">{{item.billNo || item.num}}</text>
+							</view>
+							<!-- 鐗╂枡缂栫爜琛� -->
+							<view class="table-row">
+								<text class="table-header">鐗╂枡缂栫爜锛�</text>
+								<text class="table-value">{{item.materialCode}}</text>
+							</view>
+							<!-- 鐗╂枡鎻忚堪琛� -->
+							<view class="table-row">
+								<text class="table-header">鐗╂枡鎻忚堪锛�</text>
+								<text class="table-value">{{item.materialDesc}}</text>
+							</view>
+							<!-- 浜х嚎琛� -->
+							<view class="table-row">
+								<text class="table-header">浜х嚎锛�</text>
+								<text class="table-value">{{item.productionLine}}</text>
+							</view>
+							<!-- 鐝粍琛� -->
+							<view class="table-row">
+								<text class="table-header">鐝粍锛�</text>
+								<text class="table-value">{{item.team}}</text>
+							</view>
+							<view class="table-row">
+								<text class="table-header">瀹$悊浜猴細</text>
+								<text class="table-value">{{item.team}}</text>
+							</view>
+							<view class="table-row">
+								<text class="table-header">瀹$悊缁撴灉锛�</text>
+								<text class="table-value">{{item.team}}</text>
+							</view>
+							<view class="table-row">
+								<text class="table-header">瀹$悊鏃堕棿锛�</text>
+								<text class="table-value">{{item.team}}</text>
+							</view>
+							<!-- 鐢熶骇鏃ユ湡琛岋紙澶氬唴瀹癸級 -->
+							<view class="table-row">
+								<text class="table-header">妫�楠岀被鍨嬶細</text>
+								<view class="table-value">
+									<text>{{item.produceDate}}</text>
+									<text class="right-content">璁″垝鏁伴噺锛歿{item.planQty}}</text>
+								</view>
+							</view>
+							<!-- 妫�楠岃褰曡 -->
+							<view class="table-row">
+								<text class="table-header">鍗曟嵁鐘舵�侊細</text>
+								<view class="table-value">
+									<text class="status-tag" :class="[{ passed: item.inspectResult === '鏈鐞�' },{ finish: item.inspectResult === '宸插鐞�' }]">
+										{{item.inspectResult}}
+									</text>
+								</view>
+							</view>
+							<!-- 涓婃枡淇℃伅琛岋紙澶氬唴瀹癸級 -->
+							<view class="table-row">
+								<text class="table-header">涓嶅悎鏍兼暟閲忥細</text>
+								<view class="table-value">
+									<text>{{item.feedQty}}</text>
+									<text class="right-content">澶勭悊鏁伴噺锛歿{item.feeder}}</text>
+								</view>
+							</view>
+							<!-- 鎿嶄綔琛� -->
+							<view class="table-row operation-row">
+								<text class="table-header">鎿嶄綔锛�</text>
+								<view class="table-value">
+									<view class="button-group">
+										<button class="action-btn" v-for="btn in getActionButtons(TabCur)"
+											:key="btn.type" @click="handleButtonClick(item, btn)" :class="btn.type">
+											{{btn.text}}
+										</button>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</mescroll-uni>
+		</view>
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				mockBillList: [{
+						billNo: 'SCGD202507001', // 鍗曟嵁鍙�
+						materialCode: '220005874', // 鐗╂枡缂栫爜
+						materialDesc: '澶栨硶鍏癨\G3-487/01', // 鐗╂枡鎻忚堪
+						spec: '桅120脳30mm', // 瑙勬牸鍨嬪彿
+						productionLine: '鐑鐞嗙粍', // 浜х嚎
+						team: '寮犳澃鐝粍', // 鐝粍
+						produceDate: '2025-07-10', // 鐢熶骇鏃ユ湡
+						planQty: 500, // 璁″垝鏁伴噺
+						actualQty: 480, // 瀹為檯鏁伴噺
+						inspectResult: '鏈鐞�', // 妫�楠岀粨鏋�
+						feedQty: 200, // 涓婃枡鏁伴噺
+						feeder: '鐜嬬帀', // 涓婃枡浜哄憳
+						feedTime: '2025-07-10 08:30', // 涓婃枡鏃堕棿
+						
+					},
+					{
+						billNo: 'SCGD202507002',
+						materialCode: '120008194',
+						materialDesc: '涓変唬杞暀杞磋酱鎵垮崟鍏僜\G3-487',
+						spec: '鍨嬪彿305',
+						productionLine: '瑁呴厤涓�绾�',
+						team: '寮犳澃鐝粍',
+						produceDate: '2025-07-10',
+						planQty: 200,
+						actualQty: 200,
+						inspectResult: '宸插鐞�',
+						feedQty: 200,
+						feeder: '寮犳澃',
+						feedTime: '2025-07-10 09:15',
+					
+					},
+					{
+						billNo: 'SCGD202507003',
+						materialCode: '330012456',
+						materialDesc: '杞悜鑺傝噦\\G3-500',
+						spec: 'L=210mm',
+						productionLine: '鏈哄姞宸ヤ簩绾�',
+						team: '鏉庡崕鐝粍',
+						produceDate: '2025-07-11',
+						planQty: 300,
+						actualQty: 150,
+						inspectResult: '鏈鐞�',
+						feedQty: 150,
+						feeder: '璧垫槑',
+						feedTime: '2025-07-11 10:00'
+					
+					},
+					{
+						billNo: 'SCGD202507004',
+						materialCode: '440009876',
+						materialDesc: '鍗婅酱濂楃\\G3-620',
+						spec: '桅89脳1200mm',
+						productionLine: '閿婚�犵嚎',
+						team: '鐜嬪己鐝粍',
+						produceDate: '2025-07-11',
+						planQty: 100,
+						actualQty: 0,
+						inspectResult: '宸插鐞�',
+						feedQty: 0,
+						feeder: '',
+						feedTime: ''
+					
+					},
+					{
+						billNo: 'SCGD202507005',
+						materialCode: '550010345',
+						materialDesc: '鍒跺姩鐩榎\G3-450',
+						spec: '桅350mm',
+						productionLine: '鏈哄姞宸ヤ竴绾�',
+						team: '鍒樻檽鐝粍',
+						produceDate: '2025-07-09',
+						planQty: 400,
+						actualQty: 400,
+						inspectResult: '鏈鐞�',
+						feedQty: 400,
+						feeder: '瀛欎紵',
+						feedTime: '2025-07-09 14:20'
+					
+					},
+					{
+						billNo: 'SCGD202507006',
+						materialCode: '660007654',
+						materialDesc: '杞瘋杞存壙鍗曞厓\\G3-720',
+						spec: '鍨嬪彿5206',
+						productionLine: '瑁呴厤浜岀嚎',
+						team: '鍛ㄧ孩鐝粍',
+						produceDate: '2025-07-12',
+						planQty: 250,
+						actualQty: 100,
+						inspectResult: '鏈鐞�',
+						feedQty: 100,
+						feeder: '鍚磋姵',
+						feedTime: '2025-07-12 08:45'
+						
+					},
+					{
+						billNo: 'SCGD202507007',
+						materialCode: '770003219',
+						materialDesc: '浼犲姩杞存�绘垚\\G3-800',
+						spec: '闀�1500mm',
+						productionLine: '鎬昏绾�',
+						team: '閮戝啗鐝粍',
+						produceDate: '2025-07-12',
+						planQty: 80,
+						actualQty: 0,
+						inspectResult: '宸插鐞�',
+						feedQty: 0,
+						feeder: '',
+						feedTime: ''
+						
+					}
+				],
+				scrollLeft: 0,
+				NavBarColor: this.NavBarColor,
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10, // 姣忛〉鏁版嵁鐨勬暟閲�
+
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				actionConfig: {
+					'unexecuted': [{
+						text: '瀹$悊',
+						type: 'reviewDocument',
+						path: '/pages/eam/quality/reviewDocument/reviewDocument'
+					}],
+				},
+				url: {
+					delete: "/pm/arrivalAdvice/delete",
+					sub: "/pm/arrivalAdvice/issue",
+					list: "/pm/arrivalAdvice/list"
+
+				},
+				placeholderStyle: "color:#2979FF;font-size:14px",
+				current: 0,
+				colorIndex: 0,
+				activeColor: '#5277A6',
+				msdDelList: [],
+				msgList: [], //鍒楄〃鏁版嵁
+				announcementList: []
+			}
+		},
+
+		computed: {
+			top() {
+				return this.CustomBar * 3 + 50
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+		methods: {
+			// 鏍规嵁鐘舵�佽幏鍙栧搴旂殑鎿嶄綔鎸夐挳
+			getActionButtons(status) {
+				switch (status) {
+					case '鏈墽琛�':
+					case 0:
+						return this.actionConfig.unexecuted;
+					default:
+						return this.actionConfig.unexecuted;
+				}
+			},
+
+			search(res) {
+				uni.showToast({
+					title: '鎼滅储锛�' + res.value,
+					icon: 'none'
+				})
+			},
+			input(res) {
+				console.log('----input:', res)
+			},
+			clear(res) {
+				console.log('clear浜嬩欢锛屾竻闄ゅ�间负锛�' + res.value)
+			},
+			/**
+			 * @param {Object} res
+			 * 褰撹緭鍏ユ澶卞幓鐒︾偣鏃惰Е鍙�
+			 */
+			blur(res) {
+				console.log('blur浜嬩欢锛岃緭鍏ュ�间负锛�' + res.value)
+
+			},
+			/**
+			 * @param {Object} e
+			 * 褰撹緭鍏ユ鑾峰緱鐒︾偣鏃惰Е鍙�
+			 */
+			focus(e) {
+				console.log('blur浜嬩欢锛岃緭鍏ュ�间负锛�' + e.value)
+
+			},
+			cancel(res) {
+				console.log('blur浜嬩欢锛岃緭鍏ュ�间负锛�' + res.value)
+			},
+
+
+			searBut() {
+
+				this.msgList = [];
+
+				this.$http.get(this.url.list, {
+					params: {
+						pageNo: 1,
+						pageSize: this.upOption.page.size,
+						num: this.formData.num,
+						column: "createTime",
+						order: "desc"
+
+					}
+				}).then(res => {
+					//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+			},
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+
+			// 鎸夐挳鐐瑰嚮澶勭悊
+			handleButtonClick(item, button) {
+				console.log('鐐瑰嚮鎸夐挳:', button.text, '宸ュ崟:', item.billNo);
+
+				switch (button.type) {
+					case 'reviewDocument':
+						// 瀹$悊
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					default:
+						uni.showToast({
+							title: '鍔熻兘寮�鍙戜腑',
+							icon: 'none'
+						});
+				}
+			},
+
+			upCallback(page) {
+				//鑱旂綉鍔犺浇鏁版嵁
+
+
+				this.$http.get(this.url.list, {
+					params: {
+						pageNo: page.num,
+						pageSize: page.size,
+						order: "desc",
+						column: "createTime"
+
+
+					}
+				}).then(res => {
+					//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					//console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+			},
+		}
+	}
+</script>
+
+<style>
+	<style scoped>.container {
+		background-color: #f5f5f5;
+		min-height: 100vh;
+	}
+
+	.tab-container {
+		background-color: #ffffff;
+	}
+
+	.production-container {
+		padding: 20rpx;
+	}
+
+	.bill-table {
+		background-color: #ffffff;
+		border-radius: 16rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+		overflow: hidden;
+	}
+
+	.table-content {
+		padding: 20rpx;
+	}
+
+	.table-row {
+		display: flex;
+		margin-bottom: 15rpx;
+	}
+
+	.table-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.table-header {
+		flex: 0 0 180rpx;
+		font-size: 28rpx;
+		color: #666;
+	}
+
+	.table-value {
+		flex: 1;
+		font-size: 28rpx;
+		color: #333;
+		display: flex;
+		align-items: center;
+	}
+
+	.right-content {
+		margin-left: auto;
+		color: #999;
+		font-size: 26rpx;
+	}
+
+	.status-tag {
+		padding: 6rpx 12rpx;
+		border-radius: 8rpx;
+		font-size: 24rpx;
+		background-color: #ff6347;
+		color: #ffffff;
+	}
+
+	.status-tag.passed {
+		background-color: #39b54a;
+	}
+	.status-tag.finish {
+		background-color: #ff0000;
+	}
+
+	.button-group {
+		display: flex;
+		flex-wrap: wrap;
+		gap: 15rpx;
+	}
+
+	.action-btn {
+		padding: 12rpx 20rpx;
+		font-size: 24rpx;
+		border-radius: 8rpx;
+		border: none;
+		background-color: #007AFF;
+		color: #ffffff;
+		min-width: 120rpx;
+		text-align: center;
+	}
+
+	/* 涓嶅悓鎿嶄綔鎸夐挳鐨勯鑹� */
+	.action-btn.check {
+		background-color: #007AFF;
+	}
+
+	.action-btn.process {
+		background-color: #39b54a;
+	}
+
+	.action-btn.device {
+		background-color: #9932cc;
+	}
+
+	.action-btn.sample {
+		background-color: #ff6347;
+	}
+
+	.action-btn.feed {
+		background-color: #ffa500;
+	}
+
+	.action-btn.report {
+		background-color: #1e90ff;
+	}
+
+	.action-btn.inspection {
+		background-color: #228b22;
+	}
+
+	.action-btn.detail {
+		background-color: #6a5acd;
+	}
+
+	.action-btn.record {
+		background-color: #808080;
+	}
+
+	.operation-row {
+		margin-top: 10rpx;
+		padding-top: 15rpx;
+		border-top: 1rpx solid #eee;
+	}
+
+	.empty-tip {
+		text-align: center;
+		padding: 100rpx 0;
+		color: #999;
+		font-size: 28rpx;
+	}
+
+	/* 鏍囩椤垫牱寮� */
+	.nav {
+		white-space: nowrap;
+		width: 100%;
+	}
+
+	.cu-item {
+		display: inline-block;
+		min-width: 150rpx;
+		padding: 0 30rpx;
+		height: 80rpx;
+		line-height: 80rpx;
+		text-align: center;
+	}
+
+	.cu-item.cur {
+		border-bottom: 4rpx solid #0081ff;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/quality/inspectionDetail/inspectionDetail.vue b/pages/eam/quality/inspectionDetail/inspectionDetail.vue
new file mode 100644
index 0000000..7262abb
--- /dev/null
+++ b/pages/eam/quality/inspectionDetail/inspectionDetail.vue
@@ -0,0 +1,456 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">妫�楠屾槑缁�</block>
+		</cu-custom>
+
+		<!-- 楠ㄦ灦灞� -->
+		<view v-if="loading" class="skeleton-container">
+			<view class="skeleton-list">
+				<!-- 閲嶅娓叉煋澶氫釜涓垪琛ㄩ」楠ㄦ灦 -->
+				<view class="skeleton-item" v-for="n in 4" :key="n">
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-detail-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-value"></view>
+					</view>
+					<view class="skeleton-action-row">
+						<view class="skeleton-label"></view>
+						<view class="skeleton-button"></view>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<!-- 瀹為檯鍐呭 -->
+		<view v-else class="container">
+			<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+				<!-- 鍒楄〃淇℃伅寮�濮� -->
+				<view class="content" style="margin: 10px;">
+					<view class="check-list-container">
+						<view class="list-item" v-for="(item, index) in checkList" :key="index">
+							<!-- 璇︾粏淇℃伅 -->
+							<view class="item-details">
+								<view class="detail-row">
+									<text class="label">搴忓彿:</text>
+									<text class="value">{{ item.paramCode}}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">瀹炴祴鍊�:</text>
+									<text class="value">{{ item.paramName }}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">鍒ゅ畾:</text>
+									<text class="value">{{ item.availableQty }}</text>
+								</view>
+
+								<view class="detail-row">
+									<text class="label">缂洪櫡浠g爜:</text>
+									<text class="value">{{ item.paramValue}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">缂洪櫡鎻忚堪:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">妫�楠屼汉:</text>
+									<text class="value">{{ item.judgment}}</text>
+								</view>
+								<view class="detail-row">
+									<text class="label">妫�楠屾椂闂�:</text>
+									<text class="value">{{ item.inspectionTime}}</text>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</mescroll-uni>
+		</view>
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				loading: true, // 鎺у埗楠ㄦ灦灞忔樉绀�
+				checkList: [{
+						paramCode: '01',
+						paramName: '3',
+						availableQty: '鍚堟牸',
+						paramValue: '01',
+						judgment: '鎹熷潖',
+						inspectionTime:'2025-07-28'
+					},
+					{
+						paramCode: '02',
+						paramName: '3',
+						availableQty: '鍚堟牸',
+						paramValue: '01',
+						judgment: '鎹熷潖',
+						inspectionTime:'2025-07-28'
+					},
+					{
+						paramCode: '03',
+						paramName: '3',
+						availableQty: '鍚堟牸',
+						paramValue: '01',
+						judgment: '鎹熷潖',
+						inspectionTime:'2025-07-28'
+					},
+					{
+						paramCode: '04',
+						paramName: '3',
+						availableQty: '鍚堟牸',
+						paramValue: '01',
+						judgment: '鎹熷潖',
+						inspectionTime:'2025-07-28'
+					}
+				],
+				scrollLeft: 0,
+				formData: {
+					num: '',
+					type: ''
+				},
+				NavBarColor: this.NavBarColor,
+				activeColor: '#5277A6',
+				url: {
+					flowType: "/sys/dict/getDictItems/flow_type",
+					stallList: "/assign/flow/toTaskBySelf"
+				},
+
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10 // 姣忛〉鏁版嵁鐨勬暟閲�
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				typeList: [],
+				msgList: [], //鍒楄〃鏁版嵁
+				announcement1: [],
+				msg1Count: 0,
+				msg2Count: 0,
+				msg1Title: ""
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 50
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+		onShow() {
+			if (this.mescroll) {
+				this.mescroll.resetUpScroll()
+			}
+		},
+
+		created() {
+			// 妯℃嫙鏁版嵁鍔犺浇寤惰繜锛屾樉绀洪鏋跺睆
+			setTimeout(() => {
+				this.loading = false;
+			}, 1500);
+		},
+		methods: {
+			upCallback(page) {
+				this.$http.get(this.url.stallList, {
+					params: {
+						pageNo: page.num,
+						pageSize: page.size,
+						order: 'desc',
+						column: 'createTime'
+					},
+				}).then(res => {
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+				})
+
+			},
+
+			// 閿佸畾鎿嶄綔
+			handleLock() {
+				uni.showToast({
+					title: '鎿嶄綔鎵ц涓�...',
+					icon: 'loading'
+				});
+
+				uni.navigateBack(1);
+
+			},
+
+			// 閫氱煡棰嗘枡鎿嶄綔
+			handleNotice() {
+				uni.navigateBack(1);
+			},
+
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+		},
+
+	}
+</script>
+
+<style>
+	/* 鍒楄〃瀹瑰櫒鏍峰紡 */
+	.check-list-container {
+		margin-bottom: 120rpx;
+		/* 涓哄簳閮ㄦ搷浣滄爮鐣欏嚭绌洪棿 */
+	}
+
+	/* 鍒楄〃椤规牱寮� */
+	.list-item {
+		background-color: #fff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+
+	/* 璇︾粏淇℃伅鏍峰紡 */
+	.item-details {
+		margin-bottom: 20rpx;
+	}
+
+	.detail-row {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 15rpx;
+	}
+
+	.detail-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.label {
+		font-size: 28rpx;
+		color: #666;
+		flex: 1;
+	}
+
+	.value {
+		font-size: 28rpx;
+		color: #333;
+		flex: 1;
+		text-align: right;
+	}
+
+	.warning-text {
+		color: #ff6347;
+		font-weight: bold;
+	}
+
+	/* 鍙紪杈戞牱寮� */
+	.editable {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+	}
+
+	.edit-input {
+		border: 1rpx solid #007AFF;
+		border-radius: 8rpx;
+		padding: 10rpx;
+		width: 120rpx;
+		text-align: right;
+		font-size: 28rpx;
+	}
+
+	.edit-icon {
+		margin-left: 10rpx;
+		color: #007AFF;
+		font-size: 24rpx;
+	}
+
+	/* 鎿嶄綔鎸夐挳鏍峰紡 */
+	.item-actions {
+		display: flex;
+		justify-content: flex-end;
+		gap: 20rpx;
+	}
+
+	.action-btn {
+		padding: 12rpx 24rpx;
+		font-size: 13rpx;
+		border-radius: 8rpx;
+		border: none;
+		min-width: 60rpx;
+	}
+
+	.edit-btn {
+		background-color: #007AFF;
+		color: #fff;
+	}
+
+	.delete-btn {
+		background-color: #ff6347;
+		color: #fff;
+	}
+
+	/* 搴曢儴鎿嶄綔鏍忔牱寮� */
+	.action-bar {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #fff;
+		padding: 20rpx;
+		display: flex;
+		justify-content: space-around;
+		box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
+		z-index: 999;
+	}
+
+	.operation-btn {
+		padding: 20rpx 40rpx;
+		font-size: 22rpx;
+		border-radius: 12rpx;
+		background-color: #007AFF;
+		color: #fff;
+		border: none;
+		flex: 1;
+		margin: 0 10rpx;
+	}
+	
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+	
+	/* 楠ㄦ灦灞忔牱寮� */
+	.skeleton-container {
+		padding: 20rpx;
+	}
+	
+	.skeleton-list {
+		width: 100%;
+	}
+	
+	.skeleton-item {
+		background-color: #ffffff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+	
+	.skeleton-detail-row {
+		display: flex;
+		margin-bottom: 15rpx;
+	}
+	
+	.skeleton-label {
+		width: 200rpx;
+		height: 28rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-value {
+		flex: 1;
+		height: 28rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-left: 20rpx;
+	}
+	
+	.skeleton-action-row {
+		display: flex;
+		align-items: center;
+		margin-top: 10rpx;
+	}
+	
+	.skeleton-button {
+		width: 120rpx;
+		height: 50rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-left: 20rpx;
+	}
+	
+	@keyframes skeleton-loading {
+		0% {
+			background-position: 100% 50%;
+		}
+		100% {
+			background-position: 0 50%;
+		}
+	}
+</style>
diff --git a/pages/eam/quality/productionInspection/productionInspection.vue b/pages/eam/quality/productionInspection/productionInspection.vue
new file mode 100644
index 0000000..681aeef
--- /dev/null
+++ b/pages/eam/quality/productionInspection/productionInspection.vue
@@ -0,0 +1,801 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">鐢熶骇妫�楠�</block>
+		</cu-custom>
+
+
+		<uni-card v-for="(item,index) in tableList" :key="index" margin="10px" spacing="1px">
+			<view class="flex">
+				<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">妫�楠岄」鍚嶇О:</view>
+				<view class=" bg-white padding-xs  margin-xs">
+					<uni-easyinput v-model="item.name" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex">
+				<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">鏈�澶у��:</view>
+				<view class="flex-sub bg-white padding-xs    margin-xs">
+
+
+					<uni-easyinput v-model="item.upperLimit" :disabled="true" />
+				</view>
+
+			</view>
+			<view class="flex">
+				<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">鏈�灏忓��:</view>
+				<view class="flex-sub bg-white padding-xs    margin-xs">
+					<uni-easyinput v-model="item.lowerLimit" :disabled="true" />
+
+
+				</view>
+			</view>
+
+
+			<view class="flex">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">瀹炴祴鍊�:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right">
+					<uni-number-box :max="99999" @change="changeText($event,item)" v-model="item.measuredValue" />
+				</view>
+			</view>
+
+			<view class="flex">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">鍒ゅ畾:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right">
+
+					<radio-group @change="radioChange" style="margin-left: 30rpx;">
+						<label style="margin-right: 20rpx;">
+							<radio :checked="item.result=='qualified'" value="qualified" />鍚堟牸
+						</label>
+
+						<label style="margin-right: 20rpx;">
+							<radio :checked="item.result=='unqualified'" value="unqualified" />涓嶅悎鏍�
+						</label>
+
+
+					</radio-group>
+
+				</view>
+			</view>
+
+
+			<view class="flex">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">缂洪櫡浠g爜:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right">
+					<uni-easyinput v-model="item.defectName" :disabled=true placeholder="璇疯緭鍏ョ己闄蜂唬鐮�" suffixIcon="search"
+						@iconClick="serialNumScan(index,item)" />
+				</view>
+			</view>
+
+
+			<view class="flex">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">缂洪櫡鎻忚堪:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right" :disabled=true>
+					<uni-easyinput v-model="item.defectDescription" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">妫�楠屼汉:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right" :disabled=true>
+					<uni-easyinput v-model="item.createBy" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">妫�楠屾椂闂�:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right" :disabled=true>
+					<uni-easyinput v-model="item.createTime" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex" v-show="isShow">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">鏄惁鑷姩鍒ゅ畾:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right" :disabled=true>
+					<uni-easyinput v-model="item.itemReference" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex" v-show="isShow">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">鏄惁鑷姩鍒ゅ畾:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right" :disabled=true>
+					<uni-easyinput v-model="item.id" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex" v-show="isShow">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">鏄惁鑷姩鍒ゅ畾:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right" :disabled=true>
+					<uni-easyinput v-model="item.inspectionId" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex" v-show="isShow">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">鏄惁鑷姩鍒ゅ畾:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right" :disabled=true>
+					<uni-easyinput v-model="item.inspectionSubId" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex" v-show="isShow">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">鏄惁鑷姩鍒ゅ畾:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right" :disabled=true>
+					<uni-easyinput v-model="item.itemId" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex" v-show="isShow">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">鏄惁鑷姩鍒ゅ畾:</view>
+				<view class="bg-white padding-xs margin-xs  radius text-right" :disabled=true>
+					<uni-easyinput v-model="item.productiveInspectionId" :disabled="true" />
+				</view>
+			</view>
+			<view class="flex">
+				<view class="flex-sub text-light bg-white padding-xs margin-xs radius">鎿嶄綔:</view>
+				<view class="flex-sub bg-blue padding-xs margin-xs radius text-sm text-center text-white"
+					v-if="item.createTime!=null" @click="productionEditor(item)">缂栬緫</view>
+				<view class="flex-sub bg-blue padding-xs margin-xs radius text-sm text-center text-white" v-else
+					@click="productionSub(item)">鎻愪氦</view>
+			</view>
+		</uni-card>
+
+		<view class="padding-xl">
+			<button class="cu-btn block bg-blue lg" @click="addDate">
+				<text class="cuIcon-add"></text>鏂板妫�娴嬪��</button>
+
+
+		</view>
+
+	</view>
+
+
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				num: '',
+				muber: '0',
+				isShow: false,
+				time: new Date().toUTCString(),
+				items: '',
+				current: '',
+				announcement1: [],
+				radioType: true,
+				releaseList: [{
+						value: 'qualified',
+						name: '鍚堟牸',
+						checked: 'true'
+
+					},
+					{
+						value: 'unqualified',
+						name: '涓嶅悎鏍�',
+						checked: 'true'
+
+					}
+				],
+
+				user: {
+
+
+				},
+				defectId: '',
+				applicant: '',
+				applicantName: '',
+				title: '',
+				tableList: [],
+				sheetId: '',
+				inspectionId: '',
+				inspectionSubId: '',
+				id: '',
+				mes: '',
+				cut: '',
+				createBy: '',
+				createTime: '',
+
+				itemId: '',
+				name: '',
+				upperLimit: '',
+				lowerLimit: '',
+				url: {
+
+					add: "qm/InspectionDetails/add",
+					list: "qm/InspectionDetails/query/findInspectionDetails",
+
+				}
+			}
+		},
+
+
+
+		onShow() {
+			let that = this
+			uni.$once('codeDefects', function(e) {
+				console.log('鐩戝惉鍒颁簨浠舵潵鑷� stallname 锛屾惡甯﹀弬鏁� msg 涓猴細', e.msg)
+				const annItems = JSON.parse(e.msg);
+				that.defectId = annItems.id
+				that.tableList[that.items].defectName = annItems.name
+				that.tableList[that.items].defectDescription = annItems.descreption
+			});
+		},
+
+		onLoad: function(option) {
+			this.applicant = this.$store.getters.staffId
+			this.applicantName = this.$store.getters.staffName
+			this.title = uni.getStorageSync('titlies')
+			console.log(this.title)
+			this.sheetId = option.workSheetId
+			this.inspectionType = option.inType
+			const annItem = JSON.parse(decodeURIComponent(option.item));
+			this.itemId = annItem.itemId
+			this.inspectionId = annItem.inspectionId
+			this.inspectionSubId = annItem.inspectionSubId
+			this.name = annItem.name
+			this.upperLimit = annItem.upperLimit
+			this.itemReference = annItem.itemReference
+			console.log(this.itemReference)
+			this.lowerLimit = annItem.lowerLimit
+			console.log(this.sheetId)
+
+			console.log(this.inspectionType)
+		},
+
+
+
+		created() {
+
+			this.searBut()
+
+		},
+		methods: {
+
+			changeText(event, item) {
+
+				this.num = event
+				//杈撳叆鐨勫��
+				/* alert(item.itemReference) */
+				console.log(item.itemReference)
+				if ("Y" == item.itemReference) {
+
+					if (item.upperLimit > this.num && this.num > item.lowerLimit) {
+						item.result = 'qualified';
+						this.current = 'qualified'
+
+					} else {
+						item.result = 'unqualified';
+						this.current = 'unqualified'
+					}
+				}
+
+
+
+
+			},
+			radioChange(evt) {
+
+				this.current = evt.detail.value
+				console.log(this.current)
+
+			},
+			searBut() {
+				if (this.tableList != null || this.tableList.length > 0) {
+					this.tableList = []
+				}
+
+				this.$http.get(this.url.list, {
+					params: {
+						workSheetId: this.sheetId,
+						inspectionType: this.inspectionType,
+						inspectionId: this.inspectionId,
+						inspectionSubId: this.inspectionSubId
+
+					}
+				}).then(res => {
+					//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+
+					this.announcement1 = res.data.result.records
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+
+						for (let annItem of this.announcement1) {
+							this.tableList.push(annItem)
+						}
+					}
+
+
+				}).catch(() => {
+
+				})
+
+
+
+
+			},
+
+
+
+
+
+
+
+			/**
+			 * 璺宠浆妫�娴嬪彿椤甸潰鏂规硶
+			 */
+			serialNumScan(index, item) {
+				this.items = index
+				uni.navigateTo({
+					url: "../../../qm/productiveinspection/productiveinspectionCompletion/codeDefects/codeDefects"
+				})
+
+			},
+
+
+
+			productionSub(item) {
+				console.log(item.defectName)
+				this.$http.put(this.url.add, {
+					defectDescription: item.defectDescription,
+					defectId: this.defectId,
+					defectName: item.defectName,
+					inspectionId: this.inspectionId,
+					inspectionSubId: this.inspectionSubId,
+					inspectionType: this.inspectionType,
+					itemId: this.itemId,
+					itemReference: this.itemReference,
+					lowerLimit: this.lowerLimit,
+					measuredValue: item.measuredValue,
+					name: item.name,
+					productiveInspectionId: this.productiveInspectionId,
+					result: item.result,
+					upperLimit: item.upperLimit,
+					workSheetId: this.sheetId,
+					/* defectDescription: item.defectDescription,
+					defectId: this.defectId,
+					defectName: item.defectName,
+					inspectionId: item.inspectionId,
+					inspectionSubId: item.inspectionSubId,
+					inspectionType: this.inspectionType,
+					itemId: item.itemId,
+					itemReference: this.itemReference,
+					lowerLimit: this.lowerLimit,
+					measuredValue: item.measuredValue,
+					name: item.name,
+					productiveInspectionId: item.productiveInspectionId,
+					result: item.result,
+					upperLimit: item.upperLimit,
+					workSheetId: this.sheetId, */
+
+				}).then(res => {
+
+					//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+					this.mes = res.data.message
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						uni.showToast({
+							icon: "none",
+							title: this.mes,
+							duration: 2000
+						});
+						this.searBut();
+
+					} else {
+						uni.showToast({
+							icon: "none",
+							title: this.mes,
+							duration: 2000
+						});
+
+					}
+
+
+				}).catch(() => {
+
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+
+			},
+			productionEditor(item) {
+				console.log(item.id)
+				console.log(item.id)
+				debugger
+				if (this.defectId == null || this.defectId == '') {
+					this.defectId = item.defectId
+				}
+
+				this.$http.put(this.url.add, {
+					id: item.id,
+					createBy: item.createBy,
+					createTime: item.createTime,
+					defectDescription: item.defectDescription,
+					defectId: this.defectId,
+					defectName: item.defectName,
+					inspectionId: item.inspectionId,
+					inspectionSubId: item.inspectionSubId,
+					inspectionType: this.inspectionType,
+					itemId: item.itemId,
+					itemReference: item.itemReference,
+					lowerLimit: this.lowerLimit,
+					measuredValue: item.measuredValue,
+					name: item.name,
+					productiveInspectionId: item.productiveInspectionId,
+					result: item.result,
+					upperLimit: item.upperLimit,
+					workSheetId: this.sheetId
+				}).then(res => {
+
+					//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+					this.mes = res.data.message
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						uni.showToast({
+							icon: "none",
+							title: this.mes,
+							duration: 2000
+						});
+						this.searBut();
+
+					} else {
+						uni.showToast({
+							icon: "none",
+							title: this.mes,
+							duration: 2000
+						});
+
+					}
+
+
+				}).catch(() => {
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+
+			},
+
+
+
+
+
+
+
+			addDate() {
+
+				this.user.name = this.name
+				this.user.upperLimit = this.upperLimit
+				this.user.lowerLimit = this.lowerLimit
+				this.user.itemReference = this.itemReference
+				this.tableList.push(this.user)
+
+			},
+
+
+		}
+	}
+</script>
+
+<style>
+	.container {
+
+		background: white;
+	}
+
+	.title {
+
+		display: block;
+		font-size: 14px;
+		padding: 10px;
+		color: black;
+		padding-left: 20px;
+		color: #1890FF;
+
+
+	}
+
+	.first_tab {
+		background-color: #fff;
+		border-radius: 10rpx;
+		box-shadow: 2rpx 2rpx 2rpx 2rpx #eeeeee;
+		border: 2rpx solid #ccc;
+		width: 100%-40rpx;
+		margin-left: 20rpx;
+		margin-right: 20rpx;
+		margin-top: 20px;
+
+		/* display: flex; */
+		/* flex-direction: row;
+		align-items: center;
+		justify-content: space-between; */
+	}
+
+
+	.button-yuanjiao {
+		height: 50rpx;
+		display: flex;
+		margin-top: 10rpx;
+		line-height: 50rpx;
+		justify-content: center;
+		border-radius: 5px;
+		color: #fff;
+		/* 杩欓噷鍙互鏀规垚娓愬彉锛� background:linear-gradient(to right, #FFDE28,#FF3228) */
+		background-color: #5CBB67;
+		font-size: 28rpx;
+	}
+
+	.button-stop {
+		height: 50rpx;
+		display: flex;
+		margin-top: 10rpx;
+		line-height: 50rpx;
+		justify-content: center;
+		border-radius: 5px;
+		color: #fff;
+		/* 杩欓噷鍙互鏀规垚娓愬彉锛� background:linear-gradient(to right, #FFDE28,#FF3228) */
+		background-color: #EE1E23;
+		font-size: 28rpx;
+	}
+
+	.margin-bottom {
+		margin-top: 5px;
+		margin-left: 10px;
+		margin-right: 10px;
+		margin-bottom: 0px;
+	}
+
+	.button-end {
+		height: 50rpx;
+		display: flex;
+		margin-top: 10rpx;
+		line-height: 50rpx;
+		justify-content: center;
+		border-radius: 5px;
+		color: #fff;
+		/* 杩欓噷鍙互鏀规垚娓愬彉锛� background:linear-gradient(to right, #FFDE28,#FF3228) */
+		background-color: #F79B4D;
+		font-size: 28rpx;
+	}
+
+
+	/* 鐢熸垚浠诲姟 */
+	.footer-box {
+		padding: 10rpx;
+		display: flex;
+		justify-content: space-between;
+		flex-direction: row;
+	}
+
+	.box_ta {
+		margin-top: 10px;
+		padding: 5px;
+		text-align: center;
+		border: 2px dashed gainsboro;
+		width: 100%;
+	}
+
+	.bg-click {
+
+		color: #666;
+	}
+
+	.uni-collapse-item__wrap.is--transition[data-v-41027c34] {
+
+		height: 990px;
+	}
+
+	.line {
+
+		height: 10rpx;
+		background-color: #E1E1E1;
+		width: 100%;
+	}
+
+	.task_title {
+
+		display: flex;
+		justify-content: space-between;
+		padding: 10px 10px;
+	}
+
+	.task_title .task_title_left {
+		font-weight: 800;
+		font-size: 30rpx;
+		margin-left: 10px;
+	}
+
+	.task_title .task_title_right {
+		display: flex;
+		align-items: center;
+
+	}
+
+	.task_title .task_title_right .task_title_icon {
+		width: 15px;
+		height: 15px;
+		margin-right: 5px;
+	}
+
+	.task_title .task_title_right .task_title_icon image {
+
+		width: 100%;
+		height: 100%;
+	}
+
+	.task_content {
+		display: flex;
+		width: 80%;
+		margin-top: 10px;
+	}
+
+	.task_content .task_name {
+		width: auto;
+		color: #857e7e;
+	}
+
+	.task_bottom_left_name {
+		margin-left: 5px;
+	}
+
+	.task_content .tt {
+		padding: 5px;
+		text-align: left;
+	}
+
+	.task_content .task_key {
+		flex: 1;
+	}
+
+	.task_line {
+		width: 100%;
+		height: 2px;
+		border: 1px dashed #E1E1E1;
+	}
+
+	.task_bottom {
+		display: flex;
+		justify-content: space-between;
+		padding: 0 10px;
+		margin-top: 10px;
+		margin-bottom: 10px;
+		height: 20px;
+	}
+
+	.task_bottom .task_bottom_left {
+		display: flex;
+		color: #a19797;
+		align-items: center;
+	}
+
+	.task_bottom .task_bottom_left .task_bottom_left_icon {
+		width: 15px;
+		margin-left: 10px;
+		height: 15px;
+	}
+
+	.task_bottom .task_bottom_left .task_bottom_left_icon image {
+		width: 100%;
+		height: 100%
+	}
+
+	.task_bottom .task_bottom_right {
+		/* background-color: #15a515; */
+		/* 	border-radius: 5px; */
+		width: 60px;
+		font-size: 18rpx;
+		text-align: center;
+		height: 100%;
+		background-size: 100% 100%;
+		color: #fff;
+		padding: 5px;
+		display: flex;
+		align-items: center;
+	}
+
+	.task_bottom .task_bottom_right .task_bottom_right_button {
+		width: 100%;
+	}
+
+	.first_tab {
+		background-color: #fff;
+		border-radius: 10rpx;
+		box-shadow: 2rpx 2rpx 2rpx 2rpx #eeeeee;
+		border: 2rpx solid #ccc;
+		width: 100%-40rpx;
+		margin-left: 20rpx;
+		margin-right: 20rpx;
+		margin-top: 10rpx;
+
+		/* display: flex; */
+		/* flex-direction: row;
+		align-items: center;
+		justify-content: space-between; */
+	}
+
+	.tt {
+		line-height: 50rpx;
+	}
+
+	.ttt {
+		font-size: 30rpx;
+		font-weight: 800;
+	}
+
+	.task_name {
+		font-size: 24rpx;
+		margin-left: 32rpx;
+		padding: 20rpx 0;
+	}
+
+	.task_key {
+		margin-left: 20px;
+		font-size: 24rpx;
+		padding: 20rpx 0;
+	}
+
+	.task_key view {
+		color: #;
+		text-align: right;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	.search_row {
+
+		height: 120rpx;
+		display: flex;
+		background-color: #F1F1F1;
+		padding: 20rpx;
+	}
+
+	.task_key view.ttstatus {
+
+		color: #4082ff;
+	}
+
+	.footer {
+		color: #fff;
+		line-height: 100rpx;
+		flex: 0 0 100rpx;
+		/* 涓嶆斁澶т笉缂╁皬鍥哄畾100rpx */
+	}
+
+	.table-main {
+		overflow: auto;
+	}
+
+
+	.scroll-view_H {
+		width: 200%;
+		display: flex;
+		flex-wrap: nowrap;
+	}
+
+	table {
+		border-collapse: collapse;
+		margin: 0 auto;
+		text-align: center;
+	}
+
+	table td,
+	table th {
+		border: 1px solid #cad9ea;
+		color: #666;
+		height: 30px;
+	}
+
+	table thead th {
+		background-color: #CCE8EB;
+		width: 100px;
+	}
+
+	table tr:nth-child(odd) {
+		background: #fff;
+	}
+
+	table tr:nth-child(even) {
+		background: #F5FAFA;
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/quality/qualityInspection/addInspection/addInspection.vue b/pages/eam/quality/qualityInspection/addInspection/addInspection.vue
new file mode 100644
index 0000000..a99d53d
--- /dev/null
+++ b/pages/eam/quality/qualityInspection/addInspection/addInspection.vue
@@ -0,0 +1,446 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">鏂板-鐢熶骇妫�楠�</block>
+		</cu-custom>
+		
+		<!-- 楠ㄦ灦灞� -->
+		<view v-if="loading" class="skeleton-container">
+			<view class="skeleton-group">
+				<view class="skeleton-divider"></view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+			</view>
+			
+			<view class="skeleton-group">
+				<view class="skeleton-divider"></view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-datetime"></view>
+				</view>
+			</view>
+			
+			<view class="skeleton-button"></view>
+		</view>
+		
+		<!-- 瀹為檯鍐呭 -->
+		<view v-else class="container">
+			<uni-forms 
+				ref="form" 
+				:modelValue="formData" 
+				:rules="rules" 
+			validate-trigger="bind" 
+				err-show-type="undertext">
+				<uni-group top="1">
+					<view class="divider"><text>宸ュ崟淇℃伅</text></view>
+					<uni-forms-item :label-width="100" name="workOrderNumber" label="宸ュ崟缂栫爜:">
+						<uni-easyinput v-model="formData.workOrderNumber" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="materialCode" label="鐗╂枡缂栫爜:">
+						<uni-easyinput v-model="formData.materialCode" :disabled="true" />
+					</uni-forms-item>
+
+					<uni-forms-item :label-width="100" name="materialDescription" label="鐗╂枡鎻忚堪:">
+						<uni-easyinput v-model="formData.materialDescription" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="璁″垝鏁伴噺:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+
+					<view class="divider"><text>妫�楠屼俊鎭�</text></view>
+
+					<uni-forms-item  :label-width="140" required name="inspectionOrderNumber"
+						label="妫�楠屽崟鍙�:">
+						<uni-easyinput v-model="formData.inspectionOrderNumber" placeholder="绯荤粺鐢熸垚" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="process" label="宸ュ簭">
+						<uni-data-select v-model="formData.process" :localdata="SpareList" @change="changeisSpareList"
+							placeholder="璇烽�夋嫨" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="inspectionType" label="妫�楠岀被鍨�">
+						<uni-data-select v-model="formData.inspectionType" :localdata="SpareList"
+							@change="changeisSpareList" placeholder="璇烽�夋嫨" />
+					</uni-forms-item>
+					<uni-forms-item  :label-width="140" required name="inspectionQuantity" label="閫佹鏁伴噺:">
+						<uni-number-box v-model="formData.inspectionQuantity" placeholder="绯荤粺鐢熸垚" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="inspectionPlan" label="妫�楠屾柟妗�">
+						<uni-data-select v-model="formData.inspectionPlan" :localdata="SpareList"
+							@change="changeisSpareList" placeholder="璇烽�夋嫨" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="inspectionTime" label="妫�楠屾椂闂�">
+						<uni-datetime-picker type="datetime" v-model="formData.inspectionTime" />
+					</uni-forms-item>
+				</uni-group>
+			</uni-forms>
+
+			<view class="padding flex flex-direction">
+				<view class="flex-sub bg-blue padding-sm margin-xl radius text-sm text-center text-white"
+					@click.stop="ProductionTask()" hover-class="is-hover">纭畾</view>
+			</view>
+		</view>
+		
+		<pdaScanVue></pdaScanVue>
+	</view>
+</template>
+
+<script>
+	import pdaScanVue from "@/components/mes/pdaScan.vue";
+
+	export default {
+		components: {
+			pdaScanVue
+		},
+		data() {
+			return {
+				loading: true,
+				isShow: false,
+				isSubmitting: false, // 闃查噸澶嶆彁浜�
+				SpareList: [{
+						text: "鏄�",
+						value: 1
+					},
+					{
+						text: "鍚�",
+						value: 0
+					}
+				],
+				scrollLeft: 0,
+				formData: {
+					workOrderNumber: '1111111',
+					materialCode: '120008194',
+					materialDescription: '涓変唬杞瘋杞存壙鍗曞厓\\G3-487',
+					plannedQuantity: '200',
+					inspectionOrderNumber: '88888',
+					process: '',
+					inspectionType: '',
+					inspectionQuantity: '',
+					inspectionPlan: '',
+					inspectionTime: ''
+				},
+				// 琛ㄥ崟楠岃瘉瑙勫垯
+				rules: {
+					process: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨宸ュ簭'
+						}]
+					},
+					inspectionType: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠岀被鍨�'
+						}]
+					},
+					inspectionPlan: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠屾柟妗�'
+						}]
+					},
+					inspectionTime: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠屾椂闂�'
+						}]
+					},
+					inspectionQuantity: {
+						rules: [{
+							required: true,
+							errorMessage: '璇疯緭鍏ラ�佹鏁伴噺'
+						}, {
+							format: 'number',
+							errorMessage: '閫佹鏁伴噺蹇呴』涓烘暟瀛�'
+						}]
+					}
+				},
+				NavBarColor: this.NavBarColor,
+				url: {
+					upload: "/eam/sysFiles/batch_upload",
+					stallList: "/eam/eamRepairOrder/queryById",
+					getEquipmentList: 'eam/equipment/list',
+					approval: '/eam/eamRepairOrder/perform'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				msg1Count: 0
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 160
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+		created() {
+			// 妯℃嫙鏁版嵁鍔犺浇
+			setTimeout(() => {
+				this.loading = false;
+			}, 1000);
+		},
+		methods: {
+			changeisSpareList(e) {
+				this.formData.isSpare = e;
+			
+			},
+			
+			async ProductionTask() {
+				// 闃叉閲嶅鎻愪氦
+				if (this.isSubmitting) {
+					uni.showToast({
+						icon: "none",
+						title: "姝e湪鎻愪氦涓紝璇峰嬁閲嶅鐐瑰嚮",
+						duration: 2000
+					});
+					return;
+				}
+				
+				uni.showLoading({
+					mask: true,
+					title: "鎻愪氦涓�..."
+				});
+				
+				try {
+					// 浣跨敤 uni-forms 杩涜琛ㄥ崟楠岃瘉
+					await this.$refs.form.validate();
+					
+					this.isSubmitting = true;
+					
+					// 鍙戦�佽姹�
+					const response = await this.$http.post(this.url.approval, {
+						workOrderNumber: this.formData.workOrderNumber,
+						materialCode: this.formData.materialCode,
+						materialDescription: this.formData.materialDescription,
+						plannedQuantity: this.formData.plannedQuantity,
+						inspectionOrderNumber: this.formData.inspectionOrderNumber,
+						process: this.formData.process,
+						inspectionType: this.formData.inspectionType,
+						inspectionQuantity: this.formData.inspectionQuantity,
+						inspectionPlan: this.formData.inspectionPlan,
+						inspectionTime: this.formData.inspectionTime
+					});
+					
+					if (response.data.success) {
+						uni.showToast({
+							icon: "success",
+							title: '鎻愪氦鎴愬姛',
+							duration: 2000
+						});
+						
+						// 寤惰繜璺宠浆
+						await new Promise(resolve => setTimeout(resolve, 2000));
+						
+						this.$Router.replaceAll({
+							name: 'qualityInspection'
+						});
+					} else {
+						uni.showModal({
+							title: "鎻愪氦澶辫触",
+							content: response.data.message || "鏈嶅姟鍣ㄥ鐞嗗け璐ワ紝璇风◢鍚庨噸璇�",
+							confirmText: '纭畾',
+							showCancel: false,
+							icon: "none"
+						});
+					}
+				} catch (error) {
+					// 琛ㄥ崟楠岃瘉澶辫触鎴栧叾浠栭敊璇�
+					if (error.errMsg) {
+						// 杩欐槸 uni-forms 鐨勯獙璇侀敊璇�
+						uni.showToast({
+							icon: "none",
+							title: error,
+							duration: 2000
+						});
+					} else {
+						// 缃戠粶鎴栧叾浠栭敊璇�
+						console.error("璇锋眰澶辫触:", error);
+						
+						let errorMessage = "缃戠粶璇锋眰澶辫触";
+						if (error.errMsg) {
+							if (error.errMsg.includes("timeout")) {
+								errorMessage = "璇锋眰瓒呮椂锛岃妫�鏌ョ綉缁滆繛鎺�";
+							} else if (error.errMsg.includes("fail")) {
+								errorMessage = "缃戠粶杩炴帴澶辫触锛岃妫�鏌ョ綉缁滆缃�";
+							}
+						}
+						
+						uni.showToast({
+							icon: "none",
+							title: errorMessage,
+							duration: 3000
+						});
+					}
+				} finally {
+					this.isSubmitting = false;
+					uni.hideLoading();
+				}
+			},
+		},
+	}
+</script>
+
+<style>
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+
+	.divider {
+		display: flex;
+		font-weight: bold;
+		align-items: center;
+		text-align: center;
+		color: #1E90FF;
+		font-size: 24rpx;
+		margin: 20px 0;
+	}
+
+	.divider::before,
+	.divider::after {
+		content: '';
+		flex: 1;
+		border-bottom: 1px solid gray;
+		margin: 0 16px;
+	}
+
+	.divider text {
+		white-space: nowrap;
+	}
+
+	.content {
+		margin-top: 5px;
+	}
+
+	.content scroll-view {
+		scrollIndicator: "none"
+	}
+
+	.popupView {
+		margin-top: 45px;
+		height: auto;
+	}
+	
+	/* 楠ㄦ灦灞忔牱寮� */
+	.skeleton-container {
+		padding: 20rpx;
+	}
+	
+	.skeleton-group {
+		margin-bottom: 40rpx;
+	}
+	
+	.skeleton-divider {
+		height: 40rpx;
+		width: 300rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-bottom: 30rpx;
+	}
+	
+	.skeleton-item {
+		display: flex;
+		align-items: center;
+		margin-bottom: 30rpx;
+	}
+	
+	.skeleton-label {
+		width: 160rpx;
+		height: 40rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-right: 20rpx;
+	}
+	
+	.skeleton-input {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-select {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-datetime {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-button {
+		width: 90%;
+		height: 80rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 10rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin: 40rpx auto;
+	}
+	
+	@keyframes skeleton-loading {
+		0% {
+			background-position: 100% 50%;
+		}
+		100% {
+			background-position: 0 50%;
+		}
+	}
+</style>
diff --git a/pages/eam/quality/qualityInspection/qualityInspection.vue b/pages/eam/quality/qualityInspection/qualityInspection.vue
new file mode 100644
index 0000000..f360196
--- /dev/null
+++ b/pages/eam/quality/qualityInspection/qualityInspection.vue
@@ -0,0 +1,780 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">璐ㄩ噺妫�楠�</block>
+			<block slot="right">
+				<view @click="handleAdd">
+					<image class="search" src="/static/icon/add.png" style="width: 25px; height: 25px;" alt="娣诲姞" />
+				</view>
+			</block>
+		</cu-custom>
+
+		<uni-search-bar placeholder="妫�楠屽崟鍙�/鐗╂枡淇℃伅" @confirm="search" :focus="false" v-model="searchValue" 
+			@blur="blur" @focus="focus" @input="input" @cancel="cancel" @clear="clear">
+		</uni-search-bar>
+		
+		<!-- 楠ㄦ灦灞� -->
+		<view v-if="loading" class="skeleton-container">
+			<!-- 鍒楄〃楠ㄦ灦 -->
+			<view class="skeleton-list">
+				<!-- 閲嶅娓叉煋澶氫釜鍒楄〃椤归鏋� -->
+				<view class="skeleton-bill-item" v-for="n in 5" :key="n">
+					<view class="skeleton-bill-row">
+						<view class="skeleton-bill-label"></view>
+						<view class="skeleton-bill-value"></view>
+					</view>
+					<view class="skeleton-bill-row">
+						<view class="skeleton-bill-label"></view>
+						<view class="skeleton-bill-value"></view>
+					</view>
+					<view class="skeleton-bill-row">
+						<view class="skeleton-bill-label"></view>
+						<view class="skeleton-bill-value short"></view>
+					</view>
+					<view class="skeleton-bill-row">
+						<view class="skeleton-bill-label"></view>
+						<view class="skeleton-bill-value"></view>
+					</view>
+					<view class="skeleton-bill-row">
+						<view class="skeleton-bill-label"></view>
+						<view class="skeleton-bill-value flex">
+							<view class="skeleton-half"></view>
+							<view class="skeleton-half ml-auto"></view>
+						</view>
+					</view>
+					<view class="skeleton-bill-row">
+						<view class="skeleton-bill-label"></view>
+						<view class="skeleton-status-tag"></view>
+					</view>
+					<view class="skeleton-bill-row">
+						<view class="skeleton-bill-label"></view>
+						<view class="skeleton-bill-value"></view>
+					</view>
+					<view class="skeleton-bill-row operation">
+						<view class="skeleton-bill-label"></view>
+						<view class="skeleton-buttons">
+							<view class="skeleton-btn"></view>
+							<view class="skeleton-btn ml-2"></view>
+							<view class="skeleton-btn ml-2"></view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		<!-- 瀹為檯鍐呭 -->
+		<mescroll-uni v-else ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+			<view class="production-container">
+				<view class="bill-table" v-for="(item, index) in mockBillList" :key="index">
+					<!-- 琛ㄥご锛堝叡鐢ㄦ牱寮忥級 -->
+					<view class="table-content">
+						<!-- 鍗曟嵁鍙疯 -->
+						<view class="table-row">
+							<text class="table-header">妫�楠屽崟鍙凤細</text>
+							<text class="table-value">{{item.billNo || item.num}}</text>
+						</view>
+						<!-- 鐗╂枡缂栫爜琛� -->
+						<view class="table-row">
+							<text class="table-header">鐗╂枡淇℃伅锛�</text>
+							<text class="table-value">{{item.materialCode}}</text>
+						</view>
+						<!-- 鐗╂枡鎻忚堪琛� -->
+						<view class="table-row">
+							<text class="table-header">妫�楠岀被鍨嬶細</text>
+							<text class="table-value">{{item.materialDesc}}</text>
+						</view>
+						<!-- 浜х嚎琛� -->
+						<view class="table-row">
+							<text class="table-header">妫�楠屾柟妗堬細</text>
+							<text class="table-value">{{item.productionLine}}</text>
+						</view>
+						<!-- 鐝粍琛� -->
+						<view class="table-row">
+							<text class="table-header">妫�楠屾暟閲忥細</text>
+							<text class="table-value">{{item.team}}</text>
+						</view>
+						<!-- 鐢熶骇鏃ユ湡琛岋紙澶氬唴瀹癸級 -->
+						<view class="table-row">
+							<text class="table-header">鍚堟牸鏁伴噺锛�</text>
+							<view class="table-value">
+								<text>{{item.produceDate}}</text>
+								<text class="right-content">涓嶅悎鏍兼暟閲忥細{{item.planQty}}</text>
+							</view>
+						</view>
+						<!-- 妫�楠岃褰曡 -->
+						<view class="table-row">
+							<text class="table-header">妫�楠岀姸鎬侊細</text>
+							<view class="table-value">
+								<text class="status-tag"
+									:class="[{ passed: item.inspectResult === '鎵ц涓�' },{ failed: item.inspectResult === '宸插畬鎴�' }]">
+									{{item.inspectResult}}
+								</text>
+							</view>
+						</view>
+						<!-- 涓婃枡淇℃伅琛岋紙澶氬唴瀹癸級 -->
+						<view class="table-row">
+							<text class="table-header">妫�楠屾椂闂达細</text>
+							<text class="table-value">{{item.team}}</text>
+						</view>
+						<view class="table-row">
+							<text class="table-header">澶勭悊缁撴灉锛�</text>
+							<text class="table-value">{{item.team}}</text>
+						</view>
+
+						<!-- 鎿嶄綔琛� -->
+						<view class="table-row operation-row">
+							<text class="table-header">鎿嶄綔锛�</text>
+							<view class="table-value">
+								<view class="button-group">
+									<button class="action-btn" v-for="btn in getActionButtons(item.inspectResult)"
+										:key="btn.type" @click="handleButtonClick(item, btn)" :class="btn.type">
+										{{btn.text}}
+									</button>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</mescroll-uni>
+		<pdaScan />
+	</view>
+</template>
+
+<script>
+	import pdaScan from "@/components/mes/pdaScan.vue"
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin],
+		components: {
+			pdaScan
+		},
+		data() {
+			return {
+				loading: true, // 鎺у埗楠ㄦ灦灞忔樉绀�
+				actionConfig: {
+					// 鏈墽琛岀姸鎬佷笅鐨勬搷浣滄寜閽�
+					'unexecuted': [{
+							text: '璇︽儏',
+							type: 'check',
+							path: '/pages/eam/quality/qualityInspectionDetail/qualityInspectionDetail'
+						},
+						{
+							text: '鍒犻櫎',
+							type: 'delete',
+							action: 'delete'
+						},
+						{
+							text: '妫�楠�',
+							type: 'device',
+							path: '/pages/eam/quality/checkItem/checkItem'
+						}
+
+					],
+					// 鎵ц涓姸鎬佷笅鐨勬搷浣滄寜閽�
+					'executing': [{
+							text: '妫�楠�',
+							type: 'device',
+							path: '/pages/eam/quality/checkItem/checkItem'
+						}
+
+					],
+					// 宸插畬鎴愮姸鎬佷笅鐨勬搷浣滄寜閽�
+					'completed': [{
+							text: '妫�楠屾槑缁�',
+							type: 'detail',
+							path: '/pages/eam/quality/checkItemDetail/checkItemDetail'
+						},
+
+					]
+				},
+				mockBillList: [{
+						billNo: 'SCGD202507001',
+						materialCode: '220005874',
+						materialDesc: '澶栨硶鍏癨\G3-487/01',
+						spec: '桅120脳30mm',
+						productionLine: '鐑鐞嗙粍',
+						team: '寮犳澃鐝粍',
+						produceDate: '2025-07-10',
+						planQty: 500,
+						actualQty: 480,
+						inspectResult: '鏈楠�',
+						feedQty: 200,
+						feeder: '鐜嬬帀',
+						feedTime: '2025-07-10 08:30',
+						status: '鐢熶骇涓�'
+					},
+					{
+						billNo: 'SCGD202507002',
+						materialCode: '120008194',
+						materialDesc: '涓変唬杞暀杞磋酱鎵垮崟鍏僜\G3-487',
+						spec: '鍨嬪彿305',
+						productionLine: '瑁呴厤涓�绾�',
+						team: '寮犳澃鐝粍',
+						produceDate: '2025-07-10',
+						planQty: 200,
+						actualQty: 200,
+						inspectResult: '鎵ц涓�',
+						feedQty: 200,
+						feeder: '寮犳澃',
+						feedTime: '2025-07-10 09:15',
+						status: '宸插畬鎴�'
+					},
+					{
+						billNo: 'SCGD202507003',
+						materialCode: '330012456',
+						materialDesc: '杞悜鑺傝噦\\G3-500',
+						spec: 'L=210mm',
+						productionLine: '鏈哄姞宸ヤ簩绾�',
+						team: '鏉庡崕鐝粍',
+						produceDate: '2025-07-11',
+						planQty: 300,
+						actualQty: 150,
+						inspectResult: '宸插畬鎴�',
+						feedQty: 150,
+						feeder: '璧垫槑',
+						feedTime: '2025-07-11 10:00',
+						status: '鐢熶骇涓�'
+					},
+					{
+						billNo: 'SCGD202507004',
+						materialCode: '440009876',
+						materialDesc: '鍗婅酱濂楃\\G3-620',
+						spec: '桅89脳1200mm',
+						productionLine: '閿婚�犵嚎',
+						team: '鐜嬪己鐝粍',
+						produceDate: '2025-07-11',
+						planQty: 100,
+						actualQty: 0,
+						inspectResult: '宸插畬鎴�',
+						feedQty: 0,
+						feeder: '',
+						feedTime: '',
+						status: '寰呯敓浜�'
+					},
+					{
+						billNo: 'SCGD202507005',
+						materialCode: '550010345',
+						materialDesc: '鍒跺姩鐩榎\G3-450',
+						spec: '桅350mm',
+						productionLine: '鏈哄姞宸ヤ竴绾�',
+						team: '鍒樻檽鐝粍',
+						produceDate: '2025-07-09',
+						planQty: 400,
+						actualQty: 400,
+						inspectResult: '宸插畬鎴�',
+						feedQty: 400,
+						feeder: '瀛欎紵',
+						feedTime: '2025-07-09 14:20',
+						status: '宸插畬鎴�'
+					}
+				],
+				searchValue: '',
+				scrollLeft: 0,
+				NavBarColor: this.NavBarColor,
+				upOption: {
+					page: {
+						num: 0,
+						size: 10,
+					},
+					noMoreSize: 4,
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~',
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+
+				url: {
+					delete: "/pm/arrivalAdvice/delete",
+					sub: "/pm/arrivalAdvice/issue",
+					list: "/pm/arrivalAdvice/list",
+
+				},
+				placeholderStyle: "color:#2979FF;font-size:14px",
+				current: 0,
+				colorIndex: 0,
+				activeColor: '#5277A6',
+				msdDelList: [],
+				msgList: [],
+				announcementList: [],
+			}
+		},
+
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 100
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+		
+		created() {
+			// 妯℃嫙鏁版嵁鍔犺浇寤惰繜锛屾樉绀洪鏋跺睆
+			setTimeout(() => {
+				this.loading = false;
+			}, 1500);
+		},
+
+		methods: {
+			getActionButtons(status) {
+				switch (status) {
+					case '鏈楠�':
+					case 0:
+						return this.actionConfig.unexecuted;
+					case '鎵ц涓�':
+					case 1:
+						return this.actionConfig.executing;
+					case '宸插畬鎴�':
+					case 2:
+						return this.actionConfig.completed;
+					default:
+						return this.actionConfig.unexecuted;
+				}
+			},
+			handleAdd() {
+				uni.redirectTo({
+					url: '/pages/eam/quality/qualityInspection/addInspection/addInspection'
+				})
+			},
+			search(res) {
+				uni.showToast({
+					title: '鎼滅储锛�' + res.value,
+					icon: 'none'
+				})
+			},
+			input(res) {
+				console.log('----input:', res)
+			},
+			clear(res) {
+				console.log('clear浜嬩欢锛屾竻闄ゅ�间负锛�' + res.value)
+			},
+			blur(res) {
+				console.log('blur浜嬩欢锛岃緭鍏ュ�间负锛�' + res.value)
+			},
+			focus(e) {
+				console.log('focus浜嬩欢锛岃緭鍏ュ�间负锛�' + e.value)
+			},
+			cancel(res) {
+				console.log('cancel浜嬩欢锛岃緭鍏ュ�间负锛�' + res.value)
+			},
+
+
+			mescrollInit(mescroll) {
+				console.log('mescrollInit')
+				this.mescroll = mescroll;
+			},
+			handleButtonClick(item, button) {
+				console.log('鐐瑰嚮鎸夐挳:', button.text, '宸ュ崟:', item.billNo);
+
+				switch (button.type) {
+					case 'check':
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					case 'device':
+						uni.navigateTo({
+							url: button.path
+						});
+						break;
+					case 'delete':
+						this.handleDelete(item);
+						break;
+					case 'detail':
+						uni.navigateTo({
+							url: button.path + '?billNo=' + item.billNo
+						});
+						break;
+					default:
+						uni.showToast({
+							title: '鍔熻兘寮�鍙戜腑',
+							icon: 'none'
+						});
+				}
+			},
+			handleDelete(item) {
+				uni.showModal({
+					title: '纭鍒犻櫎',
+					content: `纭畾瑕佸垹闄ゆ楠屽崟鍙� ${item.billNo} 鍚楋紵`,
+					success: (res) => {
+						if (res.confirm) {
+							this.performDelete(item.id);
+						}
+					}
+				});
+			},
+			upCallback(page) {
+				//鑱旂綉鍔犺浇鏁版嵁
+				console.log("tabindex", this.TabCur)
+				let keyword = this.TabCur
+				if (keyword == 0) {
+					this.$http.get(this.url.list, {
+						params: {
+							pageNo: page.num,
+							pageSize: page.size,
+							order: "desc",
+							column: "createTime",
+							type: 2,
+							status: 0
+
+						}
+					}).then(res => {
+						this.announcement1 = res.data.result.records
+						this.mescroll.endSuccess(this.announcement1.length);
+						if (res.data.success) {
+							console.log("res", res.data)
+							this.msg1Count = res.data.result.total
+							this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+							for (let annItem of this.announcement1) {
+								this.msgList.push(annItem)
+							}
+						}
+						if (page.num == 1) {
+							this.msgList = [];
+							this.msgList = this.msgList.concat(this.announcement1);
+						}
+
+					}).catch(() => {
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					})
+				} else if (keyword == 1) {
+					this.$http.get(this.url.list, {
+						params: {
+							pageSize: page.size,
+							order: "desc",
+							column: "createTime",
+							type: 2,
+							status: 1
+						}
+					}).then(res => {
+						this.announcement2 = res.data.result.records
+						this.mescroll.endSuccess(this.announcement2.length, this.msgCount);
+						if (res.data.success) {
+							console.log("res sys", res.data)
+							this.msg2Count = res.data.result.total
+							this.msg2Title = "閫氱煡(" + res.data.result.total + ")";
+							for (let item of this.announcement2) {
+								this.msgList.push(item)
+							}
+						}
+						if (page.num == 1) {
+							this.msgList = [];
+							this.msgList = this.msgList.concat(this.announcement2);
+						}
+					}).catch(() => {
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					})
+				} else if (keyword == 2) {
+					this.$http.get(this.url.list, {
+						params: {
+							pageSize: page.size,
+							order: "desc",
+							column: "createTime",
+							type: 2,
+							status: 2
+						}
+					}).then(res => {
+						this.announcement2 = res.data.result.records
+						this.mescroll.endSuccess(this.announcement2.length, this.msgCount);
+						if (res.data.success) {
+							console.log("res sys", res.data)
+							this.msg2Count = res.data.result.total
+							this.msg2Title = "閫氱煡(" + res.data.result.total + ")";
+							for (let item of this.announcement2) {
+								this.msgList.push(item)
+							}
+						}
+						if (page.num == 1) {
+							this.msgList = [];
+							this.msgList = this.msgList.concat(this.announcement2);
+						}
+					}).catch(() => {
+						this.mescroll.endErr();
+						uni.showToast({
+							title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+							icon: 'none'
+						});
+					})
+				}
+			},
+			performDelete(id) {
+				// 瀹炵幇鍒犻櫎閫昏緫
+				uni.showToast({
+					title: '鍒犻櫎鎴愬姛',
+					icon: 'success'
+				});
+				// 杩欓噷鍙互娣诲姞瀹為檯鐨勫垹闄PI璋冪敤
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.container {
+		background-color: #f5f5f5;
+		min-height: 100vh;
+	}
+
+	.tab-container {
+		background-color: #ffffff;
+	}
+
+	.production-container {
+		padding: 20rpx;
+	}
+
+	.bill-table {
+		background-color: #ffffff;
+		border-radius: 16rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+		overflow: hidden;
+	}
+
+	.table-content {
+		padding: 20rpx;
+	}
+
+	.table-row {
+		display: flex;
+		margin-bottom: 15rpx;
+	}
+
+	.table-row:last-child {
+		margin-bottom: 0;
+	}
+
+	.table-header {
+		flex: 0 0 180rpx;
+		font-size: 28rpx;
+		color: #666;
+	}
+
+	.table-value {
+		flex: 1;
+		font-size: 28rpx;
+		color: #333;
+		display: flex;
+		align-items: center;
+	}
+
+	.right-content {
+		margin-left: auto;
+		color: #999;
+		font-size: 26rpx;
+	}
+
+	.status-tag {
+		padding: 6rpx 12rpx;
+		border-radius: 8rpx;
+		font-size: 24rpx;
+		background-color: #ff6347;
+		color: #ffffff;
+	}
+
+	.status-tag.passed {
+		background-color: #39b54a;
+	}
+
+	.status-tag.failed {
+		background-color: #55aaff;
+	}
+
+	.button-group {
+		display: flex;
+		flex-wrap: wrap;
+		gap: 15rpx;
+	}
+
+	.action-btn {
+		padding: 12rpx 20rpx;
+		font-size: 24rpx;
+		border-radius: 8rpx;
+		border: none;
+		background-color: #007AFF;
+		color: #ffffff;
+		min-width: 120rpx;
+		text-align: center;
+	}
+
+	.action-btn.check {
+		background-color: #007AFF;
+	}
+
+	.action-btn.process {
+		background-color: #39b54a;
+	}
+
+	.action-btn.device {
+		background-color: #9932cc;
+	}
+
+	.action-btn.sample {
+		background-color: #ff6347;
+	}
+
+	.action-btn.feed {
+		background-color: #ffa500;
+	}
+
+	.action-btn.report {
+		background-color: #1e90ff;
+	}
+
+	.action-btn.inspection {
+		background-color: #228b22;
+	}
+
+	.action-btn.detail {
+		background-color: #6a5acd;
+	}
+
+	.action-btn.record {
+		background-color: #808080;
+	}
+
+	.operation-row {
+		margin-top: 10rpx;
+		padding-top: 15rpx;
+		border-top: 1rpx solid #eee;
+	}
+
+	.empty-tip {
+		text-align: center;
+		padding: 100rpx 0;
+		color: #999;
+		font-size: 28rpx;
+	}
+
+	.nav {
+		white-space: nowrap;
+		width: 100%;
+	}
+
+	.cu-item {
+		display: inline-block;
+		min-width: 150rpx;
+		padding: 0 30rpx;
+		height: 80rpx;
+		line-height: 80rpx;
+		text-align: center;
+	}
+
+	.cu-item.cur {
+		border-bottom: 4rpx solid #0081ff;
+	}
+	
+	/* 楠ㄦ灦灞忔牱寮� */
+	.skeleton-container {
+		padding: 20rpx;
+	}
+	
+	.skeleton-list {
+		width: 100%;
+	}
+	
+	.skeleton-bill-item {
+		background-color: #ffffff;
+		border-radius: 16rpx;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+	}
+	
+	.skeleton-bill-row {
+		display: flex;
+		margin-bottom: 15rpx;
+	}
+	
+	.skeleton-bill-label {
+		width: 180rpx;
+		height: 28rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-bill-value {
+		flex: 1;
+		height: 28rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-left: 20rpx;
+	}
+	
+	.skeleton-bill-value.short {
+		width: 60%;
+	}
+	
+	.skeleton-half {
+		width: 45%;
+		height: 28rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.skeleton-status-tag {
+		width: 120rpx;
+		height: 36rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-left: 20rpx;
+	}
+	
+	.skeleton-buttons {
+		display: flex;
+		flex: 1;
+		margin-left: 20rpx;
+	}
+	
+	.skeleton-btn {
+		width: 120rpx;
+		height: 40rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+	
+	.operation {
+		margin-top: 10rpx;
+		padding-top: 15rpx;
+		border-top: 1rpx solid #eee;
+	}
+	
+	@keyframes skeleton-loading {
+		0% {
+			background-position: 100% 50%;
+		}
+		100% {
+			background-position: 0 50%;
+		}
+	}
+</style>
diff --git a/pages/eam/quality/qualityInspectionDetail/qualityInspectionDetail.vue b/pages/eam/quality/qualityInspectionDetail/qualityInspectionDetail.vue
new file mode 100644
index 0000000..df3c746
--- /dev/null
+++ b/pages/eam/quality/qualityInspectionDetail/qualityInspectionDetail.vue
@@ -0,0 +1,444 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">妫�楠岃鎯�</block>
+		</cu-custom>
+
+		<!-- 楠ㄦ灦灞� -->
+		<view v-if="loading" class="skeleton-container">
+			<view class="skeleton-group">
+				<view class="skeleton-divider"></view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+			</view>
+
+			<view class="skeleton-group">
+				<view class="skeleton-divider"></view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-datetime"></view>
+				</view>
+			</view>
+
+			<view class="skeleton-button"></view>
+		</view>
+
+		<!-- 瀹為檯鍐呭 -->
+		<view v-else class="container">
+			<uni-forms ref="form" :modelValue="formData" :rules="rules" validate-trigger="bind"
+				err-show-type="undertext">
+				<uni-group top="1">
+					<view class="divider"><text>鍗曟嵁淇℃伅</text></view>
+					<uni-forms-item :label-width="100" name="workOrderNumber" label="妫�楠屽崟鍙�:">
+						<uni-easyinput v-model="formData.workOrderNumber" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="materialCode" label="鐗╂枡淇℃伅:">
+						<uni-easyinput v-model="formData.materialCode" :disabled="true" />
+					</uni-forms-item>
+
+					<uni-forms-item :label-width="100" name="materialDescription" label="妫�楠岀被鍨�:">
+						<uni-easyinput v-model="formData.materialDescription" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="妫�楠屾柟妗�:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+
+					<uni-forms-item :label-width="100" required name="inspectionOrderNumber" label="浜х嚎:">
+						<uni-easyinput v-model="formData.inspectionOrderNumber" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="process" label="鐝粍">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="inspectionQuantity" label="鐢熶骇鏁伴噺:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="inspectionPlan" label="宸ュ簭">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="inspectionTime" label="妫�楠屾暟閲�">
+						<uni-easyinput v-model="formData.inspectionTime" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="inspectionTime" label="鍚堟牸鏁伴噺">
+						<uni-easyinput v-model="formData.inspectionTime" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="inspectionTime" label="涓嶅悎鏍兼暟閲�">
+						<uni-easyinput v-model="formData.inspectionTime" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="inspectionTime" label="妫�楠岀粨鏋�">
+						<uni-easyinput v-model="formData.inspectionTime" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="inspectionTime" label="妫�楠屼汉">
+						<uni-easyinput v-model="formData.inspectionTime" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="inspectionTime" label="妫�楠屾椂闂�">
+						<uni-easyinput v-model="formData.inspectionTime" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" required name="inspectionTime" label="澶勭悊缁撴灉">
+						<uni-easyinput v-model="formData.inspectionTime" :disabled="true" />
+					</uni-forms-item>
+				</uni-group>
+			</uni-forms>
+
+
+		</view>
+
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				loading: true,
+				isShow: false,
+				isSubmitting: false, // 闃查噸澶嶆彁浜�
+				SpareList: [{
+						text: "鏄�",
+						value: 1
+					},
+					{
+						text: "鍚�",
+						value: 0
+					}
+				],
+				scrollLeft: 0,
+				formData: {
+					workOrderNumber: '1111111',
+					materialCode: '120008194',
+					materialDescription: '涓変唬杞瘋杞存壙鍗曞厓\\G3-487',
+					plannedQuantity: '200',
+					inspectionOrderNumber: '',
+					process: '',
+					inspectionType: '',
+					inspectionQuantity: '',
+					inspectionPlan: '',
+					inspectionTime: '-'
+				},
+				// 琛ㄥ崟楠岃瘉瑙勫垯
+				rules: {
+					process: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨宸ュ簭'
+						}]
+					},
+					inspectionType: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠岀被鍨�'
+						}]
+					},
+					inspectionPlan: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠屾柟妗�'
+						}]
+					},
+					inspectionTime: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠屾椂闂�'
+						}]
+					},
+					inspectionQuantity: {
+						rules: [{
+							required: true,
+							errorMessage: '璇疯緭鍏ラ�佹鏁伴噺'
+						}, {
+							format: 'number',
+							errorMessage: '閫佹鏁伴噺蹇呴』涓烘暟瀛�'
+						}]
+					}
+				},
+				NavBarColor: this.NavBarColor,
+				url: {
+					upload: "/eam/sysFiles/batch_upload",
+					stallList: "/eam/eamRepairOrder/queryById",
+					getEquipmentList: 'eam/equipment/list',
+					approval: '/eam/eamRepairOrder/perform'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				msg1Count: 0
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 160
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+		created() {
+			// 妯℃嫙鏁版嵁鍔犺浇
+			setTimeout(() => {
+				this.loading = false;
+			}, 1000);
+		},
+		methods: {
+			changeisSpareList(e) {
+				this.formData.isSpare = e;
+
+			},
+
+			async ProductionTask() {
+				// 闃叉閲嶅鎻愪氦
+				if (this.isSubmitting) {
+					uni.showToast({
+						icon: "none",
+						title: "姝e湪鎻愪氦涓紝璇峰嬁閲嶅鐐瑰嚮",
+						duration: 2000
+					});
+					return;
+				}
+
+				uni.showLoading({
+					mask: true,
+					title: "鎻愪氦涓�..."
+				});
+
+				try {
+					// 浣跨敤 uni-forms 杩涜琛ㄥ崟楠岃瘉
+					await this.$refs.form.validate();
+
+					this.isSubmitting = true;
+
+					// 鍙戦�佽姹�
+					const response = await this.$http.post(this.url.approval, {
+						workOrderNumber: this.formData.workOrderNumber,
+						materialCode: this.formData.materialCode,
+						materialDescription: this.formData.materialDescription,
+						plannedQuantity: this.formData.plannedQuantity,
+						inspectionOrderNumber: this.formData.inspectionOrderNumber,
+						process: this.formData.process,
+						inspectionType: this.formData.inspectionType,
+						inspectionQuantity: this.formData.inspectionQuantity,
+						inspectionPlan: this.formData.inspectionPlan,
+						inspectionTime: this.formData.inspectionTime
+					});
+
+					if (response.data.success) {
+						uni.showToast({
+							icon: "success",
+							title: '鎻愪氦鎴愬姛',
+							duration: 2000
+						});
+
+						// 寤惰繜璺宠浆
+						await new Promise(resolve => setTimeout(resolve, 2000));
+
+						this.$Router.replaceAll({
+							name: 'qualityInspection'
+						});
+					} else {
+						uni.showModal({
+							title: "鎻愪氦澶辫触",
+							content: response.data.message || "鏈嶅姟鍣ㄥ鐞嗗け璐ワ紝璇风◢鍚庨噸璇�",
+							confirmText: '纭畾',
+							showCancel: false,
+							icon: "none"
+						});
+					}
+				} catch (error) {
+					// 琛ㄥ崟楠岃瘉澶辫触鎴栧叾浠栭敊璇�
+					if (error.errMsg) {
+						// 杩欐槸 uni-forms 鐨勯獙璇侀敊璇�
+						uni.showToast({
+							icon: "none",
+							title: error,
+							duration: 2000
+						});
+					} else {
+						// 缃戠粶鎴栧叾浠栭敊璇�
+						console.error("璇锋眰澶辫触:", error);
+
+						let errorMessage = "缃戠粶璇锋眰澶辫触";
+						if (error.errMsg) {
+							if (error.errMsg.includes("timeout")) {
+								errorMessage = "璇锋眰瓒呮椂锛岃妫�鏌ョ綉缁滆繛鎺�";
+							} else if (error.errMsg.includes("fail")) {
+								errorMessage = "缃戠粶杩炴帴澶辫触锛岃妫�鏌ョ綉缁滆缃�";
+							}
+						}
+
+						uni.showToast({
+							icon: "none",
+							title: errorMessage,
+							duration: 3000
+						});
+					}
+				} finally {
+					this.isSubmitting = false;
+					uni.hideLoading();
+				}
+			},
+		},
+	}
+</script>
+
+<style>
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+
+	.divider {
+		display: flex;
+		font-weight: bold;
+		align-items: center;
+		text-align: center;
+		color: #1E90FF;
+		font-size: 24rpx;
+		margin: 20px 0;
+	}
+
+	.divider::before,
+	.divider::after {
+		content: '';
+		flex: 1;
+		border-bottom: 1px solid gray;
+		margin: 0 16px;
+	}
+
+	.divider text {
+		white-space: nowrap;
+	}
+
+	.content {
+		margin-top: 5px;
+	}
+
+	.content scroll-view {
+		scrollIndicator: "none"
+	}
+
+	.popupView {
+		margin-top: 45px;
+		height: auto;
+	}
+
+	/* 楠ㄦ灦灞忔牱寮� */
+	.skeleton-container {
+		padding: 20rpx;
+	}
+
+	.skeleton-group {
+		margin-bottom: 40rpx;
+	}
+
+	.skeleton-divider {
+		height: 40rpx;
+		width: 300rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-bottom: 30rpx;
+	}
+
+	.skeleton-item {
+		display: flex;
+		align-items: center;
+		margin-bottom: 30rpx;
+	}
+
+	.skeleton-label {
+		width: 160rpx;
+		height: 40rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-right: 20rpx;
+	}
+
+	.skeleton-input {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+
+	.skeleton-select {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+
+	.skeleton-datetime {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+
+	.skeleton-button {
+		width: 90%;
+		height: 80rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 10rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin: 40rpx auto;
+	}
+
+	@keyframes skeleton-loading {
+		0% {
+			background-position: 100% 50%;
+		}
+
+		100% {
+			background-position: 0 50%;
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/quality/reviewDocument/reviewDocument.vue b/pages/eam/quality/reviewDocument/reviewDocument.vue
new file mode 100644
index 0000000..aa70998
--- /dev/null
+++ b/pages/eam/quality/reviewDocument/reviewDocument.vue
@@ -0,0 +1,468 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">瀹$悊</block>
+		</cu-custom>
+
+		<!-- 楠ㄦ灦灞� -->
+		<view v-if="loading" class="skeleton-container">
+			<view class="skeleton-group">
+				<view class="skeleton-divider"></view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+			</view>
+
+			<view class="skeleton-group">
+				<view class="skeleton-divider"></view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-input"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-select"></view>
+				</view>
+				<view class="skeleton-item">
+					<view class="skeleton-label"></view>
+					<view class="skeleton-datetime"></view>
+				</view>
+			</view>
+
+			<view class="skeleton-button"></view>
+		</view>
+
+		<!-- 瀹為檯鍐呭 -->
+		<view v-else class="container">
+			<uni-forms ref="form" :modelValue="formData" :rules="rules" validate-trigger="bind"
+				err-show-type="undertext">
+				<uni-group top="1">
+					<view class="divider"><text>宸ュ崟淇℃伅</text></view>
+					<uni-forms-item :label-width="100" name="workOrderNumber" label="瀹$悊鍗曟嵁鍙�:">
+						<uni-easyinput v-model="formData.workOrderNumber" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="materialCode" label="鐢熶骇宸ュ崟:">
+						<uni-easyinput v-model="formData.materialCode" :disabled="true" />
+					</uni-forms-item>
+
+					<uni-forms-item :label-width="100" name="materialDescription" label="妫�楠屽崟:">
+						<uni-easyinput v-model="formData.materialDescription" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="鐗╂枡淇℃伅:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="鏈哄彴:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="妫�楠岀被鍨�:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="缂洪櫡绫诲瀷:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="宸ュ簭:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="璁″垝鏁伴噺:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="妫�楠屾暟閲�:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="涓嶅悎鏍兼暟閲�:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="妫�楠屼汉:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>	
+					<uni-forms-item :label-width="100" name="plannedQuantity" label="妫�楠屾椂闂�:">
+						<uni-easyinput v-model="formData.plannedQuantity" :disabled="true" />
+					</uni-forms-item>
+					<view class="divider"><text>涓嶅悎鏍煎搧瀹$悊</text></view>
+
+					<uni-forms-item :label-width="140" required name="inspectionOrderNumber" label="瀹$悊鏁伴噺:">
+						<uni-easyinput v-model="formData.inspectionOrderNumber" placeholder="绯荤粺鐢熸垚" :disabled="true" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="process" label="瀹$悊缁撴灉">
+						<uni-data-select v-model="formData.process" :localdata="SpareList" @change="changeisSpareList"
+							placeholder="璇烽�夋嫨" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="inspectionType" label="瀹$悊鍘熷洜">
+						<uni-data-select v-model="formData.inspectionType" :localdata="SpareList"
+							@change="changeisSpareList" placeholder="璇烽�夋嫨" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="inspectionQuantity" label="瑙e喅鎺柦:">
+						<uni-easyinput  type="textarea"  v-model="formData.inspectionQuantity" placeholder="璇疯緭鍏�" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="inspectionPlan" label="涓�绾у鐞嗕汉">
+						<uni-data-select v-model="formData.inspectionPlan" :localdata="SpareList"
+							@change="changeisSpareList" placeholder="璇烽�夋嫨" />
+					</uni-forms-item>
+					<uni-forms-item :label-width="140" required name="inspectionTime" label="瀹$悊鏃堕棿">
+						<uni-datetime-picker type="datetime" v-model="formData.inspectionTime" />
+					</uni-forms-item>
+				</uni-group>
+			</uni-forms>
+
+			<view class="padding flex flex-direction">
+				<view class="flex-sub bg-blue padding-sm margin-xl radius text-sm text-center text-white"
+					@click.stop="ProductionTask()" hover-class="is-hover">纭畾</view>
+			</view>
+		</view>
+
+		<pdaScanVue></pdaScanVue>
+	</view>
+</template>
+
+<script>
+	import pdaScanVue from "@/components/mes/pdaScan.vue";
+
+	export default {
+		components: {
+			pdaScanVue
+		},
+		data() {
+			return {
+				loading: true,
+				isShow: false,
+				isSubmitting: false, // 闃查噸澶嶆彁浜�
+				SpareList: [{
+						text: "鏄�",
+						value: 1
+					},
+					{
+						text: "鍚�",
+						value: 0
+					}
+				],
+				scrollLeft: 0,
+				formData: {
+					workOrderNumber: '1111111',
+					materialCode: '120008194',
+					materialDescription: '涓変唬杞瘋杞存壙鍗曞厓\\G3-487',
+					plannedQuantity: '200',
+					inspectionOrderNumber: '88888',
+					process: '',
+					inspectionType: '',
+					inspectionQuantity: '',
+					inspectionPlan: '',
+					inspectionTime: ''
+				},
+				// 琛ㄥ崟楠岃瘉瑙勫垯
+				rules: {
+					process: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨宸ュ簭'
+						}]
+					},
+					inspectionType: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠岀被鍨�'
+						}]
+					},
+					inspectionPlan: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠屾柟妗�'
+						}]
+					},
+					inspectionTime: {
+						rules: [{
+							required: true,
+							errorMessage: '璇烽�夋嫨妫�楠屾椂闂�'
+						}]
+					},
+					inspectionQuantity: {
+						rules: [{
+							required: true,
+							errorMessage: '璇疯緭鍏ラ�佹鏁伴噺'
+						}, {
+							format: 'number',
+							errorMessage: '閫佹鏁伴噺蹇呴』涓烘暟瀛�'
+						}]
+					}
+				},
+				NavBarColor: this.NavBarColor,
+				url: {
+					upload: "/eam/sysFiles/batch_upload",
+					stallList: "/eam/eamRepairOrder/queryById",
+					getEquipmentList: 'eam/equipment/list',
+					approval: '/eam/eamRepairOrder/perform'
+				},
+				styles: {
+					color: '#2979FF',
+					borderColor: '#2979FF'
+				},
+				msg1Count: 0
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 160
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+		created() {
+			// 妯℃嫙鏁版嵁鍔犺浇
+			setTimeout(() => {
+				this.loading = false;
+			}, 1000);
+		},
+		methods: {
+			changeisSpareList(e) {
+				this.formData.isSpare = e;
+
+			},
+
+			async ProductionTask() {
+				// 闃叉閲嶅鎻愪氦
+				if (this.isSubmitting) {
+					uni.showToast({
+						icon: "none",
+						title: "姝e湪鎻愪氦涓紝璇峰嬁閲嶅鐐瑰嚮",
+						duration: 2000
+					});
+					return;
+				}
+
+				uni.showLoading({
+					mask: true,
+					title: "鎻愪氦涓�..."
+				});
+
+				try {
+					// 浣跨敤 uni-forms 杩涜琛ㄥ崟楠岃瘉
+					await this.$refs.form.validate();
+
+					this.isSubmitting = true;
+
+					// 鍙戦�佽姹�
+					const response = await this.$http.post(this.url.approval, {
+						workOrderNumber: this.formData.workOrderNumber,
+						materialCode: this.formData.materialCode,
+						materialDescription: this.formData.materialDescription,
+						plannedQuantity: this.formData.plannedQuantity,
+						inspectionOrderNumber: this.formData.inspectionOrderNumber,
+						process: this.formData.process,
+						inspectionType: this.formData.inspectionType,
+						inspectionQuantity: this.formData.inspectionQuantity,
+						inspectionPlan: this.formData.inspectionPlan,
+						inspectionTime: this.formData.inspectionTime
+					});
+
+					if (response.data.success) {
+						uni.showToast({
+							icon: "success",
+							title: '鎻愪氦鎴愬姛',
+							duration: 2000
+						});
+
+						// 寤惰繜璺宠浆
+						await new Promise(resolve => setTimeout(resolve, 2000));
+
+						this.$Router.replaceAll({
+							name: 'qualityInspection'
+						});
+					} else {
+						uni.showModal({
+							title: "鎻愪氦澶辫触",
+							content: response.data.message || "鏈嶅姟鍣ㄥ鐞嗗け璐ワ紝璇风◢鍚庨噸璇�",
+							confirmText: '纭畾',
+							showCancel: false,
+							icon: "none"
+						});
+					}
+				} catch (error) {
+					// 琛ㄥ崟楠岃瘉澶辫触鎴栧叾浠栭敊璇�
+					if (error.errMsg) {
+						// 杩欐槸 uni-forms 鐨勯獙璇侀敊璇�
+						uni.showToast({
+							icon: "none",
+							title: error,
+							duration: 2000
+						});
+					} else {
+						// 缃戠粶鎴栧叾浠栭敊璇�
+						console.error("璇锋眰澶辫触:", error);
+
+						let errorMessage = "缃戠粶璇锋眰澶辫触";
+						if (error.errMsg) {
+							if (error.errMsg.includes("timeout")) {
+								errorMessage = "璇锋眰瓒呮椂锛岃妫�鏌ョ綉缁滆繛鎺�";
+							} else if (error.errMsg.includes("fail")) {
+								errorMessage = "缃戠粶杩炴帴澶辫触锛岃妫�鏌ョ綉缁滆缃�";
+							}
+						}
+
+						uni.showToast({
+							icon: "none",
+							title: errorMessage,
+							duration: 3000
+						});
+					}
+				} finally {
+					this.isSubmitting = false;
+					uni.hideLoading();
+				}
+			},
+		},
+	}
+</script>
+
+<style>
+	.is-hover {
+		color: rgba(255, 255, 255, 0.6);
+		background-color: #55aaff;
+		border-color: #55aaff;
+	}
+
+	.divider {
+		display: flex;
+		font-weight: bold;
+		align-items: center;
+		text-align: center;
+		color: #1E90FF;
+		font-size: 24rpx;
+		margin: 20px 0;
+	}
+
+	.divider::before,
+	.divider::after {
+		content: '';
+		flex: 1;
+		border-bottom: 1px solid gray;
+		margin: 0 16px;
+	}
+
+	.divider text {
+		white-space: nowrap;
+	}
+
+	.content {
+		margin-top: 5px;
+	}
+
+	.content scroll-view {
+		scrollIndicator: "none"
+	}
+
+	.popupView {
+		margin-top: 45px;
+		height: auto;
+	}
+
+	/* 楠ㄦ灦灞忔牱寮� */
+	.skeleton-container {
+		padding: 20rpx;
+	}
+
+	.skeleton-group {
+		margin-bottom: 40rpx;
+	}
+
+	.skeleton-divider {
+		height: 40rpx;
+		width: 300rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-bottom: 30rpx;
+	}
+
+	.skeleton-item {
+		display: flex;
+		align-items: center;
+		margin-bottom: 30rpx;
+	}
+
+	.skeleton-label {
+		width: 160rpx;
+		height: 40rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 4rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin-right: 20rpx;
+	}
+
+	.skeleton-input {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+
+	.skeleton-select {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+
+	.skeleton-datetime {
+		flex: 1;
+		height: 60rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 8rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+	}
+
+	.skeleton-button {
+		width: 90%;
+		height: 80rpx;
+		background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
+		background-size: 400% 100%;
+		border-radius: 10rpx;
+		animation: skeleton-loading 1.4s ease infinite;
+		margin: 40rpx auto;
+	}
+
+	@keyframes skeleton-loading {
+		0% {
+			background-position: 100% 50%;
+		}
+
+		100% {
+			background-position: 0 50%;
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/pages/eam/quality/text/text.vue b/pages/eam/quality/text/text.vue
new file mode 100644
index 0000000..ecdbaf3
--- /dev/null
+++ b/pages/eam/quality/text/text.vue
@@ -0,0 +1,25 @@
+<template>
+  <web-view :src="previewUrl"></web-view>
+</template>
+
+<script>
+export default {
+  name: 'PrintPreview',
+  data() {
+    return {
+      previewUrl: ''
+    };
+  },
+  onLoad(options) {
+    // 鎺ユ敹 HTML 鍐呭鐨勪复鏃� URL
+    this.previewUrl = options.previewUrl;
+  }
+};
+</script>
+
+<style scoped>
+web-view {
+  width: 100%;
+  height: 100vh;
+}
+</style>
\ No newline at end of file
diff --git a/pages/finished-product-preview/finished-product-preview.vue b/pages/finished-product-preview/finished-product-preview.vue
new file mode 100644
index 0000000..c236d46
--- /dev/null
+++ b/pages/finished-product-preview/finished-product-preview.vue
@@ -0,0 +1,333 @@
+<template>
+  <view class="container">
+    <!-- 鎿嶄綔鏍� -->
+    <view class="header no-print"  style="margin-top: 10px;">
+      <text class="print-title">鎵撳嵃鏍囩</text>
+      <view @click="navigateBack" class="back-btn">杩斿洖</view>
+    </view>
+
+    <!-- 涓诲唴瀹瑰尯锛氱‘淇漹-if鍜寁-else鐩搁偦 -->
+    <view v-if="tagData" class="tag-card">
+      <!-- 澶撮儴锛堝惈 logo锛� -->
+      <view class="card-header">
+        <text class="card-title">鎴愬搧鎵樻爣绛�</text>
+        <!-- 纭繚 logo 璺緞姝g‘ -->
+        <image 
+          :src="logoUrl" 
+          class="card-logo" 
+          mode="widthFix"
+          alt="鍙屾灄鏂扮伀鐐伐鍘俵ogo"
+        />
+      </view>
+
+      <!-- 鍐呭鍖猴紙璋冩暣浜岀淮鐮佷綅缃級 -->
+      <view class="card-body">
+        <view class="info-list">
+          <view class="info-item">
+            <text class="item-label">浜у搧鍨嬪彿锛�</text>
+            <text class="item-value">{{ tagData.productModel || 'N/A' }}</text>
+          </view>
+          <view class="info-item">
+            <text class="item-label">宸ュ崟鍙凤細</text>
+            <text class="item-value">{{ tagData.palletNo || 'N/A' }}</text>
+          </view>
+          <view class="info-item">
+            <text class="item-label">鎵规鍙凤細</text>
+            <text class="item-value">{{ tagData.batchNo || 'N/A' }}</text>
+          </view>
+          <view class="info-item">
+            <text class="item-label">搴撳瓨鍦扮偣锛�</text>
+            <text class="item-value">{{ tagData.workshop ||'N/A' }}</text>
+          </view>
+          <view class="info-item">
+            <text class="item-label">宸ュ崟鍙凤細</text>
+            <text class="item-value">{{ tagData.produceDate || formatDate(new Date()) }}</text>
+          </view>
+          <view class="info-item">
+            <text class="item-label">浠诲姟鍙凤細</text>
+            <text class="item-value">{{ tagData.planNum || 'N/A' }}</text>
+          </view>
+        </view>
+        <!-- 浜岀淮鐮佸尯锛堝乏绉� + 闃叉孩鍑猴級 -->
+        <view class="qr-section">
+          <uv-qrcode 
+            :value="qrContent" 
+            :size="80"  
+            style="width: 80rpx; height: 80rpx; margin-right: 35px; margin-top: 20px;"
+          ></uv-qrcode>
+        </view>
+      </view>
+
+      <!-- 搴曢儴 -->
+      <view class="card-footer">
+        <text class="footer-text">鍙屾灄鏂扮伀鐐伐鍘� 路 璐ㄩ噺杩芥函</text>
+      </view>
+    </view>
+
+    <!-- 绌虹姸鎬侊細涓庝笂闈㈢殑v-if鐩搁偦锛岃В鍐虫姤閿� -->
+    <view v-else class="empty-state">
+      <text>鏈幏鍙栧埌鏍囩鏁版嵁</text>
+    </view>
+  </view>
+</template>
+
+<script>
+import uvQrcode from '@/uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue';
+import io from '@hyoga/uni-socket.io';
+import { PrinterCommands } from '@/common/util/printer-commands.js';
+
+export default {
+  components: { uvQrcode },
+  data() {
+    return {
+      tagData: null, // 浠庡閮ㄦ帴鏀剁殑鏁版嵁
+      qrContent: '',
+      logoUrl: '/static/index_logo.png', // 纭繚姝よ矾寰勬湁鍥剧墖
+      printerConfig: null
+    };
+  },
+  onLoad(options) {
+    try {
+      // 鎺ユ敹浼犻�掔殑鏍囩鏁版嵁
+      if (options.tagData) {
+        this.tagData = JSON.parse(decodeURIComponent(options.tagData));
+        // 鐢熸垚浜岀淮鐮佸唴瀹�
+        this.qrContent = `PALLET:${this.tagData.palletNo || ''};BATCH:${this.tagData.batchNo || ''}`;
+      }
+    } catch (e) {
+      console.error('鏍囩鏁版嵁瑙f瀽閿欒:', e);
+      uni.showToast({ title: '鏁版嵁鍔犺浇澶辫触', icon: 'none' });
+    }
+    this.printerConfig = uni.getStorageSync('printerConfig') || null;
+  },
+  methods: {
+    formatDate(date) {
+      const year = date.getFullYear();
+      const month = String(date.getMonth() + 1).padStart(2, '0');
+      const day = String(date.getDate()).padStart(2, '0');
+      return `${year}-${month}-${day}`;
+    },
+    navigateBack() {
+     uni.navigateBack(1);
+    },
+    async handlePrint() {
+      // 鎵撳嵃閫昏緫淇濇寔涓嶅彉
+      if (!this.tagData) {
+        uni.showToast({ title: '鏍囩鏁版嵁涓虹┖', icon: 'none' });
+        return;
+      }
+      
+      this.printerConfig = uni.getStorageSync('printerConfig') || null;
+      if (!this.printerConfig?.ip || !this.printerConfig?.port) {
+        uni.showModal({
+          title: '鏈厤缃墦鍗版満',
+          content: '鏄惁鍓嶅線璁剧疆锛�',
+          success: (res) => {
+            if (res.confirm) uni.navigateTo({ url: '/pages/user/location' });
+          }
+        });
+        return;
+      }
+
+      try {
+        uni.showLoading({ title: '鎵撳嵃涓�...', mask: true });
+        const qrBase64 = this.$refs.qrcode?.toDataURL();
+        if (!qrBase64) throw new Error('鑾峰彇浜岀淮鐮佸け璐�');
+        
+        const qrBuffer = this.base64ToArrayBuffer(qrBase64);
+        const printData = { ...this.tagData, qrBuffer, printTime: new Date().toLocaleString() };
+        const commands = new PrinterCommands(this.printerConfig.model || 'generic');
+        const printCommand = commands.buildProductTag(printData);
+        
+        await this.sendPrintCommand(printCommand);
+        uni.hideLoading();
+        uni.showToast({ title: '鏍囩鎵撳嵃鎴愬姛', icon: 'success' });
+      } catch (error) {
+        uni.hideLoading();
+        uni.showToast({ title: error.message || '鎵撳嵃澶辫触', icon: 'none' });
+      }
+    },
+    sendPrintCommand(command) {
+      return new Promise((resolve, reject) => {
+        if (!this.printerConfig?.ip || !this.printerConfig?.port) {
+          reject(new Error('鎵撳嵃鏈洪厤缃笉瀹屾暣'));
+          return;
+        }
+        
+        const protocol = this.printerConfig.model === 'zebra' ? 'tcp://' : 'ws://';
+        const socket = io(`${protocol}${this.printerConfig.ip}:${this.printerConfig.port}`, {
+          transports: ['websocket'],
+          timeout: 5000
+        });
+
+        let isResolved = false;
+        socket.on('connect', () => {
+          socket.emit('print', command, (response) => {
+            socket.disconnect();
+            if (!isResolved) {
+              isResolved = true;
+              response.success ? resolve() : reject(new Error(response.error || '鎵撳嵃澶辫触'));
+            }
+          });
+        });
+
+        socket.on('connect_error', (err) => {
+          if (!isResolved) {
+            isResolved = true;
+            reject(new Error(`杩炴帴澶辫触: ${err.message}`));
+          }
+        });
+
+        setTimeout(() => {
+          if (!isResolved) {
+            isResolved = true;
+            socket.disconnect();
+            reject(new Error('鎵撳嵃瓒呮椂'));
+          }
+        }, 10000);
+      });
+    },
+    base64ToArrayBuffer(base64) {
+      const binaryString = uni.base64Decode(base64);
+      const len = binaryString.length;
+      const bytes = new Uint8Array(len);
+      for (let i = 0; i < len; i++) {
+        bytes[i] = binaryString.charCodeAt(i);
+      }
+      return bytes.buffer;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.container {
+  background-color: #fff;
+  padding: 20rpx;
+  min-height: 100vh;
+}
+
+/* 鎿嶄綔鏍� */
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 10rpx 0;
+  border-bottom: 1px solid #eee;
+}
+.print-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+}
+.back-btn {
+  font-size: 28rpx;
+  color: #007AFF;
+}
+
+/* 鏍囩鍗$墖 */
+.tag-card {
+  width: 680rpx; /* 鍔犲鍗$墖閬垮厤鍐呭婧㈠嚭 */
+  margin: 30rpx auto;
+  border: 1px solid #eee;
+  border-radius: 8rpx;
+  box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
+  padding: 10rpx;
+}
+
+/* 鍗$墖澶撮儴锛堝惈 logo锛� */
+.card-header {
+  display: flex;
+  align-items: center;
+  padding: 20rpx;
+  border-bottom: 2px solid #007AFF;
+}
+.card-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+  flex: 1;
+}
+.card-logo {
+  width: 120rpx;
+  height: auto;
+}
+
+/* 鍗$墖鍐呭 */
+.card-body {
+  display: flex;
+  padding: 20rpx;
+  gap: 10rpx; /* 鎺у埗淇℃伅鍖哄拰浜岀淮鐮侀棿璺� */
+}
+.info-list {
+  flex: 1;
+}
+.info-item {
+  display: flex;
+  margin-bottom: 15rpx;
+  line-height: 1.6;
+}
+.item-label {
+  width: 140rpx;
+  font-size: 26rpx;
+  color: #666;
+  font-weight: 500;
+}
+.item-value {
+  flex: 1;
+  font-size: 26rpx;
+  color: #333;
+  word-break: break-all;
+}
+
+/* 浜岀淮鐮佸尯锛堝乏绉昏皟鏁达級 */
+.qr-section {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  margin-left: 10rpx; /* 宸︾Щ鍑忓皯闂磋窛 */
+}
+.uv-qrcode {
+  width: 140rpx !important;
+  height: 140rpx !important;
+}
+.qr-tip {
+  margin-top: 10rpx;
+  font-size: 22rpx;
+  color: #666;
+  text-align: center;
+}
+
+/* 鍗$墖搴曢儴 */
+.card-footer {
+  padding: 15rpx 20rpx;
+  border-top: 1px dashed #ccc;
+  text-align: center;
+}
+.footer-text {
+  font-size: 22rpx;
+  color: #999;
+}
+
+/* 绌虹姸鎬� */
+.empty-state {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 300rpx;
+  color: #999;
+  font-size: 28rpx;
+}
+
+/* 鎵撳嵃鎺у埗 */
+@media print {
+  .no-print {
+    display: none;
+  }
+  .tag-card {
+    width: 100%;
+    box-shadow: none;
+    border: none;
+  }
+}
+</style>
diff --git a/pages/inspection-tag-preview/inspection-tag-preview.vue b/pages/inspection-tag-preview/inspection-tag-preview.vue
new file mode 100644
index 0000000..93026a6
--- /dev/null
+++ b/pages/inspection-tag-preview/inspection-tag-preview.vue
@@ -0,0 +1,227 @@
+<template>
+  <view class="container">
+    <!-- 鎿嶄綔鏍忥細鎵撳嵃/杩斿洖 -->
+    <view class="header no-print">
+      <view @click="handlePrint" class="print-btn">
+        <image src="/static/icon_print.png" class="print-icon" alt="鎵撳嵃" />
+        <text class="print-text">鎵撳嵃鏍囩</text>
+      </view>
+      <view @click="navigateBack" class="back-btn">杩斿洖</view>
+    </view>
+
+    <!-- 妫�楠屾爣璇嗗崱涓讳綋锛堝甫缁胯壊杈规 + 瀹屾暣琛ㄦ牸锛� -->
+    <view v-if="tagData" class="tag-card">
+      <!-- 鍗″ご锛氭爣棰� + 鏃ユ湡 -->
+      <view class="card-header">
+        <text class="card-title">妫�楠屾爣璇嗗崱</text>
+        <text class="card-date">{{ tagData.date }}</text>
+      </view>
+
+      <!-- 鍐呭琛ㄦ牸锛堝甫杈规锛� -->
+      <view class="card-table">
+        <view class="table-row">
+          <view class="table-cell label">鐗╂枡</view>
+          <view class="table-cell value">{{ tagData.material }}</view>
+          <view class="table-cell label">鎵规</view>
+          <view class="table-cell value">{{ tagData.batch }}</view>
+        </view>
+        <view class="table-row">
+          <view class="table-cell label">鍨嬪彿</view>
+          <view class="table-cell value">{{ tagData.model }}</view>
+          <view class="table-cell label">鏁伴噺</view>
+          <view class="table-cell value">{{ tagData.quantity }}</view>
+        </view>
+        <view class="table-row">
+          <view class="table-cell label">鏃ユ湡</view>
+          <view class="table-cell value">{{ tagData.inspectDate }}</view>
+          <view class="table-cell label">妫�楠�</view>
+          <view class="table-cell value">{{ tagData.inspector }}</view>
+        </view>
+      </view>
+
+      <!-- 搴曢儴浜岀淮鐮佸尯鍩燂紙绮惧噯瀵归綈锛� -->
+      <view class="qr-area">
+        <uv-qrcode 
+          :value="qrContent" 
+          :size="80"  
+          style="width: 80rpx; height: 80rpx;"
+        ></uv-qrcode>
+      </view>
+    </view>
+
+    <!-- 绌虹姸鎬� -->
+    <view v-else class="empty-state">
+      <text>鏈幏鍙栧埌妫�楠屾爣璇嗗崱鏁版嵁</text>
+    </view>
+  </view>
+</template>
+
+<script>
+import uvQrcode from '@/uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue';
+import io from '@hyoga/uni-socket.io';
+import { PrinterCommands } from '@/common/util/printer-commands.js';
+
+export default {
+  components: { uvQrcode },
+  data() {
+    return {
+      tagData: {
+        material: '120034535',
+        batch: '25098814',
+        model: 'G3-2B259',
+        quantity: 216,
+        inspectDate: '20250408',
+        inspector: '鐜嬬京/鍚堟牸',
+        date: '2025.08.22'
+      },
+      printerConfig: null,
+      qrContent: ''
+    };
+  },
+  onLoad() {
+    // 鐢熸垚浜岀淮鐮佸唴瀹癸紙鎷兼帴鍏抽敭淇℃伅锛�
+    this.qrContent = `M:${this.tagData.material};B:${this.tagData.batch};M:${this.tagData.model}`;
+    this.printerConfig = uni.getStorageSync('printerConfig') || null;
+  },
+  methods: {
+    navigateBack() {
+      uni.navigateBack();
+    },
+    async handlePrint() {
+      // 鎵撳嵃閫昏緫涓庝箣鍓嶄竴鑷达紙鐪佺暐閲嶅浠g爜锛屼繚鎸佸師閫昏緫锛�
+      if (!this.tagData) {
+        uni.showToast({ title: '鏍囩鏁版嵁涓虹┖', icon: 'none' });
+        return;
+      }
+      // ... 鍘熸墦鍗伴�昏緫浠g爜 ...
+    },
+    sendPrintCommand(command) {
+      // ... 鍘熸墦鍗版寚浠や唬鐮� ...
+    }
+  }
+};
+</script>
+
+<style scoped>
+/* 瀹瑰櫒鍩虹鏍峰紡 */
+.container {
+  background-color: #fff;
+  padding: 20rpx;
+  min-height: 100vh;
+}
+
+/* 鎿嶄綔鏍� */
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 10rpx 0;
+  border-bottom: 1px solid #eee;
+}
+.print-btn {
+  display: flex;
+  align-items: center;
+}
+.print-icon {
+  width: 32rpx;
+  height: 32rpx;
+  margin-right: 8rpx;
+}
+.print-text {
+  font-size: 28rpx;
+  color: #007AFF;
+}
+.back-btn {
+  font-size: 28rpx;
+  color: #007AFF;
+}
+
+/* 妫�楠屾爣璇嗗崱涓讳綋锛堟牳蹇冩牱寮忥級 */
+.tag-card {
+  width: 600rpx; 
+  margin: 30rpx auto;
+  border: 4rpx solid #28a745; /* 缁胯壊杈规 */
+  border-radius: 12rpx;
+  padding: 20rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
+}
+
+/* 鍗″ご鏍峰紡 */
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10rpx;
+  padding-bottom: 10rpx;
+  border-bottom: 2px solid #333; /* 鏍囬鍒嗗壊绾� */
+}
+.card-title {
+  font-size: 36rpx;
+  font-weight: bold;
+  color: #333;
+}
+.card-date {
+  font-size: 28rpx;
+  color: #666;
+}
+
+/* 琛ㄦ牸鏍稿績鏍峰紡锛堝甫杈规锛� */
+.card-table {
+  width: 100%;
+  border-collapse: collapse; /* 鍚堝苟杈规 */
+  margin-bottom: 20rpx;
+}
+.table-row {
+  display: flex;
+  border: 1px solid #999; /* 琛ㄦ牸琛岃竟妗� */
+}
+.table-cell {
+  flex: 1;
+  padding: 12rpx 8rpx;
+  font-size: 26rpx;
+  color: #333;
+  border-right: 1px solid #999; /* 鍗曞厓鏍煎彸渚ц竟妗� */
+}
+.table-cell:last-child {
+  border-right: none; /* 鏈�鍚庝竴鍒楁棤杈规 */
+}
+.label {
+  width: 30%;
+  text-align: right;
+  color: #666;
+  background-color: #f8f8f8; /* 鏍囩鍒楃伆鑹茶儗鏅� */
+}
+.value {
+  width: 70%;
+  text-align: left;
+}
+
+/* 浜岀淮鐮佸尯鍩燂紙鍙充笅瑙掑榻愶級 */
+.qr-area {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: -10rpx; /* 寰皟涓庤〃鏍奸棿璺� */
+}
+
+/* 绌虹姸鎬� */
+.empty-state {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 300rpx;
+  color: #999;
+  font-size: 28rpx;
+}
+
+/* 鎵撳嵃閫傞厤锛堥殣钘忔搷浣滄爮锛屼紭鍖栬竟妗嗭級 */
+@media print {
+  .no-print {
+    display: none;
+  }
+  .tag-card {
+    border: 4rpx solid #28a745; /* 鎵撳嵃鏃朵繚鐣欑豢鑹茶竟妗� */
+    box-shadow: none;
+    width: 100%;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/pages/lineSelect/lineSelect.vue b/pages/lineSelect/lineSelect.vue
new file mode 100644
index 0000000..c10618e
--- /dev/null
+++ b/pages/lineSelect/lineSelect.vue
@@ -0,0 +1,260 @@
+<template>
+  <view class="content">
+    <cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="index">
+      <block slot="backText">杩斿洖</block>
+      <block slot="content">閫夋嫨浜х嚎</block>
+    </cu-custom>
+
+    <view class="current-line" @tap="showLineSelectModal">
+      <view class="line-label">褰撳墠浜х嚎锛�</view>
+      <view class="line-name">{{ currentLineName || '鏈�夋嫨浜х嚎' }}</view>
+    </view>
+
+    <view class="line-modal-mask" v-if="showLineModal" @click="closeLineModal"></view>
+    <view class="line-modal" v-if="showLineModal" :class="{ 'line-modal-active': showLineModal }">
+      <view class="line-modal-header">
+        <view class="line-modal-title">閫夋嫨浜х嚎</view>
+        <text class="cuIcon-close" @click="closeLineModal"></text>
+      </view>
+      <view class="line-modal-content">
+        <view v-if="lineLoading" class="loading-view">
+          <view class="cu-load"></view>
+          <view class="text-gray">鍔犺浇浜х嚎涓�...</view>
+        </view>
+        <view v-else-if="lineList.length === 0" class="empty-view">
+          <text class="cuIcon-meh text-gray text-xl"></text>
+          <view class="text-gray">鏆傛棤鍙敤浜х嚎</view>
+        </view>
+        <view class="line-item" 
+          v-for="(line, index) in lineList" 
+          :key="line.id"
+          @click="selectLine(line)"
+          :class="{ 'line-item-selected': selectedLineId === line.id }">
+          <view class="line-name">{{ line.name }}</view>
+          <text class="cuIcon-check text-blue" v-if="selectedLineId === line.id"></text>
+        </view>
+      </view>
+      <view class="line-modal-footer">
+        <button class="cu-btn bg-blue lg" 
+          @click="confirmLineSelection"
+          :disabled="!selectedLineId">
+          纭閫夋嫨
+        </button>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import { mapActions, mapGetters, mapState } from "vuex";
+
+export default {
+  data() {
+    return {
+      showLineModal: false,       
+      selectedLineId: '',         
+      lineLoading: false          
+    };
+  },
+  computed: {
+    ...mapState(["currentLineId"]),
+    ...mapGetters(["lineList"]),
+    currentLineName() {
+      if (!this.currentLineId) return '';
+      const currentLine = this.lineList.find(line => line.id === this.currentLineId);
+      return currentLine ? currentLine.name : '鏈�夋嫨浜х嚎';
+    },
+    top() {
+      return this.CustomBar * 2 + 95;
+    },
+    style() {
+      var StatusBar = this.StatusBar;
+      var CustomBar = this.CustomBar;
+      var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+      return style;
+    }
+  },
+
+  created() {
+    this.fetchLineData();
+  },
+  mounted() {
+    this.selectedLineId = this.currentLineId;
+  },
+  methods: {
+    ...mapActions(["fetchLineList", "setCurrentLine"]),
+
+    fetchLineData() {
+      this.lineLoading = true;
+      this.fetchLineList()
+        .then(lineList => {
+          this.lineLoading = false;
+          if (lineList.length > 0 && !this.selectedLineId) {
+            this.selectedLineId = lineList[0].id;
+          }
+        })
+        .catch(err => {
+          console.error("鑾峰彇浜х嚎鍒楄〃澶辫触:", err);
+          this.lineLoading = false;
+          uni.showToast({
+            title: "鑾峰彇浜х嚎鍒楄〃澶辫触锛岃閲嶈瘯",
+            icon: "none"
+          });
+        });
+    },
+
+    showLineSelectModal() {
+      this.showLineModal = true;
+    },
+
+    selectLine(line) {
+      this.selectedLineId = line.id;
+    },
+
+    confirmLineSelection() {
+      if (!this.selectedLineId) {
+        uni.showToast({
+          title: "璇烽�夋嫨浜х嚎",
+          icon: "none"
+        });
+        return;
+      }
+
+      this.setCurrentLine(this.selectedLineId)
+        .then(() => {
+          this.showLineModal = false;
+          uni.showToast({
+            title: "浜х嚎璁剧疆鎴愬姛",
+            icon: "success"
+          });
+        })
+        .catch(err => {
+          console.error("淇濆瓨浜х嚎澶辫触:", err);
+          this.showLineModal = false;
+          uni.showToast({
+            title: "浜х嚎璁剧疆澶辫触锛岃閲嶈瘯",
+            icon: "none"
+          });
+        });
+    },
+
+    closeLineModal() {
+      this.showLineModal = false;
+    }
+  }
+};
+</script>
+
+<style>
+  .current-line {
+    display: flex;
+    align-items: center;
+    padding: 20upx;
+    background-color: #fff;
+    border-radius: 10upx;
+    margin: 20upx;
+    box-shadow: 0 2upx 10upx rgba(0, 0, 0, 0.1);
+  }
+
+  .line-label {
+    font-size: 28upx;
+    color: #333;
+    margin-right: 10upx;
+  }
+
+  .line-name {
+    font-size: 28upx;
+    color: #666;
+  }
+
+  /* 浜х嚎閫夋嫨寮圭獥鏍峰紡 */
+  .line-modal-mask {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.5);
+    z-index: 998;
+    opacity: 0;
+    transition: opacity 0.3s ease;
+  }
+
+  .line-modal {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: -100%;
+    background-color: #fff;
+    border-top-left-radius: 20upx;
+    border-top-right-radius: 20upx;
+    z-index: 999;
+    transition: bottom 0.3s ease;
+    max-height: 80vh;
+  }
+
+  .line-modal-active {
+    bottom: 0;
+  }
+
+  .line-modal-active + .line-modal-mask {
+    opacity: 1;
+  }
+
+  .line-modal-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 20upx 30upx;
+    border-bottom: 1px solid #eee;
+  }
+
+  .line-modal-title {
+    font-size: 34upx;
+    font-weight: bold;
+  }
+
+  .line-modal-content {
+    padding: 20upx;
+    overflow-y: auto;
+    max-height: calc(80vh - 180upx);
+  }
+
+  .line-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 25upx 20upx;
+    border-bottom: 1px solid #f5f5f5;
+    font-size: 30upx;
+  }
+
+  .line-item-selected {
+    background-color: #f0f7ff;
+  }
+
+  .line-item:last-child {
+    border-bottom: none;
+  }
+
+  .line-modal-footer {
+    padding: 20upx 30upx;
+    border-top: 1px solid #eee;
+  }
+
+  .loading-view {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 60upx 0;
+  }
+
+  .empty-view {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 60upx 0;
+  }
+</style>
\ No newline at end of file
diff --git a/pages/print-preview/print-preview.vue b/pages/print-preview/print-preview.vue
new file mode 100644
index 0000000..1c1ddd5
--- /dev/null
+++ b/pages/print-preview/print-preview.vue
@@ -0,0 +1,356 @@
+<template>
+  <view class="container">
+    <!-- 鎵撳嵃鎸夐挳鍖哄煙锛氫粎鍦ㄥ睆骞曟樉绀猴紝鎵撳嵃鏃堕殣钘� -->
+    <view class="print-btn-container no-print">
+      <view @click="handlePrint" class="print-btn">
+        <image src="/static/icon_dayin.png" class="print-icon" alt="鎵撳嵃" />
+        <text class="print-text">鎵撳嵃</text>
+      </view>
+      <view @click="navigateBack" class="back-btn">
+        <text>杩斿洖</text>
+      </view>
+    </view>
+
+    <!-- 棰勮鍖哄煙 -->
+    <view v-if="printData" class="preview-content">
+      <view class="preview-header">
+        <text class="title">绉诲簱鍗�</text>
+      </view>
+      
+      <view class="preview-body">
+        <!-- 椤堕儴淇℃伅琛� -->
+        <view class="top-info">
+          <image src="@/static/index_logo.png" class="logo" mode="aspectFit" />
+          <text class="doc-number">XHJ.QM.QMSOO9E</text>
+        </view>
+
+        <!-- 琛ㄦ牸閮ㄥ垎 -->
+        <table class="info-table">
+          <tr>
+            <td>鐢熶骇璁㈠崟鍙�</td>
+            <td>{{ printData.orderNo }}</td>
+            <td>浜у搧鍨嬪彿</td>
+            <td>G-639</td>
+            <td rowspan="4" class="qr-cell">
+              <view class="qr-container">
+                <uv-qrcode 
+                  :value="qrContent" 
+                  :size="180" 
+                  :margin="10" 
+                  ref="qrcode"
+                  @click="saveQRCode"
+                ></uv-qrcode>
+                <text class="qr-text">C2506080024</text>
+              </view>
+            </td>
+          </tr>
+          <tr>
+            <td>瀹㈡埛鍚嶇О</td>
+            <td>涓滄柟鏃ヤ骇</td>
+            <td>鐗╂枡鍙�</td>
+            <td>120047854</td>
+          </tr>
+          <tr>
+            <td>瀹㈡埛鍨嬪彿</td>
+            <td>4200-51354</td>
+            <td>鐢熶骇鎵瑰彿</td>
+            <td>25159847</td>
+          </tr>
+          <tr>
+            <td>鐢熶骇鍒嗗巶</td>
+            <td>鍙屾灄鏂扮伀鐐伐鍘�</td>
+            <td>鏁伴噺</td>
+            <td>73</td>
+          </tr>
+          <tr class="inspection-status">
+            <td>妫�楠岀姸鎬�</td>
+            <td colspan="4"></td>
+          </tr>
+        </table>
+      </view>
+    </view>
+    
+    <!-- 澶囩敤web-view -->
+    <web-view v-if="previewUrl" class="no-print" :src="previewUrl"></web-view>
+  </view>
+</template>
+
+<script>
+import io from '@hyoga/uni-socket.io';
+import { PrinterCommands } from '@/common/util/printer-commands.js';
+import uvQrcode from '@/uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue'
+
+export default {
+  components: { uvQrcode },
+  data() {
+    return {
+      previewUrl: '',
+      printData: null,
+      printerConfig: null,
+      qrContent: 'C2506080024'
+    };
+  },
+  onLoad(options) {
+    try {
+      if (options.previewUrl) {
+        this.previewUrl = decodeURIComponent(options.previewUrl);
+      }
+      if (options.printData) {
+        this.printData = JSON.parse(decodeURIComponent(options.printData));
+      }
+    } catch (e) {
+      console.error('鏁版嵁瑙f瀽閿欒:', e);
+      uni.showToast({ title: '鏁版嵁鍔犺浇澶辫触', icon: 'none' });
+    }
+    this.printerConfig = uni.getStorageSync('printerConfig') || null;
+    this.setLandscapeOrientation();
+  },
+  onUnload() {
+    if (uni.setScreenOrientation) {
+      uni.setScreenOrientation({ orientation: 'portrait' });
+    }
+  },
+  methods: {
+    setLandscapeOrientation() {
+      if (uni.setScreenOrientation) {
+        uni.setScreenOrientation({
+          orientation: 'landscape',
+          success: () => console.log('宸叉í灞�'),
+          fail: (err) => console.error('妯睆璁剧疆澶辫触:', err)
+        });
+      }
+    },
+    saveQRCode() {
+      this.$refs.qrcode.save();
+    },
+    navigateBack() {
+      uni.navigateBack();
+    },
+    async handlePrint() {
+      if (!this.printData) {
+        uni.showToast({ title: '鎵撳嵃鏁版嵁涓虹┖', icon: 'none' });
+        return;
+      }
+      
+      this.printerConfig = uni.getStorageSync('printerConfig') || null;
+      if (!this.printerConfig?.ip || !this.printerConfig?.port) {
+        uni.showModal({
+          title: '鏈厤缃墦鍗版満',
+          content: '鏄惁鍓嶅線璁剧疆锛�',
+          success: (res) => {
+            if (res.confirm) uni.navigateTo({ url: '/pages/user/location' });
+          }
+        });
+        return;
+      }
+
+      try {
+        uni.showLoading({ title: '鎵撳嵃涓�...', mask: true });
+        const qrBase64 = this.$refs.qrcode.toDataURL();
+        const qrBuffer = this.base64ToArrayBuffer(qrBase64);
+        const printDataWithQr = { ...this.printData, qrBuffer };
+        
+        const commands = new PrinterCommands(this.printerConfig.model || 'generic');
+        const printCommand = commands.buildTransferOrder(printDataWithQr);
+        await this.sendPrintCommand(printCommand);
+        
+        uni.hideLoading();
+        uni.showToast({ title: '鎵撳嵃鎴愬姛', icon: 'success' });
+      } catch (error) {
+        uni.hideLoading();
+        uni.showToast({ title: error.message || '鎵撳嵃澶辫触', icon: 'none' });
+      }
+    },
+    sendPrintCommand(command) {
+      return new Promise((resolve, reject) => {
+        if (!this.printerConfig) {
+          reject(new Error('鏈厤缃墦鍗版満'));
+          return;
+        }
+        
+        const { ip, port, model } = this.printerConfig;
+        if (!ip || !port) {
+          reject(new Error('鎵撳嵃鏈洪厤缃笉瀹屾暣'));
+          return;
+        }
+        
+        const protocol = model === 'zebra' ? 'tcp://' : 'ws://';
+        const socket = io(`${protocol}${ip}:${port}`, {
+          transports: ['websocket'],
+          timeout: 5000
+        });
+
+        let isResolved = false;
+        socket.on('connect', () => {
+          socket.emit('print', command, (response) => {
+            socket.disconnect();
+            if (!isResolved) {
+              isResolved = true;
+              response.success ? resolve() : reject(new Error(response.error || '鎵撳嵃澶辫触'));
+            }
+          });
+        });
+
+        socket.on('connect_error', (err) => {
+          if (!isResolved) {
+            isResolved = true;
+            reject(new Error(`杩炴帴澶辫触: ${err.message}`));
+          }
+        });
+
+        socket.on('disconnect', (reason) => {
+          if (!isResolved) {
+            isResolved = true;
+            reject(new Error(`杩炴帴鏂紑: ${reason}`));
+          }
+        });
+
+        setTimeout(() => {
+          if (!isResolved) {
+            isResolved = true;
+            socket.disconnect();
+            reject(new Error('鎵撳嵃瓒呮椂'));
+          }
+        }, 10000);
+      });
+    },
+    base64ToArrayBuffer(base64) {
+      const binaryString = uni.base64Decode(base64);
+      const len = binaryString.length;
+      const bytes = new Uint8Array(len);
+      for (let i = 0; i < len; i++) {
+        bytes[i] = binaryString.charCodeAt(i);
+      }
+      return bytes.buffer;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.container {
+  position: relative;
+  height: 100vh;
+  padding-top: 60rpx; /* 棰勭暀鎵撳嵃鎸夐挳鍖哄煙楂樺害 */
+}
+
+/* 鎵撳嵃鎸夐挳鍖哄煙鏍峰紡 */
+.print-btn-container {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 60rpx;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 0 30rpx;
+  background-color: #f5f5f5;
+  z-index: 999;
+}
+
+.print-btn {
+  display: flex;
+  align-items: center;
+  color: #007AFF;
+}
+
+.print-icon {
+  width: 25px;
+  height: 25px;
+  margin-right: 8rpx;
+}
+
+.back-btn {
+  color: #333;
+}
+
+/* 棰勮鍖哄煙鏍峰紡 */
+.preview-header {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 15rpx 20rpx;
+  background-color: #007AFF;
+  color: white;
+}
+
+.title {
+  font-size: 32rpx;
+  font-weight: bold;
+}
+
+.preview-body {
+  padding: 30rpx;
+}
+
+.top-info {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20rpx;
+  padding: 10rpx 0;
+  border-bottom: 1px solid #ddd;
+}
+
+.logo {
+  width: 120rpx;
+  height: 60rpx;
+}
+
+.doc-number {
+  font-size: 28rpx;
+  font-weight: bold;
+  color: #000;
+}
+
+.info-table {
+  width: 100%;
+  border-collapse: collapse;
+  margin-top: 20rpx;
+}
+
+.info-table td {
+  border: 1px solid #ddd;
+  padding: 10rpx;
+  text-align: center;
+  vertical-align: middle;
+}
+
+.qr-cell {
+  width: 200rpx;
+  text-align: center;
+}
+
+.qr-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 10rpx;
+}
+
+.qr-text {
+  font-size: 24rpx;
+  color: #000;
+}
+
+.inspection-status {
+  height: 320rpx;
+  line-height: 320rpx;
+}
+
+/* 鎵撳嵃鏍峰紡鎺у埗锛氬甫no-print绫荤殑鍏冪礌鍦ㄦ墦鍗版椂涓嶆樉绀� */
+@media print {
+  @page {
+    size: auto;
+    margin: 10mm; /* 璋冩暣鎵撳嵃杈硅窛 */
+  }
+  .no-print {
+    display: none !important; /* 鎵撳嵃鏃堕殣钘忔搷浣滄寜閽� */
+  }
+  .container {
+    padding-top: 0; /* 绉婚櫎鎵撳嵃鏃剁殑椤堕儴鐣欑櫧 */
+  }
+}
+</style>
diff --git a/pages/selectUsers/selectUsers.vue b/pages/selectUsers/selectUsers.vue
new file mode 100644
index 0000000..4613480
--- /dev/null
+++ b/pages/selectUsers/selectUsers.vue
@@ -0,0 +1,315 @@
+<template>
+	<view class="container">
+		<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
+			<block slot="backText">杩斿洖</block>
+			<block slot="content">閫夋嫨鍙戠幇浜�</block>
+			<block slot="right">
+				<view @click="search">
+					<image class="search" src="/static/icon/sear.png" style="width: 25px; height: 25px;" alt="" />
+				</view>
+			</block>
+		</cu-custom>
+
+		<view style="width: 100%;">
+			<uni-popup ref="popup" background-color="#fff" :type="type">
+				<view class="popupView" style="height: auto; margin-top: 85px;">
+					<!-- 鍩虹琛ㄥ崟鏍¢獙 -->
+					<uni-forms ref="form" :modelValue="formData" validate-trigger="bind" err-show-type="undertext">
+						<uni-group title="" top="0">
+							<uni-forms-item name="name" label="鐢ㄦ埛璐﹀彿:">
+								<uni-easyinput placeholder="璇疯緭鍏ョ敤鎴疯处鍙�" v-model="formData.name" />
+							</uni-forms-item>
+
+						</uni-group>
+					</uni-forms>
+
+					<view class="flex">
+
+						<view
+							class="cuIcon-search flex-sub bg-blue padding-sm  margin-left-lg margin-right-lg margin-xs   text-sm text-center"
+							@click="searBut">鏌ヨ
+						</view>
+						<view
+							class="cuIcon-refresh flex-sub bg-white solids padding-sm margin-left-lg margin-right-lg margin-xs radius text-sm text-center"
+							@click="resetTask">閲嶇疆</view>
+					</view>
+				</view>
+			</uni-popup>
+
+		</view>
+		<mescroll-uni ref="mescrollRef" @init="mescrollInit" :top="top" @down="downCallback" @up="upCallback">
+			<!-- 鍒楄〃淇℃伅寮�濮� -->
+			<view class="content">
+
+				<uni-card margin="10px" spacing="1px" v-for="(item,index) in msgList" :key="index"
+					@click="onClickProductionTask(item)">
+					<view class="flex">
+						<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">鐢ㄦ埛璐﹀彿:</view>
+						<view class="flex-sub bg-white padding-xs     text-right margin-xs">{{item.username}}</view>
+					</view>
+					<view class="flex">
+						<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">鐢ㄦ埛濮撳悕:</view>
+						<view class="flex-sub bg-white padding-xs   text-bold  text-right margin-xs">{{item.realname}}
+						</view>
+					</view>
+					<view class="flex">
+						<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">鐢佃瘽:</view>
+						<view class="flex-sub bg-white padding-xs     text-right margin-xs">{{item.phone}}</view>
+					</view>
+					<view class="flex">
+						<view class="flex-sub text-light bg-white  padding-xs margin-xs radius">閮ㄩ棬:</view>
+						<view class="flex-sub bg-white padding-xs     text-right margin-xs">
+							{{item.primaryDeptId_dictText}}
+						</view>
+					</view>
+
+				</uni-card>
+
+			</view>
+
+		</mescroll-uni>
+
+	</view>
+</template>
+
+<script>
+	import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], // 浣跨敤mixin
+		data() {
+			return {
+				type: 'top',
+				formData: {
+
+					name: ''
+				},
+				url: {
+					stallList: "/sys/user/queryUserComponentData"
+				},
+				upOption: {
+					page: {
+						num: 0, // 褰撳墠椤电爜,榛樿0,鍥炶皟涔嬪墠浼氬姞1,鍗砪allback(page)浼氫粠1寮�濮�
+						size: 10 // 姣忛〉鏁版嵁鐨勬暟閲�
+					},
+					noMoreSize: 4, //濡傛灉鍒楄〃宸叉棤鏁版嵁,鍙缃垪琛ㄧ殑鎬绘暟閲忚澶т簬鍗婇〉鎵嶆樉绀烘棤鏇村鏁版嵁;閬垮厤鍒楄〃鏁版嵁杩囧皯(姣斿鍙湁涓�鏉℃暟鎹�),鏄剧ず鏃犳洿澶氭暟鎹細涓嶅ソ鐪�; 榛樿5
+					empty: {
+						tip: '~ 鏆傛棤鏁版嵁 ~', // 鎻愮ず
+
+					},
+					loading: '',
+					text: '鍏ㄩ儴',
+					isShowNoMore: false,
+					textNoMore: '鎴戞槸鏈夊簳绾跨殑 >_<'
+				},
+				msgList: [], //鍒楄〃鏁版嵁
+				announcement1: [],
+				msg1Count: "",
+				msg1Title: "",
+			}
+		},
+		computed: {
+			top() {
+				return this.CustomBar * 2 + 10
+			},
+			style() {
+				var StatusBar = this.StatusBar;
+				var CustomBar = this.CustomBar;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				return style
+			},
+		},
+
+		created() {
+
+
+
+		},
+		methods: {
+			search() {
+				this.$refs.popup.open();
+			},
+			upCallback(page) {
+				//鑱旂綉鍔犺浇鏁版嵁
+
+				this.$http.get(this.url.stallList, {
+					params: {
+						pageNo: page.num,
+						pageSize: page.size,
+						status: 1,
+						column: "createTime",
+						order: "desc"
+					}
+				}).then(res => {
+					//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+			},
+
+
+			searBut() {
+				this.$refs.popup.close()
+				this.msgList = [];
+				this.$http.get(this.url.stallList, {
+					params: {
+						pageNo: 1,
+						pageSize: this.upOption.page.size,
+						username: '*' + this.formData.name + '*',
+						column: "createTime",
+						order: "desc"
+					}
+				}).then(res => {
+					//鑱旂綉鎴愬姛鐨勫洖璋�,闅愯棌涓嬫媺鍒锋柊鍜屼笂鎷夊姞杞界殑鐘舵��;
+
+					this.announcement1 = res.data.result.records
+					this.mescroll.endSuccess(this.announcement1.length);
+					console.log("url", res)
+					//璁剧疆鍒楄〃鏁版嵁
+					if (res.data.success) {
+						console.log("res", res.data)
+						this.msg1Count = res.data.result.total
+						this.msg1Title = "閫氱煡(" + res.data.result.total + ")";
+						for (let annItem of this.announcement1) {
+							this.msgList.push(annItem)
+						}
+					}
+					if (page.num == 1) {
+						this.msgList = []; //濡傛灉鏄涓�椤甸渶鎵嬪姩鍒剁┖鍒楄〃
+						this.msgList = this.msgList.concat(this.announcement1); //杩藉姞鏂版暟鎹�
+					}
+
+				}).catch(() => {
+					//鑱旂綉澶辫触, 缁撴潫鍔犺浇
+					this.mescroll.endErr();
+					uni.showToast({
+						title: '缃戠粶寮傚父锛岃绋嶅悗鍐嶈瘯',
+						icon: 'none'
+					});
+				})
+
+
+
+
+			},
+
+			resetTask() {
+				
+				this.formData.name = '',
+				this.mescroll.resetUpScroll()
+				this.$refs.popup.close()
+			},
+
+			onClickProductionTask(item) {
+				uni.$emit('choes', {
+					msg: JSON.stringify(item)
+				})
+
+				uni.navigateBack({
+					delta: 1
+				})
+
+
+			},
+		},
+
+	}
+</script>
+
+<style>
+	.footer-box__item_content {
+		font-size: 12px;
+		color: #666;
+	}
+
+	.footer-box__item_input {
+		text-align: right;
+		font-size: 13px;
+		color: #000;
+	}
+
+	.footer-box {
+		padding: 10rpx;
+		display: flex;
+		justify-content: space-between;
+		flex-direction: row;
+	}
+
+	.footer-box__item_title {
+		margin-left: 10rpx;
+		font-size: 24v;
+		font-size: 12px;
+		color: #999;
+	}
+
+	.margin-bottom {
+		margin: 0 30px;
+	}
+
+	.input {
+		text-align: right;
+	}
+
+	.cu-form-group {
+		padding-left: 25px;
+		display: flex;
+		justify-content: space-between;
+		flex-direction: row;
+	}
+
+	.text {
+		font-size: 10pt;
+		text-align: right;
+	}
+
+	.content {
+		margin-top: 5px;
+	}
+
+	.content scroll-view {
+		scrollIndicator: "none"
+	}
+
+	.footer-box-btn {
+		padding: 10rpx;
+		display: flex;
+		justify-content: space-between;
+		flex-direction: row;
+		background: white;
+	}
+
+	.button-rese {
+		height: 50rpx;
+		display: flex;
+		margin-top: 10rpx;
+		line-height: 50rpx;
+		justify-content: center;
+		border-radius: 5px;
+		color: #FFFFFF;
+		/* 杩欓噷鍙互鏀规垚娓愬彉锛� background:linear-gradient(to right, #FFDE28,#FF3228) */
+		background-color: #1890FF;
+		font-size: 28rpx;
+
+	}
+</style>
\ No newline at end of file
diff --git a/static/home/128/icon_code.png b/static/home/128/icon_code.png
new file mode 100644
index 0000000..22b17a7
--- /dev/null
+++ b/static/home/128/icon_code.png
Binary files differ
diff --git a/static/home/128/icon_into.png b/static/home/128/icon_into.png
new file mode 100644
index 0000000..ca57187
--- /dev/null
+++ b/static/home/128/icon_into.png
Binary files differ
diff --git a/static/home/128/icon_out.png b/static/home/128/icon_out.png
new file mode 100644
index 0000000..24cf44d
--- /dev/null
+++ b/static/home/128/icon_out.png
Binary files differ
diff --git a/static/home/128/icon_quality.png b/static/home/128/icon_quality.png
new file mode 100644
index 0000000..0f6e1ca
--- /dev/null
+++ b/static/home/128/icon_quality.png
Binary files differ
diff --git a/static/home/128/icon_report.png b/static/home/128/icon_report.png
new file mode 100644
index 0000000..8e6ccd7
--- /dev/null
+++ b/static/home/128/icon_report.png
Binary files differ
diff --git a/static/home/128/icon_wait.png b/static/home/128/icon_wait.png
new file mode 100644
index 0000000..8a958c1
--- /dev/null
+++ b/static/home/128/icon_wait.png
Binary files differ
diff --git a/static/icon_dayin.png b/static/icon_dayin.png
new file mode 100644
index 0000000..a2e624a
--- /dev/null
+++ b/static/icon_dayin.png
Binary files differ
diff --git a/static/index_logo.png b/static/index_logo.png
new file mode 100644
index 0000000..34f164f
--- /dev/null
+++ b/static/index_logo.png
Binary files differ
diff --git a/uni_modules/uv-qrcode/changelog.md b/uni_modules/uv-qrcode/changelog.md
new file mode 100644
index 0000000..70d8ba1
--- /dev/null
+++ b/uni_modules/uv-qrcode/changelog.md
@@ -0,0 +1,13 @@
+## 1.0.5锛�2023-12-19锛�
+1. 浼樺寲
+## 1.0.4锛�2023-07-17锛�
+1. 浼樺寲鏂囨。
+2. 浼樺寲鍏朵粬
+## 1.0.3锛�2023-06-26锛�
+1. H5澧炲姞灞炴�5SaveTip 淇濆瓨浜岀淮鐮佹椂鍊欐槸鍚︽樉绀烘彁绀�
+## 1.0.2锛�2023-06-01锛�
+1. 淇鐐瑰嚮瑙﹀彂涓ゆ浜嬩欢鐨凚UG 
+## 1.0.1锛�2023-05-23锛�
+1. 淇鍦ㄩ儴鍒嗗钩鍙颁笉鏄剧ず鍔犺浇鏁堟灉鐨凚UG
+## 1.0.0锛�2023-05-17锛�
+1. 鏂板uv-qrcode缁勪欢
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/cache.js b/uni_modules/uv-qrcode/components/uv-qrcode/cache.js
new file mode 100644
index 0000000..d897d26
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/cache.js
@@ -0,0 +1 @@
+export const cacheImageList = [];
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/bridge/bridge-weex.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/bridge/bridge-weex.js
new file mode 100644
index 0000000..27086ec
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/bridge/bridge-weex.js
@@ -0,0 +1,241 @@
+const isWeex = typeof WXEnvironment !== 'undefined';
+const isWeexIOS = isWeex && /ios/i.test(WXEnvironment.platform);
+const isWeexAndroid = isWeex && !isWeexIOS;
+
+import GLmethod from '../context-webgl/GLmethod';
+
+const GCanvasModule =
+    (typeof weex !== 'undefined' && weex.requireModule) ? (weex.requireModule('gcanvas')) :
+        (typeof __weex_require__ !== 'undefined') ? (__weex_require__('@weex-module/gcanvas')) : {};
+
+let isDebugging = false;
+
+let isComboDisabled = false;
+
+const logCommand = (function () {
+    const methodQuery = [];
+    Object.keys(GLmethod).forEach(key => {
+        methodQuery[GLmethod[key]] = key;
+    })
+    const queryMethod = (id) => {
+        return methodQuery[parseInt(id)] || 'NotFoundMethod';
+    }
+    const logCommand = (id, cmds) => {
+        const mId = cmds.split(',')[0];
+        const mName = queryMethod(mId);
+        console.log(`=== callNative - componentId:${id}; method: ${mName}; cmds: ${cmds}`);
+    }
+    return logCommand;
+})();
+
+function joinArray(arr, sep) {
+    let res = '';
+    for (let i = 0; i < arr.length; i++) {
+        if (i !== 0) {
+            res += sep;
+        }
+        res += arr[i];
+    }
+    return res;
+}
+
+const commandsCache = {}
+
+const GBridge = {
+
+    callEnable: (ref, configArray) => {
+
+        commandsCache[ref] = [];
+
+        return GCanvasModule.enable({
+            componentId: ref,
+            config: configArray
+        });
+    },
+
+    callEnableDebug: () => {
+        isDebugging = true;
+    },
+
+    callEnableDisableCombo: () => {
+        isComboDisabled = true;
+    },
+
+    callSetContextType: function (componentId, context_type) {
+        GCanvasModule.setContextType(context_type, componentId);
+    },
+
+    callReset: function(id){
+        GCanvasModule.resetComponent && canvasModule.resetComponent(componentId);
+    },
+
+    render: isWeexIOS ? function (componentId) {
+        return GCanvasModule.extendCallNative({
+            contextId: componentId,
+            type: 0x60000001
+        });
+    } : function (componentId) {
+        return callGCanvasLinkNative(componentId, 0x60000001, 'render');
+    },
+
+    render2d: isWeexIOS ? function (componentId, commands, callback) {
+
+        if (isDebugging) {
+            console.log('>>> >>> render2d ===');
+            console.log('>>> commands: ' + commands);
+        }
+		
+        GCanvasModule.render([commands, callback?true:false], componentId, callback);
+
+    } : function (componentId, commands,callback) {
+
+        if (isDebugging) {
+            console.log('>>> >>> render2d ===');
+            console.log('>>> commands: ' + commands);
+        }
+
+        callGCanvasLinkNative(componentId, 0x20000001, commands);
+		if(callback){
+		callback();
+		}
+    },
+
+    callExtendCallNative: isWeexIOS ? function (componentId, cmdArgs) {
+
+        throw 'should not be here anymore ' + cmdArgs;
+
+    } : function (componentId, cmdArgs) {
+
+        throw 'should not be here anymore ' + cmdArgs;
+
+    },
+
+
+    flushNative: isWeexIOS ? function (componentId) {
+
+        const cmdArgs = joinArray(commandsCache[componentId], ';');
+        commandsCache[componentId] = [];
+
+        if (isDebugging) {
+            console.log('>>> >>> flush native ===');
+            console.log('>>> commands: ' + cmdArgs);
+        }
+
+        const result = GCanvasModule.extendCallNative({
+            "contextId": componentId,
+            "type": 0x60000000,
+            "args": cmdArgs
+        });
+
+        const res = result && result.result;
+
+        if (isDebugging) {
+            console.log('>>> result: ' + res);
+        }
+
+        return res;
+
+    } : function (componentId) {
+
+        const cmdArgs = joinArray(commandsCache[componentId], ';');
+        commandsCache[componentId] = [];
+
+        if (isDebugging) {
+            console.log('>>> >>> flush native ===');
+            console.log('>>> commands: ' + cmdArgs);
+        }
+
+        const result = callGCanvasLinkNative(componentId, 0x60000000, cmdArgs);
+
+        if (isDebugging) {
+            console.log('>>> result: ' + result);
+        }
+
+        return result;
+    },
+
+    callNative: function (componentId, cmdArgs, cache) {
+
+        if (isDebugging) {
+            logCommand(componentId, cmdArgs);
+        }
+
+        commandsCache[componentId].push(cmdArgs);
+
+        if (!cache || isComboDisabled) {
+            return GBridge.flushNative(componentId);
+        } else {
+            return undefined;
+        }
+    },
+
+    texImage2D(componentId, ...args) {
+        if (isWeexIOS) {
+            if (args.length === 6) {
+                const [target, level, internalformat, format, type, image] = args;
+                GBridge.callNative(
+                    componentId,
+                    GLmethod.texImage2D + ',' + 6 + ',' + target + ',' + level + ',' + internalformat + ',' + format + ',' + type + ',' + image.src
+                )
+            } else if (args.length === 9) {
+                const [target, level, internalformat, width, height, border, format, type, image] = args;
+                GBridge.callNative(
+                    componentId,
+                    GLmethod.texImage2D + ',' + 9 + ',' + target + ',' + level + ',' + internalformat + ',' + width + ',' + height + ',' + border + ',' +
+                    + format + ',' + type + ',' + (image ? image.src : 0)
+                )
+            }
+        } else if (isWeexAndroid) {
+            if (args.length === 6) {
+                const [target, level, internalformat, format, type, image] = args;
+                GCanvasModule.texImage2D(componentId, target, level, internalformat, format, type, image.src);
+            } else if (args.length === 9) {
+                const [target, level, internalformat, width, height, border, format, type, image] = args;
+                GCanvasModule.texImage2D(componentId, target, level, internalformat, width, height, border, format, type, (image ? image.src : 0));
+            }
+        }
+    },
+
+    texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image) {
+        if (isWeexIOS) {
+            if (arguments.length === 8) {
+                GBridge.callNative(
+                    componentId,
+                    GLmethod.texSubImage2D + ',' + 6 + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset, + ',' + format + ',' + type + ',' + image.src
+                )
+            }
+        } else if (isWeexAndroid) {
+            GCanvasModule.texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image.src);
+        }
+    },
+
+    bindImageTexture(componentId, src, imageId) {
+        GCanvasModule.bindImageTexture([src, imageId], componentId);
+    },
+
+    perloadImage([url, id], callback) {
+        GCanvasModule.preLoadImage([url, id], function (image) {
+            image.url = url;
+            image.id = id;
+            callback(image);
+        });
+    },
+	
+	measureText(text, fontStyle, componentId) {
+	    return GCanvasModule.measureText([text, fontStyle], componentId);
+	},
+	
+	getImageData (componentId, x, y, w, h, callback) {
+		GCanvasModule.getImageData([x, y,w,h],componentId,callback);
+	},
+	
+	putImageData (componentId, data, x, y, w, h, callback) {
+		GCanvasModule.putImageData([x, y,w,h,data],componentId,callback);
+	},
+	
+	toTempFilePath(componentId, x, y, width, height, destWidth, destHeight, fileType, quality, callback){ 
+		GCanvasModule.toTempFilePath([x, y, width,height, destWidth, destHeight, fileType, quality], componentId, callback);
+	}
+}
+
+export default GBridge;
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js
new file mode 100644
index 0000000..3e7f03a
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js
@@ -0,0 +1,18 @@
+class FillStyleLinearGradient {
+
+    constructor(x0, y0, x1, y1) {
+        this._start_pos = { _x: x0, _y: y0 };
+        this._end_pos = { _x: x1, _y: y1 };
+        this._stop_count = 0;
+        this._stops = [0, 0, 0, 0, 0];
+    }
+
+    addColorStop = function (pos, color) {
+        if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
+            this._stops[this._stop_count] = { _pos: pos, _color: color };
+            this._stop_count++;
+        }
+    }
+}
+
+export default FillStyleLinearGradient;
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStylePattern.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStylePattern.js
new file mode 100644
index 0000000..6e4f646
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStylePattern.js
@@ -0,0 +1,8 @@
+class FillStylePattern {
+    constructor(img, pattern) {
+        this._style = pattern;
+        this._img = img;
+    }
+}
+
+export default FillStylePattern;
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js
new file mode 100644
index 0000000..7790596
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js
@@ -0,0 +1,17 @@
+class FillStyleRadialGradient {
+    constructor(x0, y0, r0, x1, y1, r1) {
+        this._start_pos = { _x: x0, _y: y0, _r: r0 };
+        this._end_pos = { _x: x1, _y: y1, _r: r1 };
+        this._stop_count = 0;
+        this._stops = [0, 0, 0, 0, 0];
+    }
+
+    addColorStop(pos, color) {
+        if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
+            this._stops[this._stop_count] = { _pos: pos, _color: color };
+            this._stop_count++;
+        }
+    }
+}
+
+export default FillStyleRadialGradient;
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/RenderingContext.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/RenderingContext.js
new file mode 100644
index 0000000..e6b8f48
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/RenderingContext.js
@@ -0,0 +1,666 @@
+import FillStylePattern from './FillStylePattern';
+import FillStyleLinearGradient from './FillStyleLinearGradient';
+import FillStyleRadialGradient from './FillStyleRadialGradient';
+import GImage from '../env/image.js';
+import {
+	ArrayBufferToBase64,
+	Base64ToUint8ClampedArray
+} from '../env/tool.js';
+
+export default class CanvasRenderingContext2D {
+
+	_drawCommands = '';
+
+	_globalAlpha = 1.0;
+
+	_fillStyle = 'rgb(0,0,0)';
+	_strokeStyle = 'rgb(0,0,0)';
+
+	_lineWidth = 1;
+	_lineCap = 'butt';
+	_lineJoin = 'miter';
+
+	_miterLimit = 10;
+
+	_globalCompositeOperation = 'source-over';
+
+	_textAlign = 'start';
+	_textBaseline = 'alphabetic';
+
+	_font = '10px sans-serif';
+
+	_savedGlobalAlpha = [];
+
+	timer = null;
+	componentId = null;
+
+	_notCommitDrawImageCache = [];
+	_needRedrawImageCache = [];
+	_redrawCommands = '';
+	_autoSaveContext = true;
+	// _imageMap = new GHashMap();
+	// _textureMap = new GHashMap();
+
+	constructor() {
+		this.className = 'CanvasRenderingContext2D';
+		//this.save()
+	}
+
+	setFillStyle(value) {
+		this.fillStyle = value;
+	}
+
+	set fillStyle(value) {
+		this._fillStyle = value;
+
+		if (typeof(value) == 'string') {
+			this._drawCommands = this._drawCommands.concat("F" + value + ";");
+		} else if (value instanceof FillStylePattern) {
+			const image = value._img;
+			if (!image.complete) {
+				image.onload = () => {
+					var index = this._needRedrawImageCache.indexOf(image);
+					if (index > -1) {
+						this._needRedrawImageCache.splice(index, 1);
+						CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+						this._redrawflush(true);
+					}
+				}
+				this._notCommitDrawImageCache.push(image);
+			} else {
+				CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			}
+
+			//CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
+		} else if (value instanceof FillStyleLinearGradient) {
+			var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
+				value._stop_count;
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		} else if (value instanceof FillStyleRadialGradient) {
+			var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
+				.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + value._end_pos._r.toFixed(2) + "," +
+				value._stop_count;
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		}
+	}
+
+	get fillStyle() {
+		return this._fillStyle;
+	}
+
+	get globalAlpha() {
+		return this._globalAlpha;
+	}
+
+	setGlobalAlpha(value) {
+		this.globalAlpha = value;
+	}
+
+	set globalAlpha(value) {
+		this._globalAlpha = value;
+		this._drawCommands = this._drawCommands.concat("a" + value.toFixed(2) + ";");
+	}
+
+
+	get strokeStyle() {
+		return this._strokeStyle;
+	}
+
+	setStrokeStyle(value) {
+		this.strokeStyle = value;
+	}
+
+	set strokeStyle(value) {
+
+		this._strokeStyle = value;
+
+		if (typeof(value) == 'string') {
+			this._drawCommands = this._drawCommands.concat("S" + value + ";");
+		} else if (value instanceof FillStylePattern) {
+			CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
+		} else if (value instanceof FillStyleLinearGradient) {
+			var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
+				value._stop_count;
+
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		} else if (value instanceof FillStyleRadialGradient) {
+			var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
+				.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y + ",".toFixed(2) + value._end_pos._r.toFixed(2) + "," +
+				value._stop_count;
+
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		}
+	}
+
+	get lineWidth() {
+		return this._lineWidth;
+	}
+
+	setLineWidth(value) {
+		this.lineWidth = value;
+	}
+
+	set lineWidth(value) {
+		this._lineWidth = value;
+		this._drawCommands = this._drawCommands.concat("W" + value + ";");
+	}
+
+	get lineCap() {
+		return this._lineCap;
+	}
+
+	setLineCap(value) {
+		this.lineCap = value;
+	}
+
+	set lineCap(value) {
+		this._lineCap = value;
+		this._drawCommands = this._drawCommands.concat("C" + value + ";");
+	}
+
+	get lineJoin() {
+		return this._lineJoin;
+	}
+
+	setLineJoin(value) {
+		this.lineJoin = value
+	}
+
+	set lineJoin(value) {
+		this._lineJoin = value;
+		this._drawCommands = this._drawCommands.concat("J" + value + ";");
+	}
+
+	get miterLimit() {
+		return this._miterLimit;
+	}
+
+	setMiterLimit(value) {
+		this.miterLimit = value
+	}
+
+	set miterLimit(value) {
+		this._miterLimit = value;
+		this._drawCommands = this._drawCommands.concat("M" + value + ";");
+	}
+
+	get globalCompositeOperation() {
+		return this._globalCompositeOperation;
+	}
+
+	set globalCompositeOperation(value) {
+
+		this._globalCompositeOperation = value;
+		let mode = 0;
+		switch (value) {
+			case "source-over":
+				mode = 0;
+				break;
+			case "source-atop":
+				mode = 5;
+				break;
+			case "source-in":
+				mode = 0;
+				break;
+			case "source-out":
+				mode = 2;
+				break;
+			case "destination-over":
+				mode = 4;
+				break;
+			case "destination-atop":
+				mode = 4;
+				break;
+			case "destination-in":
+				mode = 4;
+				break;
+			case "destination-out":
+				mode = 3;
+				break;
+			case "lighter":
+				mode = 1;
+				break;
+			case "copy":
+				mode = 2;
+				break;
+			case "xor":
+				mode = 6;
+				break;
+			default:
+				mode = 0;
+		}
+
+		this._drawCommands = this._drawCommands.concat("B" + mode + ";");
+	}
+
+	get textAlign() {
+		return this._textAlign;
+	}
+
+	setTextAlign(value) {
+		this.textAlign = value
+	}
+
+	set textAlign(value) {
+
+		this._textAlign = value;
+		let Align = 0;
+		switch (value) {
+			case "start":
+				Align = 0;
+				break;
+			case "end":
+				Align = 1;
+				break;
+			case "left":
+				Align = 2;
+				break;
+			case "center":
+				Align = 3;
+				break;
+			case "right":
+				Align = 4;
+				break;
+			default:
+				Align = 0;
+		}
+
+		this._drawCommands = this._drawCommands.concat("A" + Align + ";");
+	}
+
+	get textBaseline() {
+		return this._textBaseline;
+	}
+
+	setTextBaseline(value) {
+		this.textBaseline = value
+	}
+
+	set textBaseline(value) {
+		this._textBaseline = value;
+		let baseline = 0;
+		switch (value) {
+			case "alphabetic":
+				baseline = 0;
+				break;
+			case "middle":
+				baseline = 1;
+				break;
+			case "top":
+				baseline = 2;
+				break;
+			case "hanging":
+				baseline = 3;
+				break;
+			case "bottom":
+				baseline = 4;
+				break;
+			case "ideographic":
+				baseline = 5;
+				break;
+			default:
+				baseline = 0;
+				break;
+		}
+
+		this._drawCommands = this._drawCommands.concat("E" + baseline + ";");
+	}
+
+	get font() {
+		return this._font;
+	}
+
+	setFontSize(size) {
+		var str = this._font;
+		var strs = str.trim().split(/\s+/);
+		for (var i = 0; i < strs.length; i++) {
+			var values = ["normal", "italic", "oblique", "normal", "small-caps", "normal", "bold",
+				"bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900",
+				"normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
+				"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
+			];
+
+			if (-1 == values.indexOf(strs[i].trim())) {
+				if (typeof size === 'string') {
+					strs[i] = size;
+				} else if (typeof size === 'number') {
+					strs[i] = String(size) + 'px';
+				}
+				break;
+			}
+		}
+		this.font = strs.join(" ");
+	}
+
+	set font(value) {
+		this._font = value;
+		this._drawCommands = this._drawCommands.concat("j" + value + ";");
+	}
+
+	setTransform(a, b, c, d, tx, ty) {
+		this._drawCommands = this._drawCommands.concat("t" +
+			(a === 1 ? "1" : a.toFixed(2)) + "," +
+			(b === 0 ? "0" : b.toFixed(2)) + "," +
+			(c === 0 ? "0" : c.toFixed(2)) + "," +
+			(d === 1 ? "1" : d.toFixed(2)) + "," + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
+	}
+
+	transform(a, b, c, d, tx, ty) {
+		this._drawCommands = this._drawCommands.concat("f" +
+			(a === 1 ? "1" : a.toFixed(2)) + "," +
+			(b === 0 ? "0" : b.toFixed(2)) + "," +
+			(c === 0 ? "0" : c.toFixed(2)) + "," +
+			(d === 1 ? "1" : d.toFixed(2)) + "," + tx + "," + ty + ";");
+	}
+
+	resetTransform() {
+		this._drawCommands = this._drawCommands.concat("m;");
+	}
+
+	scale(a, d) {
+		this._drawCommands = this._drawCommands.concat("k" + a.toFixed(2) + "," +
+			d.toFixed(2) + ";");
+	}
+
+	rotate(angle) {
+		this._drawCommands = this._drawCommands
+			.concat("r" + angle.toFixed(6) + ";");
+	}
+
+	translate(tx, ty) {
+		this._drawCommands = this._drawCommands.concat("l" + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
+	}
+
+	save() {
+		this._savedGlobalAlpha.push(this._globalAlpha);
+		this._drawCommands = this._drawCommands.concat("v;");
+	}
+
+	restore() {
+		this._drawCommands = this._drawCommands.concat("e;");
+		this._globalAlpha = this._savedGlobalAlpha.pop();
+	}
+
+	createPattern(img, pattern) {
+		if (typeof img === 'string') {
+			var imgObj = new GImage();
+			imgObj.src = img;
+			img = imgObj;
+		}
+		return new FillStylePattern(img, pattern);
+	}
+
+	createLinearGradient(x0, y0, x1, y1) {
+		return new FillStyleLinearGradient(x0, y0, x1, y1);
+	}
+
+	createRadialGradient = function(x0, y0, r0, x1, y1, r1) {
+		return new FillStyleRadialGradient(x0, y0, r0, x1, y1, r1);
+	};
+
+	createCircularGradient = function(x0, y0, r0) {
+		return new FillStyleRadialGradient(x0, y0, 0, x0, y0, r0);
+	};
+
+	strokeRect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("s" + x + "," + y + "," + w + "," + h + ";");
+	}
+
+
+	clearRect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("c" + x + "," + y + "," + w +
+			"," + h + ";");
+	}
+
+	clip() {
+		this._drawCommands = this._drawCommands.concat("p;");
+	}
+
+	resetClip() {
+		this._drawCommands = this._drawCommands.concat("q;");
+	}
+
+	closePath() {
+		this._drawCommands = this._drawCommands.concat("o;");
+	}
+
+	moveTo(x, y) {
+		this._drawCommands = this._drawCommands.concat("g" + x.toFixed(2) + "," + y.toFixed(2) + ";");
+	}
+
+	lineTo(x, y) {
+		this._drawCommands = this._drawCommands.concat("i" + x.toFixed(2) + "," + y.toFixed(2) + ";");
+	}
+
+	quadraticCurveTo = function(cpx, cpy, x, y) {
+		this._drawCommands = this._drawCommands.concat("u" + cpx + "," + cpy + "," + x + "," + y + ";");
+	}
+
+	bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, ) {
+		this._drawCommands = this._drawCommands.concat(
+			"z" + cp1x.toFixed(2) + "," + cp1y.toFixed(2) + "," + cp2x.toFixed(2) + "," + cp2y.toFixed(2) + "," +
+			x.toFixed(2) + "," + y.toFixed(2) + ";");
+	}
+
+	arcTo(x1, y1, x2, y2, radius) {
+		this._drawCommands = this._drawCommands.concat("h" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + radius + ";");
+	}
+
+	beginPath() {
+		this._drawCommands = this._drawCommands.concat("b;");
+	}
+
+
+	fillRect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("n" + x + "," + y + "," + w +
+			"," + h + ";");
+	}
+
+	rect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("w" + x + "," + y + "," + w + "," + h + ";");
+	}
+
+	fill() {
+		this._drawCommands = this._drawCommands.concat("L;");
+	}
+
+	stroke(path) {
+		this._drawCommands = this._drawCommands.concat("x;");
+	}
+
+	arc(x, y, radius, startAngle, endAngle, anticlockwise) {
+
+		let ianticlockwise = 0;
+		if (anticlockwise) {
+			ianticlockwise = 1;
+		}
+
+		this._drawCommands = this._drawCommands.concat(
+			"y" + x.toFixed(2) + "," + y.toFixed(2) + "," +
+			radius.toFixed(2) + "," + startAngle + "," + endAngle + "," + ianticlockwise +
+			";"
+		);
+	}
+
+	fillText(text, x, y) {
+		let tmptext = text.replace(/!/g, "!!");
+		tmptext = tmptext.replace(/,/g, "!,");
+		tmptext = tmptext.replace(/;/g, "!;");
+		this._drawCommands = this._drawCommands.concat("T" + tmptext + "," + x + "," + y + ",0.0;");
+	}
+
+	strokeText = function(text, x, y) {
+		let tmptext = text.replace(/!/g, "!!");
+		tmptext = tmptext.replace(/,/g, "!,");
+		tmptext = tmptext.replace(/;/g, "!;");
+		this._drawCommands = this._drawCommands.concat("U" + tmptext + "," + x + "," + y + ",0.0;");
+	}
+
+	measureText(text) {
+		return CanvasRenderingContext2D.GBridge.measureText(text, this.font, this.componentId);
+	}
+
+	isPointInPath = function(x, y) {
+		throw new Error('GCanvas not supported yet');
+	}
+
+	drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
+		if (typeof image === 'string') {
+			var imgObj = new GImage();
+			imgObj.src = image;
+			image = imgObj;
+		}
+		if (image instanceof GImage) {
+			if (!image.complete) {
+				imgObj.onload = () => {
+					var index = this._needRedrawImageCache.indexOf(image);
+					if (index > -1) {
+						this._needRedrawImageCache.splice(index, 1);
+						CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+						this._redrawflush(true);
+					}
+				}
+				this._notCommitDrawImageCache.push(image);
+			} else {
+				CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			}
+			var srcArgs = [image, sx, sy, sw, sh, dx, dy, dw, dh];
+			var args = [];
+			for (var arg in srcArgs) {
+				if (typeof(srcArgs[arg]) != 'undefined') {
+					args.push(srcArgs[arg]);
+				}
+			}
+			this.__drawImage.apply(this, args);
+			//this.__drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);
+		}
+	}
+
+	__drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
+		const numArgs = arguments.length;
+
+		function drawImageCommands() {
+
+			if (numArgs === 3) {
+				const x = parseFloat(sx) || 0.0;
+				const y = parseFloat(sy) || 0.0;
+
+				return ("d" + image._id + ",0,0," +
+					image.width + "," + image.height + "," +
+					x + "," + y + "," + image.width + "," + image.height + ";");
+			} else if (numArgs === 5) {
+				const x = parseFloat(sx) || 0.0;
+				const y = parseFloat(sy) || 0.0;
+				const width = parseInt(sw) || image.width;
+				const height = parseInt(sh) || image.height;
+
+				return ("d" + image._id + ",0,0," +
+					image.width + "," + image.height + "," +
+					x + "," + y + "," + width + "," + height + ";");
+			} else if (numArgs === 9) {
+				sx = parseFloat(sx) || 0.0;
+				sy = parseFloat(sy) || 0.0;
+				sw = parseInt(sw) || image.width;
+				sh = parseInt(sh) || image.height;
+				dx = parseFloat(dx) || 0.0;
+				dy = parseFloat(dy) || 0.0;
+				dw = parseInt(dw) || image.width;
+				dh = parseInt(dh) || image.height;
+
+				return ("d" + image._id + "," +
+					sx + "," + sy + "," + sw + "," + sh + "," +
+					dx + "," + dy + "," + dw + "," + dh + ";");
+			}
+		}
+		this._drawCommands += drawImageCommands();
+	}
+
+	_flush(reserve, callback) {
+		const commands = this._drawCommands;
+		this._drawCommands = '';
+		CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
+		this._needRender = false;
+	}
+
+	_redrawflush(reserve, callback) {
+		const commands = this._redrawCommands;
+		CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
+		if (this._needRedrawImageCache.length == 0) {
+			this._redrawCommands = '';
+		}
+	}
+
+	draw(reserve, callback) {
+		if (!reserve) {
+			this._globalAlpha = this._savedGlobalAlpha.pop();
+			this._savedGlobalAlpha.push(this._globalAlpha);
+			this._redrawCommands = this._drawCommands;
+			this._needRedrawImageCache = this._notCommitDrawImageCache;
+			if (this._autoSaveContext) {
+				this._drawCommands = ("v;" + this._drawCommands);
+				this._autoSaveContext = false;
+			} else {
+				this._drawCommands = ("e;X;v;" + this._drawCommands);
+			}
+		} else {
+			this._needRedrawImageCache = this._needRedrawImageCache.concat(this._notCommitDrawImageCache);
+			this._redrawCommands += this._drawCommands;
+			if (this._autoSaveContext) {
+				this._drawCommands = ("v;" + this._drawCommands);
+				this._autoSaveContext = false;
+			}
+		}
+		this._notCommitDrawImageCache = [];
+		if (this._flush) {
+			this._flush(reserve, callback);
+		}
+	}
+
+	getImageData(x, y, w, h, callback) {
+		CanvasRenderingContext2D.GBridge.getImageData(this.componentId, x, y, w, h, function(res) {
+			res.data = Base64ToUint8ClampedArray(res.data);
+			if (typeof(callback) == 'function') {
+				callback(res);
+			}
+		});
+	}
+
+	putImageData(data, x, y, w, h, callback) {
+		if (data instanceof Uint8ClampedArray) {
+			data = ArrayBufferToBase64(data);
+			CanvasRenderingContext2D.GBridge.putImageData(this.componentId, data, x, y, w, h, function(res) {
+				if (typeof(callback) == 'function') {
+					callback(res);
+				}
+			});
+		}
+	}
+
+	toTempFilePath(x, y, width, height, destWidth, destHeight, fileType, quality, callback) {
+		CanvasRenderingContext2D.GBridge.toTempFilePath(this.componentId, x, y, width, height, destWidth, destHeight,
+			fileType, quality,
+			function(res) {
+				if (typeof(callback) == 'function') {
+					callback(res);
+				}
+			});
+	}
+}
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ActiveInfo.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ActiveInfo.js
new file mode 100644
index 0000000..b495129
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ActiveInfo.js
@@ -0,0 +1,11 @@
+export default class WebGLActiveInfo {
+    className = 'WebGLActiveInfo';
+
+    constructor({
+        type, name, size
+    }) {
+        this.type = type;
+        this.name = name;
+        this.size = size;
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Buffer.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Buffer.js
new file mode 100644
index 0000000..4800f67
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Buffer.js
@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLBuffer';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLBuffer {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Framebuffer.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Framebuffer.js
new file mode 100644
index 0000000..28b46d3
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Framebuffer.js
@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLFrameBuffer';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLFramebuffer {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLenum.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLenum.js
new file mode 100644
index 0000000..ac5544d
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLenum.js
@@ -0,0 +1,298 @@
+export default {
+    "DEPTH_BUFFER_BIT": 256,
+    "STENCIL_BUFFER_BIT": 1024,
+    "COLOR_BUFFER_BIT": 16384,
+    "POINTS": 0,
+    "LINES": 1,
+    "LINE_LOOP": 2,
+    "LINE_STRIP": 3,
+    "TRIANGLES": 4,
+    "TRIANGLE_STRIP": 5,
+    "TRIANGLE_FAN": 6,
+    "ZERO": 0,
+    "ONE": 1,
+    "SRC_COLOR": 768,
+    "ONE_MINUS_SRC_COLOR": 769,
+    "SRC_ALPHA": 770,
+    "ONE_MINUS_SRC_ALPHA": 771,
+    "DST_ALPHA": 772,
+    "ONE_MINUS_DST_ALPHA": 773,
+    "DST_COLOR": 774,
+    "ONE_MINUS_DST_COLOR": 775,
+    "SRC_ALPHA_SATURATE": 776,
+    "FUNC_ADD": 32774,
+    "BLEND_EQUATION": 32777,
+    "BLEND_EQUATION_RGB": 32777,
+    "BLEND_EQUATION_ALPHA": 34877,
+    "FUNC_SUBTRACT": 32778,
+    "FUNC_REVERSE_SUBTRACT": 32779,
+    "BLEND_DST_RGB": 32968,
+    "BLEND_SRC_RGB": 32969,
+    "BLEND_DST_ALPHA": 32970,
+    "BLEND_SRC_ALPHA": 32971,
+    "CONSTANT_COLOR": 32769,
+    "ONE_MINUS_CONSTANT_COLOR": 32770,
+    "CONSTANT_ALPHA": 32771,
+    "ONE_MINUS_CONSTANT_ALPHA": 32772,
+    "BLEND_COLOR": 32773,
+    "ARRAY_BUFFER": 34962,
+    "ELEMENT_ARRAY_BUFFER": 34963,
+    "ARRAY_BUFFER_BINDING": 34964,
+    "ELEMENT_ARRAY_BUFFER_BINDING": 34965,
+    "STREAM_DRAW": 35040,
+    "STATIC_DRAW": 35044,
+    "DYNAMIC_DRAW": 35048,
+    "BUFFER_SIZE": 34660,
+    "BUFFER_USAGE": 34661,
+    "CURRENT_VERTEX_ATTRIB": 34342,
+    "FRONT": 1028,
+    "BACK": 1029,
+    "FRONT_AND_BACK": 1032,
+    "TEXTURE_2D": 3553,
+    "CULL_FACE": 2884,
+    "BLEND": 3042,
+    "DITHER": 3024,
+    "STENCIL_TEST": 2960,
+    "DEPTH_TEST": 2929,
+    "SCISSOR_TEST": 3089,
+    "POLYGON_OFFSET_FILL": 32823,
+    "SAMPLE_ALPHA_TO_COVERAGE": 32926,
+    "SAMPLE_COVERAGE": 32928,
+    "NO_ERROR": 0,
+    "INVALID_ENUM": 1280,
+    "INVALID_VALUE": 1281,
+    "INVALID_OPERATION": 1282,
+    "OUT_OF_MEMORY": 1285,
+    "CW": 2304,
+    "CCW": 2305,
+    "LINE_WIDTH": 2849,
+    "ALIASED_POINT_SIZE_RANGE": 33901,
+    "ALIASED_LINE_WIDTH_RANGE": 33902,
+    "CULL_FACE_MODE": 2885,
+    "FRONT_FACE": 2886,
+    "DEPTH_RANGE": 2928,
+    "DEPTH_WRITEMASK": 2930,
+    "DEPTH_CLEAR_VALUE": 2931,
+    "DEPTH_FUNC": 2932,
+    "STENCIL_CLEAR_VALUE": 2961,
+    "STENCIL_FUNC": 2962,
+    "STENCIL_FAIL": 2964,
+    "STENCIL_PASS_DEPTH_FAIL": 2965,
+    "STENCIL_PASS_DEPTH_PASS": 2966,
+    "STENCIL_REF": 2967,
+    "STENCIL_VALUE_MASK": 2963,
+    "STENCIL_WRITEMASK": 2968,
+    "STENCIL_BACK_FUNC": 34816,
+    "STENCIL_BACK_FAIL": 34817,
+    "STENCIL_BACK_PASS_DEPTH_FAIL": 34818,
+    "STENCIL_BACK_PASS_DEPTH_PASS": 34819,
+    "STENCIL_BACK_REF": 36003,
+    "STENCIL_BACK_VALUE_MASK": 36004,
+    "STENCIL_BACK_WRITEMASK": 36005,
+    "VIEWPORT": 2978,
+    "SCISSOR_BOX": 3088,
+    "COLOR_CLEAR_VALUE": 3106,
+    "COLOR_WRITEMASK": 3107,
+    "UNPACK_ALIGNMENT": 3317,
+    "PACK_ALIGNMENT": 3333,
+    "MAX_TEXTURE_SIZE": 3379,
+    "MAX_VIEWPORT_DIMS": 3386,
+    "SUBPIXEL_BITS": 3408,
+    "RED_BITS": 3410,
+    "GREEN_BITS": 3411,
+    "BLUE_BITS": 3412,
+    "ALPHA_BITS": 3413,
+    "DEPTH_BITS": 3414,
+    "STENCIL_BITS": 3415,
+    "POLYGON_OFFSET_UNITS": 10752,
+    "POLYGON_OFFSET_FACTOR": 32824,
+    "TEXTURE_BINDING_2D": 32873,
+    "SAMPLE_BUFFERS": 32936,
+    "SAMPLES": 32937,
+    "SAMPLE_COVERAGE_VALUE": 32938,
+    "SAMPLE_COVERAGE_INVERT": 32939,
+    "COMPRESSED_TEXTURE_FORMATS": 34467,
+    "DONT_CARE": 4352,
+    "FASTEST": 4353,
+    "NICEST": 4354,
+    "GENERATE_MIPMAP_HINT": 33170,
+    "BYTE": 5120,
+    "UNSIGNED_BYTE": 5121,
+    "SHORT": 5122,
+    "UNSIGNED_SHORT": 5123,
+    "INT": 5124,
+    "UNSIGNED_INT": 5125,
+    "FLOAT": 5126,
+    "DEPTH_COMPONENT": 6402,
+    "ALPHA": 6406,
+    "RGB": 6407,
+    "RGBA": 6408,
+    "LUMINANCE": 6409,
+    "LUMINANCE_ALPHA": 6410,
+    "UNSIGNED_SHORT_4_4_4_4": 32819,
+    "UNSIGNED_SHORT_5_5_5_1": 32820,
+    "UNSIGNED_SHORT_5_6_5": 33635,
+    "FRAGMENT_SHADER": 35632,
+    "VERTEX_SHADER": 35633,
+    "MAX_VERTEX_ATTRIBS": 34921,
+    "MAX_VERTEX_UNIFORM_VECTORS": 36347,
+    "MAX_VARYING_VECTORS": 36348,
+    "MAX_COMBINED_TEXTURE_IMAGE_UNITS": 35661,
+    "MAX_VERTEX_TEXTURE_IMAGE_UNITS": 35660,
+    "MAX_TEXTURE_IMAGE_UNITS": 34930,
+    "MAX_FRAGMENT_UNIFORM_VECTORS": 36349,
+    "SHADER_TYPE": 35663,
+    "DELETE_STATUS": 35712,
+    "LINK_STATUS": 35714,
+    "VALIDATE_STATUS": 35715,
+    "ATTACHED_SHADERS": 35717,
+    "ACTIVE_UNIFORMS": 35718,
+    "ACTIVE_ATTRIBUTES": 35721,
+    "SHADING_LANGUAGE_VERSION": 35724,
+    "CURRENT_PROGRAM": 35725,
+    "NEVER": 512,
+    "LESS": 513,
+    "EQUAL": 514,
+    "LEQUAL": 515,
+    "GREATER": 516,
+    "NOTEQUAL": 517,
+    "GEQUAL": 518,
+    "ALWAYS": 519,
+    "KEEP": 7680,
+    "REPLACE": 7681,
+    "INCR": 7682,
+    "DECR": 7683,
+    "INVERT": 5386,
+    "INCR_WRAP": 34055,
+    "DECR_WRAP": 34056,
+    "VENDOR": 7936,
+    "RENDERER": 7937,
+    "VERSION": 7938,
+    "NEAREST": 9728,
+    "LINEAR": 9729,
+    "NEAREST_MIPMAP_NEAREST": 9984,
+    "LINEAR_MIPMAP_NEAREST": 9985,
+    "NEAREST_MIPMAP_LINEAR": 9986,
+    "LINEAR_MIPMAP_LINEAR": 9987,
+    "TEXTURE_MAG_FILTER": 10240,
+    "TEXTURE_MIN_FILTER": 10241,
+    "TEXTURE_WRAP_S": 10242,
+    "TEXTURE_WRAP_T": 10243,
+    "TEXTURE": 5890,
+    "TEXTURE_CUBE_MAP": 34067,
+    "TEXTURE_BINDING_CUBE_MAP": 34068,
+    "TEXTURE_CUBE_MAP_POSITIVE_X": 34069,
+    "TEXTURE_CUBE_MAP_NEGATIVE_X": 34070,
+    "TEXTURE_CUBE_MAP_POSITIVE_Y": 34071,
+    "TEXTURE_CUBE_MAP_NEGATIVE_Y": 34072,
+    "TEXTURE_CUBE_MAP_POSITIVE_Z": 34073,
+    "TEXTURE_CUBE_MAP_NEGATIVE_Z": 34074,
+    "MAX_CUBE_MAP_TEXTURE_SIZE": 34076,
+    "TEXTURE0": 33984,
+    "TEXTURE1": 33985,
+    "TEXTURE2": 33986,
+    "TEXTURE3": 33987,
+    "TEXTURE4": 33988,
+    "TEXTURE5": 33989,
+    "TEXTURE6": 33990,
+    "TEXTURE7": 33991,
+    "TEXTURE8": 33992,
+    "TEXTURE9": 33993,
+    "TEXTURE10": 33994,
+    "TEXTURE11": 33995,
+    "TEXTURE12": 33996,
+    "TEXTURE13": 33997,
+    "TEXTURE14": 33998,
+    "TEXTURE15": 33999,
+    "TEXTURE16": 34000,
+    "TEXTURE17": 34001,
+    "TEXTURE18": 34002,
+    "TEXTURE19": 34003,
+    "TEXTURE20": 34004,
+    "TEXTURE21": 34005,
+    "TEXTURE22": 34006,
+    "TEXTURE23": 34007,
+    "TEXTURE24": 34008,
+    "TEXTURE25": 34009,
+    "TEXTURE26": 34010,
+    "TEXTURE27": 34011,
+    "TEXTURE28": 34012,
+    "TEXTURE29": 34013,
+    "TEXTURE30": 34014,
+    "TEXTURE31": 34015,
+    "ACTIVE_TEXTURE": 34016,
+    "REPEAT": 10497,
+    "CLAMP_TO_EDGE": 33071,
+    "MIRRORED_REPEAT": 33648,
+    "FLOAT_VEC2": 35664,
+    "FLOAT_VEC3": 35665,
+    "FLOAT_VEC4": 35666,
+    "INT_VEC2": 35667,
+    "INT_VEC3": 35668,
+    "INT_VEC4": 35669,
+    "BOOL": 35670,
+    "BOOL_VEC2": 35671,
+    "BOOL_VEC3": 35672,
+    "BOOL_VEC4": 35673,
+    "FLOAT_MAT2": 35674,
+    "FLOAT_MAT3": 35675,
+    "FLOAT_MAT4": 35676,
+    "SAMPLER_2D": 35678,
+    "SAMPLER_CUBE": 35680,
+    "VERTEX_ATTRIB_ARRAY_ENABLED": 34338,
+    "VERTEX_ATTRIB_ARRAY_SIZE": 34339,
+    "VERTEX_ATTRIB_ARRAY_STRIDE": 34340,
+    "VERTEX_ATTRIB_ARRAY_TYPE": 34341,
+    "VERTEX_ATTRIB_ARRAY_NORMALIZED": 34922,
+    "VERTEX_ATTRIB_ARRAY_POINTER": 34373,
+    "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING": 34975,
+    "IMPLEMENTATION_COLOR_READ_TYPE": 35738,
+    "IMPLEMENTATION_COLOR_READ_FORMAT": 35739,
+    "COMPILE_STATUS": 35713,
+    "LOW_FLOAT": 36336,
+    "MEDIUM_FLOAT": 36337,
+    "HIGH_FLOAT": 36338,
+    "LOW_INT": 36339,
+    "MEDIUM_INT": 36340,
+    "HIGH_INT": 36341,
+    "FRAMEBUFFER": 36160,
+    "RENDERBUFFER": 36161,
+    "RGBA4": 32854,
+    "RGB5_A1": 32855,
+    "RGB565": 36194,
+    "DEPTH_COMPONENT16": 33189,
+    "STENCIL_INDEX8": 36168,
+    "DEPTH_STENCIL": 34041,
+    "RENDERBUFFER_WIDTH": 36162,
+    "RENDERBUFFER_HEIGHT": 36163,
+    "RENDERBUFFER_INTERNAL_FORMAT": 36164,
+    "RENDERBUFFER_RED_SIZE": 36176,
+    "RENDERBUFFER_GREEN_SIZE": 36177,
+    "RENDERBUFFER_BLUE_SIZE": 36178,
+    "RENDERBUFFER_ALPHA_SIZE": 36179,
+    "RENDERBUFFER_DEPTH_SIZE": 36180,
+    "RENDERBUFFER_STENCIL_SIZE": 36181,
+    "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE": 36048,
+    "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME": 36049,
+    "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL": 36050,
+    "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE": 36051,
+    "COLOR_ATTACHMENT0": 36064,
+    "DEPTH_ATTACHMENT": 36096,
+    "STENCIL_ATTACHMENT": 36128,
+    "DEPTH_STENCIL_ATTACHMENT": 33306,
+    "NONE": 0,
+    "FRAMEBUFFER_COMPLETE": 36053,
+    "FRAMEBUFFER_INCOMPLETE_ATTACHMENT": 36054,
+    "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT": 36055,
+    "FRAMEBUFFER_INCOMPLETE_DIMENSIONS": 36057,
+    "FRAMEBUFFER_UNSUPPORTED": 36061,
+    "FRAMEBUFFER_BINDING": 36006,
+    "RENDERBUFFER_BINDING": 36007,
+    "MAX_RENDERBUFFER_SIZE": 34024,
+    "INVALID_FRAMEBUFFER_OPERATION": 1286,
+    "UNPACK_FLIP_Y_WEBGL": 37440,
+    "UNPACK_PREMULTIPLY_ALPHA_WEBGL": 37441,
+    "CONTEXT_LOST_WEBGL": 37442,
+    "UNPACK_COLORSPACE_CONVERSION_WEBGL": 37443,
+    "BROWSER_DEFAULT_WEBGL": 37444
+};
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLmethod.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLmethod.js
new file mode 100644
index 0000000..f2659be
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLmethod.js
@@ -0,0 +1,142 @@
+let i = 1;
+
+const GLmethod = {};
+
+GLmethod.activeTexture = i++;         //1
+GLmethod.attachShader = i++;
+GLmethod.bindAttribLocation = i++;
+GLmethod.bindBuffer = i++;
+GLmethod.bindFramebuffer = i++;
+GLmethod.bindRenderbuffer = i++;
+GLmethod.bindTexture = i++;
+GLmethod.blendColor = i++;
+GLmethod.blendEquation = i++;
+GLmethod.blendEquationSeparate = i++; //10
+GLmethod.blendFunc = i++;
+GLmethod.blendFuncSeparate = i++;
+GLmethod.bufferData = i++;
+GLmethod.bufferSubData = i++;
+GLmethod.checkFramebufferStatus = i++;
+GLmethod.clear = i++;
+GLmethod.clearColor = i++;
+GLmethod.clearDepth = i++;
+GLmethod.clearStencil = i++;
+GLmethod.colorMask = i++;              //20
+GLmethod.compileShader = i++;
+GLmethod.compressedTexImage2D = i++;
+GLmethod.compressedTexSubImage2D = i++;
+GLmethod.copyTexImage2D = i++;
+GLmethod.copyTexSubImage2D = i++;
+GLmethod.createBuffer = i++;
+GLmethod.createFramebuffer = i++;
+GLmethod.createProgram = i++;
+GLmethod.createRenderbuffer = i++;
+GLmethod.createShader = i++;           //30
+GLmethod.createTexture = i++;
+GLmethod.cullFace = i++;
+GLmethod.deleteBuffer = i++;
+GLmethod.deleteFramebuffer = i++;
+GLmethod.deleteProgram = i++;
+GLmethod.deleteRenderbuffer = i++;
+GLmethod.deleteShader = i++;
+GLmethod.deleteTexture = i++;
+GLmethod.depthFunc = i++;
+GLmethod.depthMask = i++;              //40
+GLmethod.depthRange = i++;
+GLmethod.detachShader = i++;
+GLmethod.disable = i++;
+GLmethod.disableVertexAttribArray = i++;
+GLmethod.drawArrays = i++;
+GLmethod.drawArraysInstancedANGLE = i++;
+GLmethod.drawElements = i++;
+GLmethod.drawElementsInstancedANGLE = i++;
+GLmethod.enable = i++;
+GLmethod.enableVertexAttribArray = i++;    //50
+GLmethod.flush = i++;
+GLmethod.framebufferRenderbuffer = i++;
+GLmethod.framebufferTexture2D = i++;
+GLmethod.frontFace = i++;
+GLmethod.generateMipmap = i++;
+GLmethod.getActiveAttrib = i++;
+GLmethod.getActiveUniform = i++;
+GLmethod.getAttachedShaders = i++;
+GLmethod.getAttribLocation = i++;
+GLmethod.getBufferParameter = i++;         //60
+GLmethod.getContextAttributes = i++;
+GLmethod.getError = i++;
+GLmethod.getExtension = i++;
+GLmethod.getFramebufferAttachmentParameter = i++;
+GLmethod.getParameter = i++;
+GLmethod.getProgramInfoLog = i++;
+GLmethod.getProgramParameter = i++;
+GLmethod.getRenderbufferParameter = i++;
+GLmethod.getShaderInfoLog = i++;
+GLmethod.getShaderParameter = i++;         //70
+GLmethod.getShaderPrecisionFormat = i++;
+GLmethod.getShaderSource = i++;
+GLmethod.getSupportedExtensions = i++;
+GLmethod.getTexParameter = i++;
+GLmethod.getUniform = i++;
+GLmethod.getUniformLocation = i++;
+GLmethod.getVertexAttrib = i++;
+GLmethod.getVertexAttribOffset = i++;
+GLmethod.isBuffer = i++;
+GLmethod.isContextLost = i++;              //80
+GLmethod.isEnabled = i++;
+GLmethod.isFramebuffer = i++;
+GLmethod.isProgram = i++;
+GLmethod.isRenderbuffer = i++;
+GLmethod.isShader = i++;
+GLmethod.isTexture = i++;
+GLmethod.lineWidth = i++;
+GLmethod.linkProgram = i++;
+GLmethod.pixelStorei = i++;
+GLmethod.polygonOffset = i++;              //90
+GLmethod.readPixels = i++;
+GLmethod.renderbufferStorage = i++;
+GLmethod.sampleCoverage = i++;
+GLmethod.scissor = i++;
+GLmethod.shaderSource = i++;
+GLmethod.stencilFunc = i++;
+GLmethod.stencilFuncSeparate = i++;
+GLmethod.stencilMask = i++;
+GLmethod.stencilMaskSeparate = i++;
+GLmethod.stencilOp = i++;                  //100
+GLmethod.stencilOpSeparate = i++;
+GLmethod.texImage2D = i++;
+GLmethod.texParameterf = i++;
+GLmethod.texParameteri = i++;
+GLmethod.texSubImage2D = i++;
+GLmethod.uniform1f = i++;
+GLmethod.uniform1fv = i++;
+GLmethod.uniform1i = i++;
+GLmethod.uniform1iv = i++;
+GLmethod.uniform2f = i++;                  //110
+GLmethod.uniform2fv = i++;
+GLmethod.uniform2i = i++;
+GLmethod.uniform2iv = i++;
+GLmethod.uniform3f = i++;
+GLmethod.uniform3fv = i++;
+GLmethod.uniform3i = i++;
+GLmethod.uniform3iv = i++;
+GLmethod.uniform4f = i++;
+GLmethod.uniform4fv = i++;
+GLmethod.uniform4i = i++;                  //120
+GLmethod.uniform4iv = i++;
+GLmethod.uniformMatrix2fv = i++;
+GLmethod.uniformMatrix3fv = i++;
+GLmethod.uniformMatrix4fv = i++;
+GLmethod.useProgram = i++;
+GLmethod.validateProgram = i++;
+GLmethod.vertexAttrib1f = i++; //new
+GLmethod.vertexAttrib2f = i++; //new
+GLmethod.vertexAttrib3f = i++; //new
+GLmethod.vertexAttrib4f = i++; //new       //130
+GLmethod.vertexAttrib1fv = i++; //new
+GLmethod.vertexAttrib2fv = i++; //new
+GLmethod.vertexAttrib3fv = i++; //new
+GLmethod.vertexAttrib4fv = i++; //new
+GLmethod.vertexAttribPointer = i++;
+GLmethod.viewport = i++;
+
+export default GLmethod;
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLtype.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLtype.js
new file mode 100644
index 0000000..695abcb
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLtype.js
@@ -0,0 +1,23 @@
+const GLtype = {};
+
+[
+    "GLbitfield",    
+    "GLboolean",
+    "GLbyte",
+    "GLclampf",
+    "GLenum",
+    "GLfloat",
+    "GLint",
+    "GLintptr",
+    "GLsizei",
+    "GLsizeiptr",
+    "GLshort",
+    "GLubyte",
+    "GLuint",
+    "GLushort"
+].sort().map((typeName, i) => GLtype[typeName] = 1 >> (i + 1));
+
+export default GLtype;
+
+
+
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Program.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Program.js
new file mode 100644
index 0000000..6f5691c
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Program.js
@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLProgram';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLProgram {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Renderbuffer.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Renderbuffer.js
new file mode 100644
index 0000000..d3182ae
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Renderbuffer.js
@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLRenderBuffer';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLRenderbuffer {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/RenderingContext.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/RenderingContext.js
new file mode 100644
index 0000000..5f9608f
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/RenderingContext.js
@@ -0,0 +1,1191 @@
+import GLenum from './GLenum';
+import ActiveInfo from './ActiveInfo';
+import Buffer from './Buffer';
+import Framebuffer from './Framebuffer';
+import Renderbuffer from './Renderbuffer';
+import Texture from './Texture';
+import Program from './Program';
+import Shader from './Shader';
+import ShaderPrecisionFormat from './ShaderPrecisionFormat';
+import UniformLocation from './UniformLocation';
+import GLmethod from './GLmethod';
+
+const processArray = (array, checkArrayType = false) => {
+
+    function joinArray(arr, sep) {
+        let res = '';
+        for (let i = 0; i < arr.length; i++) {
+            if (i !== 0) {
+                res += sep;
+            }
+            res += arr[i];
+        }
+        return res;
+    }
+
+    let type = 'Float32Array';
+    if (checkArrayType) {
+        if (array instanceof Uint8Array) {
+            type = 'Uint8Array'
+        } else if (array instanceof Uint16Array) {
+            type = 'Uint16Array';
+        } else if (array instanceof Uint32Array) {
+            type = 'Uint32Array';
+        } else if (array instanceof Float32Array) {
+            type = 'Float32Array';
+        } else {
+            throw new Error('Check array type failed. Array type is ' + typeof array);
+        }
+    }
+
+    const ArrayTypes = {
+        Uint8Array: 1,
+        Uint16Array: 2,
+        Uint32Array: 4,
+        Float32Array: 14
+    };
+    return ArrayTypes[type] + ',' + btoa(joinArray(array, ','))
+}
+
+export default class WebGLRenderingContext {
+
+    // static GBridge = null;
+
+    className = 'WebGLRenderingContext';
+
+    constructor(canvas, type, attrs) {
+        this._canvas = canvas;
+        this._type = type;
+        this._version = 'WebGL 1.0';
+        this._attrs = attrs;
+        this._map = new Map();
+
+        Object.keys(GLenum)
+            .forEach(name => Object.defineProperty(this, name, {
+                value: GLenum[name]
+            }));
+    }
+
+    get canvas() {
+        return this._canvas;
+    }
+
+    activeTexture = function (textureUnit) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.activeTexture + ',' + textureUnit,
+            true
+        );
+    }
+
+    attachShader = function (progarm, shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.attachShader + ',' + progarm.id + ',' + shader.id,
+            true
+        );
+    }
+
+    bindAttribLocation = function (program, index, name) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindAttribLocation + ',' + program.id + ',' + index + ',' + name,
+            true
+        )
+    }
+
+    bindBuffer = function (target, buffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindBuffer + ',' + target + ',' + (buffer ? buffer.id : 0),
+            true
+        );
+    }
+
+    bindFramebuffer = function (target, framebuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindFramebuffer + ',' + target + ',' + (framebuffer ? framebuffer.id : 0),
+            true
+        )
+    }
+
+    bindRenderbuffer = function (target, renderBuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindRenderbuffer + ',' + target + ',' + (renderBuffer ? renderBuffer.id : 0),
+            true
+        )
+    }
+
+    bindTexture = function (target, texture) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindTexture + ',' + target + ',' + (texture ? texture.id : 0),
+            true
+        )
+    }
+
+    blendColor = function (r, g, b, a) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendColor + ',' + target + ',' + r + ',' + g + ',' + b + ',' + a,
+            true
+        )
+    }
+
+    blendEquation = function (mode) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendEquation + ',' + mode,
+            true
+        )
+    }
+
+    blendEquationSeparate = function (modeRGB, modeAlpha) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendEquationSeparate + ',' + modeRGB + ',' + modeAlpha,
+            true
+        )
+    }
+
+
+    blendFunc = function (sfactor, dfactor) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendFunc + ',' + sfactor + ',' + dfactor,
+            true
+        );
+    }
+
+    blendFuncSeparate = function (srcRGB, dstRGB, srcAlpha, dstAlpha) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendFuncSeparate + ',' + srcRGB + ',' + dstRGB + ',' + srcAlpha + ',' + dstAlpha,
+            true
+        );
+    }
+
+    bufferData = function (target, data, usage) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bufferData + ',' + target + ',' + processArray(data, true) + ',' + usage,
+            true
+        )
+    }
+
+    bufferSubData = function (target, offset, data) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bufferSubData + ',' + target + ',' + offset + ',' + processArray(data, true),
+            true
+        )
+    }
+
+    checkFramebufferStatus = function (target) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.checkFramebufferStatus + ',' + target
+        );
+        return Number(result);
+    }
+
+    clear = function (mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clear + ',' + mask
+        );
+        this._canvas._needRender = true;
+    }
+
+    clearColor = function (r, g, b, a) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clearColor + ',' + r + ',' + g + ',' + b,
+            true
+        )
+    }
+
+    clearDepth = function (depth) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clearDepth + ',' + depth,
+            true
+        )
+    }
+
+    clearStencil = function (s) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clearStencil + ',' + s
+        );
+    }
+
+    colorMask = function (r, g, b, a) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.colorMask + ',' + r + ',' + g + ',' + b + ',' + a
+        )
+    }
+
+    compileShader = function (shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.compileShader + ',' + shader.id,
+            true
+        )
+    }
+
+    compressedTexImage2D = function (target, level, internalformat, width, height, border, pixels) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.compressedTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' +
+            width + ',' + height + ',' + border + ',' + processArray(pixels),
+            true
+        )
+    }
+
+    compressedTexSubImage2D = function (target, level, xoffset, yoffset, width, height, format, pixels) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.compressedTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' +
+            width + ',' + height + ',' + format + ',' + processArray(pixels),
+            true
+        )
+    }
+
+
+    copyTexImage2D = function (target, level, internalformat, x, y, width, height, border) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.copyTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' + x + ',' + y + ',' +
+            width + ',' + height + ',' + border,
+            true
+        );
+    }
+
+    copyTexSubImage2D = function (target, level, xoffset, yoffset, x, y, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.copyTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' + x + ',' + y + ',' +
+            width + ',' + height
+        );
+    }
+
+    createBuffer = function () {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createBuffer + ''
+        );
+        const buffer = new Buffer(result);
+        this._map.set(buffer.uuid(), buffer);
+        return buffer;
+    }
+
+    createFramebuffer = function () {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createFramebuffer + ''
+        );
+        const framebuffer = new Framebuffer(result);
+        this._map.set(framebuffer.uuid(), framebuffer);
+        return framebuffer;
+    }
+
+
+    createProgram = function () {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createProgram + ''
+        );
+        const program = new Program(id);
+        this._map.set(program.uuid(), program);
+        return program;
+    }
+
+    createRenderbuffer = function () {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createRenderbuffer + ''
+        )
+        const renderBuffer = new Renderbuffer(id);
+        this._map.set(renderBuffer.uuid(), renderBuffer);
+        return renderBuffer;
+    }
+
+    createShader = function (type) {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createShader + ',' + type
+        )
+        const shader = new Shader(id, type);
+        this._map.set(shader.uuid(), shader);
+        return shader;
+    }
+
+    createTexture = function () {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createTexture + ''
+        );
+        const texture = new Texture(id);
+        this._map.set(texture.uuid(), texture);
+        return texture;
+    }
+
+    cullFace = function (mode) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.cullFace + ',' + mode,
+            true
+        )
+    }
+
+
+    deleteBuffer = function (buffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteBuffer + ',' + buffer.id,
+            true
+        )
+    }
+
+    deleteFramebuffer = function (framebuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteFramebuffer + ',' + framebuffer.id,
+            true
+        )
+    }
+
+    deleteProgram = function (program) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteProgram + ',' + program.id,
+            true
+        )
+    }
+
+    deleteRenderbuffer = function (renderbuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteRenderbuffer + ',' + renderbuffer.id,
+            true
+        )
+    }
+
+    deleteShader = function (shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteShader + ',' + shader.id,
+            true
+        )
+    }
+
+    deleteTexture = function (texture) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteTexture + ',' + texture.id,
+            true
+        )
+    }
+
+    depthFunc = function (func) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.depthFunc + ',' + func
+        )
+    }
+
+    depthMask = function (flag) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.depthMask + ',' + Number(flag),
+            true
+        )
+    }
+
+    depthRange = function (zNear, zFar) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.depthRange + ',' + zNear + ',' + zFar,
+            true
+        )
+    }
+
+    detachShader = function (program, shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.detachShader + ',' + program.id + ',' + shader.id,
+            true
+        )
+    }
+
+    disable = function (cap) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.disable + ',' + cap,
+            true
+        )
+    }
+
+    disableVertexAttribArray = function (index) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.disableVertexAttribArray + ',' + index,
+            true
+        );
+    }
+
+    drawArrays = function (mode, first, count) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.drawArrays + ',' + mode + ',' + first + ',' + count
+        )
+        this._canvas._needRender = true;
+    }
+
+    drawElements = function (mode, count, type, offset) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.drawElements + ',' + mode + ',' + count + ',' + type + ',' + offset + ';'
+        );
+        this._canvas._needRender = true;
+    }
+
+    enable = function (cap) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.enable + ',' + cap,
+            true
+        );
+    }
+
+    enableVertexAttribArray = function (index) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.enableVertexAttribArray + ',' + index,
+            true
+        )
+    }
+
+
+    flush = function () {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.flush + ''
+        )
+    }
+
+    framebufferRenderbuffer = function (target, attachment, textarget, texture, level) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.framebufferRenderbuffer + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level,
+            true
+        )
+    }
+
+    framebufferTexture2D = function (target, attachment, textarget, texture, level) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.framebufferTexture2D + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level,
+            true
+        )
+    }
+
+    frontFace = function (mode) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.frontFace + ',' + mode,
+            true
+        )
+    }
+
+    generateMipmap = function (target) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.generateMipmap + ',' + target,
+            true
+        )
+    }
+
+    getActiveAttrib = function (progarm, index) {
+        const resultString = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getActiveAttrib + ',' + progarm.id + ',' + index
+        )
+        const [type, size, name] = resultString.split(',');
+        return new ActiveInfo({
+            type: Number(type),
+            size: Number(size),
+            name
+        });
+    }
+
+    getActiveUniform = function (progarm, index) {
+        const resultString = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getActiveUniform + ',' + progarm.id + ',' + index
+        );
+        const [type, size, name] = resultString.split(',');
+        return new ActiveInfo({
+            type: Number(type),
+            size: Number(size),
+            name
+        })
+    }
+
+    getAttachedShaders = function (progarm) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getAttachedShaders + ',' + progarm.id
+        );
+        const [type, ...ids] = result;
+        return ids.map(id => this._map.get(Shader.uuid(id)));
+    }
+
+    getAttribLocation = function (progarm, name) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getAttribLocation + ',' + progarm.id + ',' + name
+        )
+    }
+
+    getBufferParameter = function (target, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getBufferParameter + ',' + target + ',' + pname
+        );
+        const [type, res] = getBufferParameter;
+        return res;
+    }
+
+    getError = function () {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getError + ''
+        )
+        return result;
+    }
+
+    getExtension = function (name) {
+        return null;
+    }
+
+    getFramebufferAttachmentParameter = function (target, attachment, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getFramebufferAttachmentParameter + ',' + target + ',' + attachment + ',' + pname
+        )
+        switch (pname) {
+            case GLenum.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+                return this._map.get(Renderbuffer.uuid(result)) || this._map.get(Texture.uuid(result)) || null;
+            default:
+                return result;
+        }
+    }
+
+    getParameter = function (pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getParameter + ',' + pname
+        )
+        switch (pname) {
+            case GLenum.VERSION:
+                return this._version;
+            case GLenum.ARRAY_BUFFER_BINDING: // buffer
+            case GLenum.ELEMENT_ARRAY_BUFFER_BINDING: // buffer
+                return this._map.get(Buffer.uuid(result)) || null;
+            case GLenum.CURRENT_PROGRAM: // program
+                return this._map.get(Program.uuid(result)) || null;
+            case GLenum.FRAMEBUFFER_BINDING: // framebuffer
+                return this._map.get(Framebuffer.uuid(result)) || null;
+            case GLenum.RENDERBUFFER_BINDING: // renderbuffer
+                return this._map.get(Renderbuffer.uuid(result)) || null;
+            case GLenum.TEXTURE_BINDING_2D: // texture
+            case GLenum.TEXTURE_BINDING_CUBE_MAP: // texture
+                return this._map.get(Texture.uuid(result)) || null;
+            case GLenum.ALIASED_LINE_WIDTH_RANGE: // Float32Array
+            case GLenum.ALIASED_POINT_SIZE_RANGE: // Float32Array
+            case GLenum.BLEND_COLOR: // Float32Array
+            case GLenum.COLOR_CLEAR_VALUE: // Float32Array
+            case GLenum.DEPTH_RANGE: // Float32Array
+            case GLenum.MAX_VIEWPORT_DIMS: // Int32Array
+            case GLenum.SCISSOR_BOX: // Int32Array
+            case GLenum.VIEWPORT: // Int32Array            
+            case GLenum.COMPRESSED_TEXTURE_FORMATS: // Uint32Array
+            default:
+                const [type, ...res] = result.split(',');
+                if (res.length === 1) {
+                    return Number(res[0]);
+                } else {
+                    return res.map(Number);
+                }
+        }
+    }
+
+    getProgramInfoLog = function (progarm) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getProgramInfoLog + ',' + progarm.id
+        )
+    }
+
+    getProgramParameter = function (program, pname) {
+        const res = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getProgramParameter + ',' + program.id + ',' + pname
+        );
+
+        const [type, result] = res.split(',').map(i => parseInt(i));
+
+        if (type === 1) {
+            return Boolean(result);
+        } else if (type === 2) {
+            return result;
+        } else {
+            throw new Error('Unrecongized program paramater ' + res + ', type: ' + typeof res);
+        }
+    }
+
+
+    getRenderbufferParameter = function (target, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getRenderbufferParameter + ',' + target + ',' + pname
+        )
+        return result;
+    }
+
+
+    getShaderInfoLog = function (shader) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderInfoLog + ',' + shader.id
+        );
+    }
+
+    getShaderParameter = function (shader, pname) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderParameter + ',' + shader.id + ',' + pname
+        )
+    }
+
+    getShaderPrecisionFormat = function (shaderType, precisionType) {
+        const [rangeMin, rangeMax, precision] = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderPrecisionFormat + ',' + shaderType + ',' + precisionType
+        );
+        const shaderPrecisionFormat = new ShaderPrecisionFormat({
+            rangeMin: Number(rangeMin),
+            rangeMax: Number(rangeMax),
+            precision: Number(precision)
+        });
+        return shaderPrecisionFormat;
+    }
+
+    getShaderSource = function (shader) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderSource + ',' + shader.id
+        );
+        return result;
+    }
+
+    getSupportedExtensions = function () {
+        return Object.keys({});
+    }
+
+    getTexParameter = function (target, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getTexParameter + ',' + target + ',' + pname
+        )
+        return result;
+    }
+
+    getUniformLocation = function (program, name) {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getUniformLocation + ',' + program.id + ',' + name
+        );
+        if (id === -1) {
+            return null;
+        } else {
+            return new UniformLocation(Number(id));
+        }
+    }
+
+    getVertexAttrib = function (index, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getVertexAttrib + ',' + index + ',' + pname
+        );
+        switch (pname) {
+            case GLenum.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+                return this._map.get(Buffer.uuid(result)) || null;
+            case GLenum.CURRENT_VERTEX_ATTRIB: // Float32Array
+            default:
+                return result;
+        }
+    }
+
+    getVertexAttribOffset = function (index, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getVertexAttribOffset + ',' + index + ',' + pname
+        )
+        return Number(result);
+    }
+
+    isBuffer = function (buffer) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isBuffer + ',' + buffer.id
+        )
+        return Boolean(result);
+    }
+
+    isContextLost = function () {
+        return false;
+    }
+
+    isEnabled = function (cap) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isEnabled + ',' + cap
+        )
+        return Boolean(result);
+    }
+
+    isFramebuffer = function (framebuffer) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isFramebuffer + ',' + framebuffer.id
+        )
+        return Boolean(result);
+    }
+
+    isProgram = function (program) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isProgram + ',' + program.id
+        )
+        return Boolean(result);
+    }
+
+    isRenderbuffer = function (renderBuffer) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isRenderbuffer + ',' + renderbuffer.id
+        )
+        return Boolean(result);
+    }
+
+    isShader = function (shader) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isShader + ',' + shader.id
+        )
+        return Boolean(result);
+    }
+
+    isTexture = function (texture) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isTexture + ',' + texture.id
+        );
+        return Boolean(result);
+    }
+
+    lineWidth = function (width) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.lineWidth + ',' + width,
+            true
+        )
+    }
+
+    linkProgram = function (program) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.linkProgram + ',' + program.id,
+            true
+        );
+    }
+
+
+    pixelStorei = function (pname, param) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.pixelStorei + ',' + pname + ',' + Number(param)
+        )
+    }
+
+    polygonOffset = function (factor, units) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.polygonOffset + ',' + factor + ',' + units
+        )
+    }
+
+    readPixels = function (x, y, width, height, format, type, pixels) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.readPixels + ',' + x + ',' + y + ',' + width + ',' + height + ',' + format + ',' + type
+        )
+        return result;
+    }
+
+    renderbufferStorage = function (target, internalFormat, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.renderbufferStorage + ',' + target + ',' + internalFormat + ',' + width + ',' + height,
+            true
+        )
+    }
+
+    sampleCoverage = function (value, invert) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.sampleCoverage + ',' + value + ',' + Number(invert),
+            true
+        )
+    }
+
+    scissor = function (x, y, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.scissor + ',' + x + ',' + y + ',' + width + ',' + height,
+            true
+        )
+    }
+
+    shaderSource = function (shader, source) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.shaderSource + ',' + shader.id + ',' + source
+        )
+    }
+
+    stencilFunc = function (func, ref, mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilFunc + ',' + func + ',' + ref + ',' + mask,
+            true
+        )
+    }
+
+    stencilFuncSeparate = function (face, func, ref, mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilFuncSeparate + ',' + face + ',' + func + ',' + ref + ',' + mask,
+            true
+        )
+    }
+
+    stencilMask = function (mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilMask + ',' + mask,
+            true
+        )
+    }
+
+    stencilMaskSeparate = function (face, mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilMaskSeparate + ',' + face + ',' + mask,
+            true
+        )
+    }
+
+    stencilOp = function (fail, zfail, zpass) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilOp + ',' + fail + ',' + zfail + ',' + zpass
+        )
+    }
+
+    stencilOpSeparate = function (face, fail, zfail, zpass) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilOp + ',' + face + ',' + fail + ',' + zfail + ',' + zpass,
+            true
+        )
+    }
+
+    texImage2D = function (...args) {
+        WebGLRenderingContext.GBridge.texImage2D(this._canvas.id, ...args);
+    }
+
+
+    texParameterf = function (target, pname, param) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.texParameterf + ',' + target + ',' + pname + ',' + param,
+            true
+        )
+    }
+
+    texParameteri = function (target, pname, param) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.texParameteri + ',' + target + ',' + pname + ',' + param
+        )
+    }
+
+    texSubImage2D = function (...args) {
+        WebGLRenderingContext.GBridge.texSubImage2D(this._canvas.id, ...args);
+    }
+
+    uniform1f = function (location, v0) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1f + ',' + location.id + ',' + v0
+        )
+    }
+
+    uniform1fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform1i = function (location, v0) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1i + ',' + location.id + ',' + v0,
+            // true
+        )
+    }
+
+    uniform1iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1iv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform2f = function (location, v0, v1) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2f + ',' + location.id + ',' + v0 + ',' + v1,
+            true
+        )
+    }
+
+    uniform2fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform2i = function (location, v0, v1) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2i + ',' + location.id + ',' + v0 + ',' + v1,
+            true
+        )
+    }
+
+    uniform2iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2iv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform3f = function (location, v0, v1, v2) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2,
+            true
+        )
+    }
+
+    uniform3fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform3i = function (location, v0, v1, v2) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2,
+            true
+        )
+    }
+
+    uniform3iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3iv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform4f = function (location, v0, v1, v2, v3) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
+            true
+        )
+    }
+
+    uniform4fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform4i = function (location, v0, v1, v2, v3) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
+            true
+        )
+    }
+
+    uniform4iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4iv + ',' + location.id + ',' + processArray(value, true),
+            true
+        )
+    }
+
+    uniformMatrix2fv = function (location, transpose, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniformMatrix2fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniformMatrix3fv = function (location, transpose, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniformMatrix3fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniformMatrix4fv = function (location, transpose, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniformMatrix4fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
+            true
+        );
+    }
+
+    useProgram = function (progarm) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.useProgram + ',' + progarm.id + '',
+            true
+        )
+    }
+
+
+    validateProgram = function (program) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.validateProgram + ',' + program.id,
+            true
+        )
+    }
+
+    vertexAttrib1f = function (index, v0) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib1f + ',' + index + ',' + v0,
+            true
+        )
+    }
+
+    vertexAttrib2f = function (index, v0, v1) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib2f + ',' + index + ',' + v0 + ',' + v1,
+            true
+        )
+    }
+
+    vertexAttrib3f = function (index, v0, v1, v2) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib3f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2,
+            true
+        )
+    }
+
+    vertexAttrib4f = function (index, v0, v1, v2, v3) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib4f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
+            true
+        )
+    }
+
+    vertexAttrib1fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib1fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttrib2fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib2fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttrib3fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib3fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttrib4fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib4fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttribPointer = function (index, size, type, normalized, stride, offset) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttribPointer + ',' + index + ',' + size + ',' + type + ',' + Number(normalized) + ',' + stride + ',' + offset,
+            true
+        )
+    }
+
+    viewport = function (x, y, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.viewport + ',' + x + ',' + y + ',' + width + ',' + height,
+            true
+        )
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Shader.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Shader.js
new file mode 100644
index 0000000..a763886
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Shader.js
@@ -0,0 +1,22 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLShader';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLShader {
+    className = name;
+
+    constructor(id, type) {
+        this.id = id;
+        this.type = type;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js
new file mode 100644
index 0000000..208d6c1
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js
@@ -0,0 +1,11 @@
+export default class WebGLShaderPrecisionFormat {
+    className = 'WebGLShaderPrecisionFormat';
+
+    constructor({
+        rangeMin, rangeMax, precision
+    }) {
+        this.rangeMin = rangeMin;
+        this.rangeMax = rangeMax;
+        this.precision = precision;
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Texture.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Texture.js
new file mode 100644
index 0000000..de4d806
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Texture.js
@@ -0,0 +1,22 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLTexture';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLTexture {
+    className = name;
+
+    constructor(id, type) {
+        this.id = id;
+        this.type = type;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/UniformLocation.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/UniformLocation.js
new file mode 100644
index 0000000..f5e99dc
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/UniformLocation.js
@@ -0,0 +1,22 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLUniformLocation';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLUniformLocation {
+    className = name;
+
+    constructor(id, type) {
+        this.id = id;
+        this.type = type;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/classUtils.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/classUtils.js
new file mode 100644
index 0000000..88716be
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/classUtils.js
@@ -0,0 +1,3 @@
+export function getTransferedObjectUUID(name, id) {
+    return `${name.toLowerCase()}-${id}`;
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/canvas.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/canvas.js
new file mode 100644
index 0000000..a8d9bb9
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/canvas.js
@@ -0,0 +1,74 @@
+import GContext2D from '../context-2d/RenderingContext';
+import GContextWebGL from '../context-webgl/RenderingContext';
+
+export default class GCanvas {
+
+    // static GBridge = null;
+
+    id = null;
+
+    _needRender = true;
+
+    constructor(id, { disableAutoSwap }) {
+        this.id = id;
+
+        this._disableAutoSwap = disableAutoSwap;
+        if (disableAutoSwap) {
+            this._swapBuffers = () => {
+                GCanvas.GBridge.render(this.id);
+            }
+        }
+    }
+
+    getContext(type) {
+
+        let context = null;
+
+        if (type.match(/webgl/i)) {
+            context = new GContextWebGL(this);
+
+            context.componentId = this.id;
+
+            if (!this._disableAutoSwap) {
+                const render = () => {
+                    if (this._needRender) {
+                        GCanvas.GBridge.render(this.id);
+                        this._needRender = false;
+                    }
+                }
+                setInterval(render, 16);
+            }
+
+            GCanvas.GBridge.callSetContextType(this.id, 1); // 0 for 2d; 1 for webgl
+        } else if (type.match(/2d/i)) {
+            context = new GContext2D(this);
+
+            context.componentId = this.id;
+
+//             const render = ( callback ) => {
+// 
+//                 const commands = context._drawCommands;
+//                 context._drawCommands = '';
+// 
+//                 GCanvas.GBridge.render2d(this.id, commands, callback);
+//                 this._needRender = false;
+//             }
+// 			//draw鏂规硶瑙﹀彂
+// 			context._flush = render;
+//             //setInterval(render, 16);
+
+            GCanvas.GBridge.callSetContextType(this.id, 0);
+        } else {
+            throw new Error('not supported context ' + type);
+        }
+
+        return context;
+
+    }
+
+    reset() {
+        GCanvas.GBridge.callReset(this.id);
+    }
+
+
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/image.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/image.js
new file mode 100644
index 0000000..9499a51
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/image.js
@@ -0,0 +1,96 @@
+let incId = 1;
+
+const noop = function () { };
+
+class GImage {
+
+    static GBridge = null;
+
+    constructor() {
+        this._id = incId++;
+        this._width = 0;
+        this._height = 0;
+        this._src = undefined;
+        this._onload = noop;
+        this._onerror = noop;
+        this.complete = false;
+    }
+
+    get width() {
+        return this._width;
+    }
+    set width(v) {
+        this._width = v;
+    }
+
+    get height() {
+        return this._height;
+    }
+
+    set height(v) {
+        this._height = v;
+    }
+
+    get src() {
+        return this._src;
+    }
+
+    set src(v) {
+
+        if (v.startsWith('//')) {
+            v = 'http:' + v;
+        }
+
+        this._src = v;
+
+        GImage.GBridge.perloadImage([this._src, this._id], (data) => {
+            if (typeof data === 'string') {
+                data = JSON.parse(data);
+            }
+            if (data.error) {
+                var evt = { type: 'error', target: this };
+                this.onerror(evt);
+            } else {
+                this.complete = true;
+                this.width = typeof data.width === 'number' ? data.width : 0;
+                this.height = typeof data.height === 'number' ? data.height : 0;
+                var evt = { type: 'load', target: this };
+                this.onload(evt);
+            }
+        });
+    }
+
+    addEventListener(name, listener) {
+        if (name === 'load') {
+            this.onload = listener;
+        } else if (name === 'error') {
+            this.onerror = listener;
+        }
+    }
+
+    removeEventListener(name, listener) {
+        if (name === 'load') {
+            this.onload = noop;
+        } else if (name === 'error') {
+            this.onerror = noop;
+        }
+    }
+
+    get onload() {
+        return this._onload;
+    }
+
+    set onload(v) {
+        this._onload = v;
+    }
+
+    get onerror() {
+        return this._onerror;
+    }
+
+    set onerror(v) {
+        this._onerror = v;
+    }
+}
+
+export default GImage;
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/tool.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/tool.js
new file mode 100644
index 0000000..d3fb398
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/tool.js
@@ -0,0 +1,24 @@
+
+export function ArrayBufferToBase64 (buffer) {
+    var binary = '';
+    var bytes = new Uint8ClampedArray(buffer);
+    for (var len = bytes.byteLength, i = 0; i < len; i++) {
+        binary += String.fromCharCode(bytes[i]);
+    }
+    return btoa(binary);
+}
+	
+export function Base64ToUint8ClampedArray(base64String) {
+	const padding = '='.repeat((4 - base64String.length % 4) % 4);
+	const base64 = (base64String + padding)
+		.replace(/\-/g, '+')
+		.replace(/_/g, '/');
+
+	const rawData = atob(base64);
+	const outputArray = new Uint8ClampedArray(rawData.length);
+
+	for (let i = 0; i < rawData.length; ++i) {
+		outputArray[i] = rawData.charCodeAt(i);
+	}
+	return outputArray;
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/index.js b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/index.js
new file mode 100644
index 0000000..a34ad58
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/index.js
@@ -0,0 +1,39 @@
+import GCanvas from './env/canvas';
+import GImage from './env/image';
+
+import GWebGLRenderingContext from './context-webgl/RenderingContext';
+import GContext2D from './context-2d/RenderingContext';
+
+import GBridgeWeex from './bridge/bridge-weex';
+
+export let Image = GImage;
+
+export let WeexBridge = GBridgeWeex;
+
+export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommands } = {}) {
+
+    const GBridge = GImage.GBridge = GCanvas.GBridge = GWebGLRenderingContext.GBridge = GContext2D.GBridge = bridge;
+
+    GBridge.callEnable(el.ref, [
+        0,      // renderMode: 0--RENDERMODE_WHEN_DIRTY, 1--RENDERMODE_CONTINUOUSLY
+        -1,     // hybridLayerType:  0--LAYER_TYPE_NONE 1--LAYER_TYPE_SOFTWARE 2--LAYER_TYPE_HARDWARE
+        false,  // supportScroll
+        false,  // newCanvasMode
+        1,      // compatible
+        'white',// clearColor
+        false   // sameLevel: newCanvasMode = true && true => GCanvasView and Webview is same level
+    ]);
+
+    if (debug === true) {
+        GBridge.callEnableDebug();
+    }
+    if (disableComboCommands) {
+        GBridge.callEnableDisableCombo();
+    }
+
+    var canvas = new GCanvas(el.ref, { disableAutoSwap });
+    canvas.width = el.style.width;
+    canvas.height = el.style.height;
+
+    return canvas;
+};
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/props.js b/uni_modules/uv-qrcode/components/uv-qrcode/props.js
new file mode 100644
index 0000000..55df5bb
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/props.js
@@ -0,0 +1,85 @@
+export default {
+	props: {
+		//浜岀淮鐮佸唴瀹�
+		value: {
+			type: [String, Number]
+		},
+		//閫夐」
+		options: {
+			type: Object,
+			default: () => {
+				return {};
+			}
+		},
+		//浜岀淮鐮佸ぇ灏�
+		size: {
+			type: [String, Number],
+			default: 200
+		},
+		//瀵煎嚭鐨勬枃浠剁被鍨�
+		fileType: {
+			type: String,
+			default: 'png'
+		},
+		//鏄惁鍒濆鍖栫粍浠跺悗灏卞紑濮嬬敓鎴�
+		start: {
+			type: Boolean,
+			default: true
+		},
+		//鏄惁鏁版嵁鍙戠敓鏀瑰彉鑷姩閲嶇粯
+		auto: {
+			type: Boolean,
+			default: true
+		},
+		//闅愯棌缁勪欢
+		hide: {
+			type: Boolean,
+			default: false
+		},
+		/**
+		 * canvas 绫诲瀷锛屽井淇″皬绋嬪簭榛樿浣跨敤2d锛岄潪2d寰俊瀹樻柟宸叉斁寮冪淮鎶わ紝闂姣旇緝澶�
+		 * 娉ㄦ剰锛氬井淇″皬绋嬪簭type2d鎵嬫満涓婃甯革紝PC涓婂井淇″唴鎵撳紑灏忕▼搴弔oDataURL鎶ラ敊锛岀湅鍚庢湡寰俊瀹樻柟鍥㈤槦浼氫笉浼氬仛鍏煎锛屼笉鍏煎鐨勮瘽鍙兘鍦ㄨ嚜琛屽垽鏂湪PC浣跨敤闈�2d锛屾垨鑰呯洿鎺ユ彁绀虹敤鎴疯鍦ㄦ墜鏈轰笂鎿嶄綔锛屽井淇″洟闃熺殑娴锋姤涓績灏忕▼搴忓氨鏄繖涔堝仛鐨�
+		 */
+		type: {
+			type: String,
+			default: () => {
+				// #ifdef MP-WEIXIN
+				return '2d';
+				// #endif
+				// #ifndef MP-WEIXIN
+				return 'normal';
+				// #endif
+			}
+		},
+		//闃熷垪缁樺埗锛屼富瑕侀拡瀵筃Vue绔�
+		queue: {
+			type: Boolean,
+			default: false
+		},
+		//鏄惁闃熷垪鍔犺浇鍥剧墖锛屽彲鍑忓皯canvas鍙戣捣鐨勭綉缁滆祫婧愯姹傦紝鑺傜渷鏈嶅姟鍣ㄨ祫婧�
+		isQueueLoadImage: {
+			type: Boolean,
+			default: false
+		},
+		//loading鎬�
+		loading: {
+			type: Boolean,
+			default: undefined
+		},
+		//H5淇濆瓨鍗宠嚜鍔ㄤ笅杞斤紙鍦ㄦ敮鎸佺殑鐜涓嬶級锛岄粯璁alse涓轰粎寮瑰眰鎻愮ず鐢ㄦ埛闇�瑕侀暱鎸夊浘鐗囦繚瀛橈紝涓嶄細鑷姩涓嬭浇
+		h5SaveIsDownload: {
+			type: Boolean,
+			default: false
+		},
+		//H5涓嬭浇鍚嶇О
+		h5DownloadName: {
+			type: String,
+			default: 'uvQRCode'
+		},
+		// H5淇濆瓨浜岀淮鐮佹椂鍊欐槸鍚︽樉绀烘彁绀�
+		h5SaveTip: {
+			type: Boolean,
+			default: true
+		}
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/qrcode.js b/uni_modules/uv-qrcode/components/uv-qrcode/qrcode.js
new file mode 100644
index 0000000..2290ab3
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/qrcode.js
@@ -0,0 +1,34 @@
+//---------------------------------------------------------------------
+// uQRCode浜岀淮鐮佺敓鎴愭彃浠� v4.0.6
+// 
+// uQRCode鏄竴娆惧熀浜嶫avascript鐜寮�鍙戠殑浜岀淮鐮佺敓鎴愭彃浠讹紝閫傜敤鎵�鏈塉avascript杩愯鐜鐨勫墠绔簲鐢ㄥ拰Node.js銆�
+// 
+// Copyright (c) Sansnn uQRCode All rights reserved.
+// 
+// Licensed under the Apache License, Version 2.0.
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// github鍦板潃锛�
+//   https://github.com/Sansnn/uQRCode
+// 
+// npm鍦板潃锛�
+//   https://www.npmjs.com/package/uqrcodejs
+// 
+// uni-app鎻掍欢甯傚満鍦板潃锛�
+//   https://ext.dcloud.net.cn/plugin?id=1287
+// 
+// 澶嶅埗浣跨敤璇蜂繚鐣欐湰娈垫敞閲婏紝鎰熻阿鏀寔寮�婧愶紒
+// 
+//---------------------------------------------------------------------
+
+//---------------------------------------------------------------------
+// 褰撳墠鏂囦欢鏍煎紡涓� es锛屽皢 bundle 淇濈暀涓� ES 妯″潡鏂囦欢锛岄�傜敤浜庡叾浠栨墦鍖呭伐鍏蜂互鍙婃敮鎸� <script type=module> 鏍囩鐨勬祻瑙堝櫒锛堝埆鍚�: esm锛宮odule锛�
+// 濡傞渶鍦ㄥ叾浠栫幆澧冧娇鐢紝璇疯幏鍙栫幆澧冨搴旂殑鏍煎紡鏂囦欢
+// 鏍煎紡璇存槑锛�
+// amd - 寮傛妯″潡瀹氫箟锛岄�傜敤浜� RequireJS 绛夋ā鍧楀姞杞藉櫒
+// cjs - CommonJS锛岄�傜敤浜� Node 鐜鍜屽叾浠栨墦鍖呭伐鍏凤紙鍒悕锛歝ommonjs锛�
+// es - 灏� bundle 淇濈暀涓� ES 妯″潡鏂囦欢锛岄�傜敤浜庡叾浠栨墦鍖呭伐鍏蜂互鍙婃敮鎸� <script type=module> 鏍囩鐨勬祻瑙堝櫒锛堝埆鍚�: esm锛宮odule锛�
+// umd - 閫氱敤妯″潡瀹氫箟锛岀敓鎴愮殑鍖呭悓鏃舵敮鎸� amd銆乧js 鍜� iife 涓夌鏍煎紡
+//---------------------------------------------------------------------
+
+function o(o){this.mode=r.MODE_8BIT_BYTE,this.data=o;}function e(o,e){this.typeNumber=o,this.errorCorrectLevel=e,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=new Array;}o.prototype={getLength:function(o){return this.data.length},write:function(o){for(var e=0;e<this.data.length;e++)o.put(this.data.charCodeAt(e),8);}},e.prototype={addData:function(e){var r=new o(e);this.dataList.push(r),this.dataCache=null;},isDark:function(o,e){if(o<0||this.moduleCount<=o||e<0||this.moduleCount<=e)throw new Error(o+","+e);return this.modules[o][e]},getModuleCount:function(){return this.moduleCount},make:function(){if(this.typeNumber<1){var o=1;for(o=1;o<40;o++){for(var e=v.getRSBlocks(o,this.errorCorrectLevel),r=new p,t=0,i=0;i<e.length;i++)t+=e[i].dataCount;for(i=0;i<this.dataList.length;i++){var n=this.dataList[i];r.put(n.mode,4),r.put(n.getLength(),h.getLengthInBits(n.mode,o)),n.write(r);}if(r.getLengthInBits()<=8*t)break}this.typeNumber=o;}this.makeImpl(!1,this.getBestMaskPattern());},makeImpl:function(o,r){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var t=0;t<this.moduleCount;t++){this.modules[t]=new Array(this.moduleCount);for(var i=0;i<this.moduleCount;i++)this.modules[t][i]=null;}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(o,r),this.typeNumber>=7&&this.setupTypeNumber(o),null==this.dataCache&&(this.dataCache=e.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,r);},setupPositionProbePattern:function(o,e){for(var r=-1;r<=7;r++)if(!(o+r<=-1||this.moduleCount<=o+r))for(var t=-1;t<=7;t++)e+t<=-1||this.moduleCount<=e+t||(this.modules[o+r][e+t]=0<=r&&r<=6&&(0==t||6==t)||0<=t&&t<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=t&&t<=4);},getBestMaskPattern:function(){for(var o=0,e=0,r=0;r<8;r++){this.makeImpl(!0,r);var t=h.getLostPoint(this);(0==r||o>t)&&(o=t,e=r);}return e},createMovieClip:function(o,e,r){var t=o.createEmptyMovieClip(e,r);this.make();for(var i=0;i<this.modules.length;i++)for(var n=1*i,a=0;a<this.modules[i].length;a++){var d=1*a;this.modules[i][a]&&(t.beginFill(0,100),t.moveTo(d,n),t.lineTo(d+1,n),t.lineTo(d+1,n+1),t.lineTo(d,n+1),t.endFill());}return t},setupTimingPattern:function(){for(var o=8;o<this.moduleCount-8;o++)null==this.modules[o][6]&&(this.modules[o][6]=o%2==0);for(var e=8;e<this.moduleCount-8;e++)null==this.modules[6][e]&&(this.modules[6][e]=e%2==0);},setupPositionAdjustPattern:function(){for(var o=h.getPatternPosition(this.typeNumber),e=0;e<o.length;e++)for(var r=0;r<o.length;r++){var t=o[e],i=o[r];if(null==this.modules[t][i])for(var n=-2;n<=2;n++)for(var a=-2;a<=2;a++)this.modules[t+n][i+a]=-2==n||2==n||-2==a||2==a||0==n&&0==a;}},setupTypeNumber:function(o){for(var e=h.getBCHTypeNumber(this.typeNumber),r=0;r<18;r++){var t=!o&&1==(e>>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=t;}for(r=0;r<18;r++){t=!o&&1==(e>>r&1);this.modules[r%3+this.moduleCount-8-3][Math.floor(r/3)]=t;}},setupTypeInfo:function(o,e){for(var r=this.errorCorrectLevel<<3|e,t=h.getBCHTypeInfo(r),i=0;i<15;i++){var n=!o&&1==(t>>i&1);i<6?this.modules[i][8]=n:i<8?this.modules[i+1][8]=n:this.modules[this.moduleCount-15+i][8]=n;}for(i=0;i<15;i++){n=!o&&1==(t>>i&1);i<8?this.modules[8][this.moduleCount-i-1]=n:i<9?this.modules[8][15-i-1+1]=n:this.modules[8][15-i-1]=n;}this.modules[this.moduleCount-8][8]=!o;},mapData:function(o,e){for(var r=-1,t=this.moduleCount-1,i=7,n=0,a=this.moduleCount-1;a>0;a-=2)for(6==a&&a--;;){for(var d=0;d<2;d++)if(null==this.modules[t][a-d]){var u=!1;n<o.length&&(u=1==(o[n]>>>i&1)),h.getMask(e,t,a-d)&&(u=!u),this.modules[t][a-d]=u,-1==--i&&(n++,i=7);}if((t+=r)<0||this.moduleCount<=t){t-=r,r=-r;break}}}},e.PAD0=236,e.PAD1=17,e.createData=function(o,r,t){for(var i=v.getRSBlocks(o,r),n=new p,a=0;a<t.length;a++){var d=t[a];n.put(d.mode,4),n.put(d.getLength(),h.getLengthInBits(d.mode,o)),d.write(n);}var u=0;for(a=0;a<i.length;a++)u+=i[a].dataCount;if(n.getLengthInBits()>8*u)throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*u+")");for(n.getLengthInBits()+4<=8*u&&n.put(0,4);n.getLengthInBits()%8!=0;)n.putBit(!1);for(;!(n.getLengthInBits()>=8*u||(n.put(e.PAD0,8),n.getLengthInBits()>=8*u));)n.put(e.PAD1,8);return e.createBytes(n,i)},e.createBytes=function(o,e){for(var r=0,t=0,i=0,n=new Array(e.length),a=new Array(e.length),d=0;d<e.length;d++){var u=e[d].dataCount,s=e[d].totalCount-u;t=Math.max(t,u),i=Math.max(i,s),n[d]=new Array(u);for(var g=0;g<n[d].length;g++)n[d][g]=255&o.buffer[g+r];r+=u;var l=h.getErrorCorrectPolynomial(s),c=new f(n[d],l.getLength()-1).mod(l);a[d]=new Array(l.getLength()-1);for(g=0;g<a[d].length;g++){var m=g+c.getLength()-a[d].length;a[d][g]=m>=0?c.get(m):0;}}var v=0;for(g=0;g<e.length;g++)v+=e[g].totalCount;var p=new Array(v),C=0;for(g=0;g<t;g++)for(d=0;d<e.length;d++)g<n[d].length&&(p[C++]=n[d][g]);for(g=0;g<i;g++)for(d=0;d<e.length;d++)g<a[d].length&&(p[C++]=a[d][g]);return p};for(var r={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},t={L:1,M:0,Q:3,H:2},i=0,n=1,a=2,d=3,u=4,s=5,g=6,l=7,h={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(o){for(var e=o<<10;h.getBCHDigit(e)-h.getBCHDigit(h.G15)>=0;)e^=h.G15<<h.getBCHDigit(e)-h.getBCHDigit(h.G15);return (o<<10|e)^h.G15_MASK},getBCHTypeNumber:function(o){for(var e=o<<12;h.getBCHDigit(e)-h.getBCHDigit(h.G18)>=0;)e^=h.G18<<h.getBCHDigit(e)-h.getBCHDigit(h.G18);return o<<12|e},getBCHDigit:function(o){for(var e=0;0!=o;)e++,o>>>=1;return e},getPatternPosition:function(o){return h.PATTERN_POSITION_TABLE[o-1]},getMask:function(o,e,r){switch(o){case i:return (e+r)%2==0;case n:return e%2==0;case a:return r%3==0;case d:return (e+r)%3==0;case u:return (Math.floor(e/2)+Math.floor(r/3))%2==0;case s:return e*r%2+e*r%3==0;case g:return (e*r%2+e*r%3)%2==0;case l:return (e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+o)}},getErrorCorrectPolynomial:function(o){for(var e=new f([1],0),r=0;r<o;r++)e=e.multiply(new f([1,c.gexp(r)],0));return e},getLengthInBits:function(o,e){if(1<=e&&e<10)switch(o){case r.MODE_NUMBER:return 10;case r.MODE_ALPHA_NUM:return 9;case r.MODE_8BIT_BYTE:case r.MODE_KANJI:return 8;default:throw new Error("mode:"+o)}else if(e<27)switch(o){case r.MODE_NUMBER:return 12;case r.MODE_ALPHA_NUM:return 11;case r.MODE_8BIT_BYTE:return 16;case r.MODE_KANJI:return 10;default:throw new Error("mode:"+o)}else {if(!(e<41))throw new Error("type:"+e);switch(o){case r.MODE_NUMBER:return 14;case r.MODE_ALPHA_NUM:return 13;case r.MODE_8BIT_BYTE:return 16;case r.MODE_KANJI:return 12;default:throw new Error("mode:"+o)}}},getLostPoint:function(o){for(var e=o.getModuleCount(),r=0,t=0;t<e;t++)for(var i=0;i<e;i++){for(var n=0,a=o.isDark(t,i),d=-1;d<=1;d++)if(!(t+d<0||e<=t+d))for(var u=-1;u<=1;u++)i+u<0||e<=i+u||0==d&&0==u||a==o.isDark(t+d,i+u)&&n++;n>5&&(r+=3+n-5);}for(t=0;t<e-1;t++)for(i=0;i<e-1;i++){var s=0;o.isDark(t,i)&&s++,o.isDark(t+1,i)&&s++,o.isDark(t,i+1)&&s++,o.isDark(t+1,i+1)&&s++,0!=s&&4!=s||(r+=3);}for(t=0;t<e;t++)for(i=0;i<e-6;i++)o.isDark(t,i)&&!o.isDark(t,i+1)&&o.isDark(t,i+2)&&o.isDark(t,i+3)&&o.isDark(t,i+4)&&!o.isDark(t,i+5)&&o.isDark(t,i+6)&&(r+=40);for(i=0;i<e;i++)for(t=0;t<e-6;t++)o.isDark(t,i)&&!o.isDark(t+1,i)&&o.isDark(t+2,i)&&o.isDark(t+3,i)&&o.isDark(t+4,i)&&!o.isDark(t+5,i)&&o.isDark(t+6,i)&&(r+=40);var g=0;for(i=0;i<e;i++)for(t=0;t<e;t++)o.isDark(t,i)&&g++;return r+=10*(Math.abs(100*g/e/e-50)/5)}},c={glog:function(o){if(o<1)throw new Error("glog("+o+")");return c.LOG_TABLE[o]},gexp:function(o){for(;o<0;)o+=255;for(;o>=256;)o-=255;return c.EXP_TABLE[o]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},m=0;m<8;m++)c.EXP_TABLE[m]=1<<m;for(m=8;m<256;m++)c.EXP_TABLE[m]=c.EXP_TABLE[m-4]^c.EXP_TABLE[m-5]^c.EXP_TABLE[m-6]^c.EXP_TABLE[m-8];for(m=0;m<255;m++)c.LOG_TABLE[c.EXP_TABLE[m]]=m;function f(o,e){if(null==o.length)throw new Error(o.length+"/"+e);for(var r=0;r<o.length&&0==o[r];)r++;this.num=new Array(o.length-r+e);for(var t=0;t<o.length-r;t++)this.num[t]=o[t+r];}function v(o,e){this.totalCount=o,this.dataCount=e;}function p(){this.buffer=new Array,this.length=0;}function C(o){return o.setFillStyle=o.setFillStyle||function(e){o.fillStyle=e;},o.setFontSize=o.setFontSize||function(e){o.font=`${e}px`;},o.setTextAlign=o.setTextAlign||function(e){o.textAlign=e;},o.setTextBaseline=o.setTextBaseline||function(e){o.textBaseline=e;},o.setGlobalAlpha=o.setGlobalAlpha||function(e){o.globalAlpha=e;},o.setStrokeStyle=o.setStrokeStyle||function(e){o.strokeStyle=e;},o.setShadow=o.setShadow||function(e,r,t,i){o.shadowOffsetX=e,o.shadowOffsetY=r,o.shadowBlur=t,o.shadowColor=i;},o.draw=o.draw||function(o,e){e&&e();},o.clearRect=o.clearRect||function(e,r,t,i){o.draw(!1);},o}function b(o,e){var r=this.data="",t=this.size=200;this.useDynamicSize=!1,this.dynamicSize=t;var i=this.typeNumber=-1;this.errorCorrectLevel=b.errorCorrectLevel.H;var n=this.margin=0;this.areaColor="#FFFFFF",this.backgroundColor="rgba(255,255,255,0)",this.backgroundImageSrc=void 0;var a=this.backgroundImageWidth=void 0,d=this.backgroundImageHeight=void 0,u=this.backgroundImageX=void 0,s=this.backgroundImageY=void 0;this.backgroundImageAlpha=1,this.backgroundImageBorderRadius=0;var g=this.backgroundPadding=0;this.foregroundColor="#000000",this.foregroundImageSrc=void 0;var l=this.foregroundImageWidth=void 0,h=this.foregroundImageHeight=void 0,c=this.foregroundImageX=void 0,m=this.foregroundImageY=void 0,f=this.foregroundImagePadding=0;this.foregroundImageBackgroundColor="#FFFFFF";var v=this.foregroundImageBorderRadius=0,p=this.foregroundImageShadowOffsetX=0,k=this.foregroundImageShadowOffsetY=0,y=this.foregroundImageShadowBlur=0;this.foregroundImageShadowColor="#808080";var w=this.foregroundPadding=0,I=this.positionProbeBackgroundColor=void 0,B=this.positionProbeForegroundColor=void 0,S=this.separatorColor=void 0,P=this.positionAdjustBackgroundColor=void 0,L=this.positionAdjustForegroundColor=void 0,D=this.timingBackgroundColor=void 0,A=this.timingForegroundColor=void 0,E=this.typeNumberBackgroundColor=void 0,T=this.typeNumberForegroundColor=void 0,N=this.darkBlockColor=void 0;this.base=void 0,this.modules=[],this.moduleCount=0,this.drawModules=[];var M=this.canvasContext=void 0;this.loadImage,this.drawReserve=!1,this.isMaked=!1,Object.defineProperties(this,{data:{get(){if(""===r||void 0===r)throw console.error("[uQRCode]: data must be set!"),new b.Error("data must be set!");return r},set(o){r=String(o);}},size:{get:()=>t,set(o){t=Number(o);}},typeNumber:{get:()=>i,set(o){i=Number(o);}},margin:{get:()=>n,set(o){n=Number(o);}},backgroundImageWidth:{get(){return void 0===a?this.dynamicSize:this.useDynamicSize?this.dynamicSize/this.size*a:a},set(o){a=Number(o);}},backgroundImageHeight:{get(){return void 0===d?this.dynamicSize:this.useDynamicSize?this.dynamicSize/this.size*d:d},set(o){d=Number(o);}},backgroundImageX:{get(){return void 0===u?0:this.useDynamicSize?this.dynamicSize/this.size*u:u},set(o){u=Number(o);}},backgroundImageY:{get(){return void 0===s?0:this.useDynamicSize?this.dynamicSize/this.size*s:s},set(o){s=Number(o);}},backgroundPadding:{get:()=>g,set(o){g=o>1?1:o<0?0:o;}},foregroundImageWidth:{get(){return void 0===l?(this.dynamicSize-2*this.margin)/4:this.useDynamicSize?this.dynamicSize/this.size*l:l},set(o){l=Number(o);}},foregroundImageHeight:{get(){return void 0===h?(this.dynamicSize-2*this.margin)/4:this.useDynamicSize?this.dynamicSize/this.size*h:h},set(o){h=Number(o);}},foregroundImageX:{get(){return void 0===c?this.dynamicSize/2-this.foregroundImageWidth/2:this.useDynamicSize?this.dynamicSize/this.size*c:c},set(o){c=Number(o);}},foregroundImageY:{get(){return void 0===m?this.dynamicSize/2-this.foregroundImageHeight/2:this.useDynamicSize?this.dynamicSize/this.size*m:m},set(o){m=Number(o);}},foregroundImagePadding:{get(){return this.useDynamicSize?this.dynamicSize/this.size*f:f},set(o){f=Number(o);}},foregroundImageBorderRadius:{get(){return this.useDynamicSize?this.dynamicSize/this.size*v:v},set(o){v=Number(o);}},foregroundImageShadowOffsetX:{get(){return this.useDynamicSize?this.dynamicSize/this.size*p:p},set(o){p=Number(o);}},foregroundImageShadowOffsetY:{get(){return this.useDynamicSize?this.dynamicSize/this.size*k:k},set(o){k=Number(o);}},foregroundImageShadowBlur:{get(){return this.useDynamicSize?this.dynamicSize/this.size*y:y},set(o){y=Number(o);}},foregroundPadding:{get:()=>w,set(o){w=o>1?1:o<0?0:o;}},positionProbeBackgroundColor:{get(){return I||this.backgroundColor},set(o){I=o;}},positionProbeForegroundColor:{get(){return B||this.foregroundColor},set(o){B=o;}},separatorColor:{get(){return S||this.backgroundColor},set(o){S=o;}},positionAdjustBackgroundColor:{get(){return P||this.backgroundColor},set(o){P=o;}},positionAdjustForegroundColor:{get(){return L||this.foregroundColor},set(o){L=o;}},timingBackgroundColor:{get(){return D||this.backgroundColor},set(o){D=o;}},timingForegroundColor:{get(){return A||this.foregroundColor},set(o){A=o;}},typeNumberBackgroundColor:{get(){return E||this.backgroundColor},set(o){E=o;}},typeNumberForegroundColor:{get(){return T||this.foregroundColor},set(o){T=o;}},darkBlockColor:{get(){return N||this.foregroundColor},set(o){N=o;}},canvasContext:{get(){if(void 0===M)throw console.error("[uQRCode]: use drawCanvas, you need to set the canvasContext!"),new b.Error("use drawCanvas, you need to set the canvasContext!");return M},set(o){M=C(o);}}}),b.plugins.forEach((o=>o(b,this,!1))),o&&this.setOptions(o),e&&(this.canvasContext=C(e));}f.prototype={get:function(o){return this.num[o]},getLength:function(){return this.num.length},multiply:function(o){for(var e=new Array(this.getLength()+o.getLength()-1),r=0;r<this.getLength();r++)for(var t=0;t<o.getLength();t++)e[r+t]^=c.gexp(c.glog(this.get(r))+c.glog(o.get(t)));return new f(e,0)},mod:function(o){if(this.getLength()-o.getLength()<0)return this;for(var e=c.glog(this.get(0))-c.glog(o.get(0)),r=new Array(this.getLength()),t=0;t<this.getLength();t++)r[t]=this.get(t);for(t=0;t<o.getLength();t++)r[t]^=c.gexp(c.glog(o.get(t))+e);return new f(r,0).mod(o)}},v.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],v.getRSBlocks=function(o,e){var r=v.getRsBlockTable(o,e);if(null==r)throw new Error("bad rs block @ typeNumber:"+o+"/errorCorrectLevel:"+e);for(var t=r.length/3,i=new Array,n=0;n<t;n++)for(var a=r[3*n+0],d=r[3*n+1],u=r[3*n+2],s=0;s<a;s++)i.push(new v(d,u));return i},v.getRsBlockTable=function(o,e){switch(e){case t.L:return v.RS_BLOCK_TABLE[4*(o-1)+0];case t.M:return v.RS_BLOCK_TABLE[4*(o-1)+1];case t.Q:return v.RS_BLOCK_TABLE[4*(o-1)+2];case t.H:return v.RS_BLOCK_TABLE[4*(o-1)+3];default:return}},p.prototype={get:function(o){var e=Math.floor(o/8);return 1==(this.buffer[e]>>>7-o%8&1)},put:function(o,e){for(var r=0;r<e;r++)this.putBit(1==(o>>>e-r-1&1));},getLengthInBits:function(){return this.length},putBit:function(o){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),o&&(this.buffer[e]|=128>>>this.length%8),this.length++;}},e.errorCorrectLevel=t,b.errorCorrectLevel=e.errorCorrectLevel,b.Error=function(o){this.errMsg="[uQRCode]: "+o;},b.plugins=[],b.use=function(o){"function"==typeof o&&b.plugins.push(o);},b.prototype.loadImage=function(o){return Promise.resolve(o)},b.prototype.setOptions=function(o){var e,r,t,i,n,a,d,u,s,g,l,h,c,m,f,v,p,C,b,k,y,w,I,B,S,P,L,D,A,E,T,N,M,z,R,_,O,F,x,H,X,Y,j,W,G,K,Q,U,$,J,q,V,Z,oo,eo,ro;o&&(Object.keys(o).forEach((e=>{this[e]=o[e];})),function(o={},e={},r=!1){let t;t=r?o:{...o};for(let o in e){var i=e[o];null!=i&&(i.constructor==Object?t[o]=this.deepReplace(t[o],i):i.constructor!=String||i?t[o]=i:t[o]=t[o]);}}(this,{data:o.data||o.text,size:o.size,useDynamicSize:o.useDynamicSize,typeNumber:o.typeNumber,errorCorrectLevel:o.errorCorrectLevel,margin:o.margin,areaColor:o.areaColor,backgroundColor:o.backgroundColor||(null===(e=o.background)||void 0===e?void 0:e.color),backgroundImageSrc:o.backgroundImageSrc||(null===(r=o.background)||void 0===r||null===(t=r.image)||void 0===t?void 0:t.src),backgroundImageWidth:o.backgroundImageWidth||(null===(i=o.background)||void 0===i||null===(n=i.image)||void 0===n?void 0:n.width),backgroundImageHeight:o.backgroundImageHeight||(null===(a=o.background)||void 0===a||null===(d=a.image)||void 0===d?void 0:d.height),backgroundImageX:o.backgroundImageX||(null===(u=o.background)||void 0===u||null===(s=u.image)||void 0===s?void 0:s.x),backgroundImageY:o.backgroundImageY||(null===(g=o.background)||void 0===g||null===(l=g.image)||void 0===l?void 0:l.y),backgroundImageAlpha:o.backgroundImageAlpha||(null===(h=o.background)||void 0===h||null===(c=h.image)||void 0===c?void 0:c.alpha),backgroundImageBorderRadius:o.backgroundImageBorderRadius||(null===(m=o.background)||void 0===m||null===(f=m.image)||void 0===f?void 0:f.borderRadius),backgroundPadding:o.backgroundPadding,foregroundColor:o.foregroundColor||(null===(v=o.foreground)||void 0===v?void 0:v.color),foregroundImageSrc:o.foregroundImageSrc||(null===(p=o.foreground)||void 0===p||null===(C=p.image)||void 0===C?void 0:C.src),foregroundImageWidth:o.foregroundImageWidth||(null===(b=o.foreground)||void 0===b||null===(k=b.image)||void 0===k?void 0:k.width),foregroundImageHeight:o.foregroundImageHeight||(null===(y=o.foreground)||void 0===y||null===(w=y.image)||void 0===w?void 0:w.height),foregroundImageX:o.foregroundImageX||(null===(I=o.foreground)||void 0===I||null===(B=I.image)||void 0===B?void 0:B.x),foregroundImageY:o.foregroundImageY||(null===(S=o.foreground)||void 0===S||null===(P=S.image)||void 0===P?void 0:P.y),foregroundImagePadding:o.foregroundImagePadding||(null===(L=o.foreground)||void 0===L||null===(D=L.image)||void 0===D?void 0:D.padding),foregroundImageBackgroundColor:o.foregroundImageBackgroundColor||(null===(A=o.foreground)||void 0===A||null===(E=A.image)||void 0===E?void 0:E.backgroundColor),foregroundImageBorderRadius:o.foregroundImageBorderRadius||(null===(T=o.foreground)||void 0===T||null===(N=T.image)||void 0===N?void 0:N.borderRadius),foregroundImageShadowOffsetX:o.foregroundImageShadowOffsetX||(null===(M=o.foreground)||void 0===M||null===(z=M.image)||void 0===z?void 0:z.shadowOffsetX),foregroundImageShadowOffsetY:o.foregroundImageShadowOffsetY||(null===(R=o.foreground)||void 0===R||null===(_=R.image)||void 0===_?void 0:_.shadowOffsetY),foregroundImageShadowBlur:o.foregroundImageShadowBlur||(null===(O=o.foreground)||void 0===O||null===(F=O.image)||void 0===F?void 0:F.shadowBlur),foregroundImageShadowColor:o.foregroundImageShadowColor||(null===(x=o.foreground)||void 0===x||null===(H=x.image)||void 0===H?void 0:H.shadowColor),foregroundPadding:o.foregroundPadding,positionProbeBackgroundColor:o.positionProbeBackgroundColor||(null===(X=o.positionProbe)||void 0===X?void 0:X.backgroundColor)||(null===(Y=o.positionDetection)||void 0===Y?void 0:Y.backgroundColor),positionProbeForegroundColor:o.positionProbeForegroundColor||(null===(j=o.positionProbe)||void 0===j?void 0:j.foregroundColor)||(null===(W=o.positionDetection)||void 0===W?void 0:W.foregroundColor),separatorColor:o.separatorColor||(null===(G=o.separator)||void 0===G?void 0:G.color),positionAdjustBackgroundColor:o.positionAdjustBackgroundColor||(null===(K=o.positionAdjust)||void 0===K?void 0:K.backgroundColor)||(null===(Q=o.alignment)||void 0===Q?void 0:Q.backgroundColor),positionAdjustForegroundColor:o.positionAdjustForegroundColor||(null===(U=o.positionAdjust)||void 0===U?void 0:U.foregroundColor)||(null===($=o.alignment)||void 0===$?void 0:$.foregroundColor),timingBackgroundColor:o.timingBackgroundColor||(null===(J=o.timing)||void 0===J?void 0:J.backgroundColor),timingForegroundColor:o.timingForegroundColor||(null===(q=o.timing)||void 0===q?void 0:q.foregroundColor),typeNumberBackgroundColor:o.typeNumberBackgroundColor||(null===(V=o.typeNumber)||void 0===V?void 0:V.backgroundColor)||(null===(Z=o.versionInformation)||void 0===Z?void 0:Z.backgroundColor),typeNumberForegroundColor:o.typeNumberForegroundColor||(null===(oo=o.typeNumber)||void 0===oo?void 0:oo.foregroundColor)||(null===(eo=o.versionInformation)||void 0===eo?void 0:eo.foregroundColor),darkBlockColor:o.darkBlockColor||(null===(ro=o.darkBlock)||void 0===ro?void 0:ro.color)},!0));},b.prototype.make=function(){let{foregroundColor:o,backgroundColor:r,typeNumber:t,errorCorrectLevel:i,data:n,size:a,margin:d,useDynamicSize:u}=this;if(o===r)throw console.error("[uQRCode]: foregroundColor and backgroundColor cannot be the same!"),new b.Error("foregroundColor and backgroundColor cannot be the same!");var s=new e(t,i);s.addData(function(o){o=o.toString();for(var e,r="",t=0;t<o.length;t++)(e=o.charCodeAt(t))>=1&&e<=127?r+=o.charAt(t):e>2047?(r+=String.fromCharCode(224|e>>12&15),r+=String.fromCharCode(128|e>>6&63),r+=String.fromCharCode(128|e>>0&63)):(r+=String.fromCharCode(192|e>>6&31),r+=String.fromCharCode(128|e>>0&63));return r}(n)),s.make(),this.base=s,this.typeNumber=s.typeNumber,this.modules=s.modules,this.moduleCount=s.moduleCount,this.dynamicSize=u?Math.ceil((a-2*d)/s.moduleCount)*s.moduleCount+2*d:a,function(o){let{dynamicSize:e,margin:r,backgroundColor:t,backgroundPadding:i,foregroundColor:n,foregroundPadding:a,modules:d,moduleCount:u}=o,s=(e-2*r)/u,g=s,l=0;i>0&&(l=g*i/2,g-=2*l);let h=s,c=0;a>0&&(c=h*a/2,h-=2*c);for(var m=0;m<u;m++)for(var f=0;f<u;f++){var v=f*s+r,p=m*s+r;if(d[m][f]){var C=c,b=v+c,k=p+c,y=h,w=h;d[m][f]={type:["foreground"],color:n,isBlack:!0,isDrawn:!1,destX:v,destY:p,destWidth:s,destHeight:s,x:b,y:k,width:y,height:w,paddingTop:C,paddingRight:C,paddingBottom:C,paddingLeft:C};}else C=l,b=v+l,k=p+l,y=g,w=g,d[m][f]={type:["background"],color:t,isBlack:!1,isDrawn:!1,destX:v,destY:p,destWidth:s,destHeight:s,x:b,y:k,width:y,height:w,paddingTop:C,paddingRight:C,paddingBottom:C,paddingLeft:C};}}(this),function(o){let{modules:e,moduleCount:r,positionProbeBackgroundColor:t,positionProbeForegroundColor:i}=o,n=r-7;[[0,0,1],[1,0,1],[2,0,1],[3,0,1],[4,0,1],[5,0,1],[6,0,1],[0,1,1],[1,1,0],[2,1,0],[3,1,0],[4,1,0],[5,1,0],[6,1,1],[0,2,1],[1,2,0],[2,2,1],[3,2,1],[4,2,1],[5,2,0],[6,2,1],[0,3,1],[1,3,0],[2,3,1],[3,3,1],[4,3,1],[5,3,0],[6,3,1],[0,4,1],[1,4,0],[2,4,1],[3,4,1],[4,4,1],[5,4,0],[6,4,1],[0,5,1],[1,5,0],[2,5,0],[3,5,0],[4,5,0],[5,5,0],[6,5,1],[0,6,1],[1,6,1],[2,6,1],[3,6,1],[4,6,1],[5,6,1],[6,6,1]].forEach((o=>{var r=e[o[0]][o[1]],a=e[o[0]+n][o[1]],d=e[o[0]][o[1]+n];d.type.push("positionProbe"),a.type.push("positionProbe"),r.type.push("positionProbe"),r.color=1==o[2]?i:t,a.color=1==o[2]?i:t,d.color=1==o[2]?i:t;}));}(this),function(o){let{modules:e,moduleCount:r,separatorColor:t}=o;[[7,0],[7,1],[7,2],[7,3],[7,4],[7,5],[7,6],[7,7],[0,7],[1,7],[2,7],[3,7],[4,7],[5,7],[6,7]].forEach((o=>{var i=e[o[0]][o[1]],n=e[r-o[0]-1][o[1]],a=e[o[0]][r-o[1]-1];a.type.push("separator"),n.type.push("separator"),i.type.push("separator"),i.color=t,n.color=t,a.color=t;}));}(this),function(o){let{typeNumber:e,modules:r,moduleCount:t,foregroundColor:i,backgroundColor:n,positionAdjustForegroundColor:a,positionAdjustBackgroundColor:d,timingForegroundColor:u,timingBackgroundColor:s}=o;const g=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]][e-1];if(g){const o=[[-2,-2,1],[-1,-2,1],[0,-2,1],[1,-2,1],[2,-2,1],[-2,-1,1],[-1,-1,0],[0,-1,0],[1,-1,0],[2,-1,1],[-2,0,1],[-1,0,0],[0,0,1],[1,0,0],[2,0,1],[-2,1,1],[-1,1,0],[0,1,0],[1,1,0],[2,1,1],[-2,2,1],[-1,2,1],[0,2,1],[1,2,1],[2,2,1]],e=g.length;for(let l=0;l<e;l++)for(let h=0;h<e;h++){let{x:e,y:c}={x:g[l],y:g[h]};e<9&&c<9||e>t-9-1&&c<9||c>t-9-1&&e<9||o.forEach((o=>{var t=r[e+o[0]][c+o[1]];t.type.push("positionAdjust"),t.type.includes("timing")?1==o[2]?t.color=a==i?u:a:t.color=a==i&&d==n?s:d:t.color=1==o[2]?a:d;}));}}}(this),function(o){let{modules:e,moduleCount:r,timingForegroundColor:t,timingBackgroundColor:i}=o,n=r-16;for(let o=0;o<n;o++){var a=e[6][8+o],d=e[8+o][6];a.type.push("timing"),d.type.push("timing"),a.color=1&o^1?t:i,d.color=1&o^1?t:i;}}(this),function(o){let{modules:e,moduleCount:r,darkBlockColor:t}=o;var i=e[r-7-1][8];i.type.push("darkBlock"),i.color=t;}(this),function(o){let{typeNumber:e,modules:r,moduleCount:t,typeNumberBackgroundColor:i,typeNumberForegroundColor:n}=o;if(e<7)return r;const a=[0,0,0,0,0,0,0,"000111110010010100","001000010110111100","001001101010011001","001010010011010011","001011101111110110","001100011101100010","001101100001000111","001110011000001101","001111100100101000","010000101101111000","010001010001011101","010010101000010111","010011010100110010","010100100110100110","010101011010000011","010110100011001001","010111011111101100","011000111011000100","011001000111100001","011010111110101011","011011000010001110","011100110000011010","011101001100111111","011110110101110101","011111001001010000","100000100111010101","100001011011110000","100010100010111010","100011011110011111","100100101100001011","100101010000101110","100110101001100100","100111010101000001","101000110001101001"];let d=a[e]+a[e],u=[t-11,t-10,t-9];[[5,u[2]],[5,u[1]],[5,u[0]],[4,u[2]],[4,u[1]],[4,u[0]],[3,u[2]],[3,u[1]],[3,u[0]],[2,u[2]],[2,u[1]],[2,u[0]],[1,u[2]],[1,u[1]],[1,u[0]],[0,u[2]],[0,u[1]],[0,u[0]],[u[2],5],[u[1],5],[u[0],5],[u[2],4],[u[1],4],[u[0],4],[u[2],3],[u[1],3],[u[0],3],[u[2],2],[u[1],2],[u[0],2],[u[2],1],[u[1],1],[u[0],1],[u[2],0],[u[1],0],[u[0],0]].forEach(((o,e)=>{var t=r[o[0]][o[1]];t.type.push("typeNumber"),t.color="1"==d[e]?n:i;}));}(this),this.isMaked=!0,this.drawModules=[];},b.prototype.getDrawModules=function(){if(this.drawModules&&this.drawModules.length>0)return this.drawModules;let o=this.drawModules=[],{modules:e,moduleCount:r,dynamicSize:t,areaColor:i,backgroundImageSrc:n,backgroundImageX:a,backgroundImageY:d,backgroundImageWidth:u,backgroundImageHeight:s,backgroundImageAlpha:g,backgroundImageBorderRadius:l,foregroundImageSrc:h,foregroundImageX:c,foregroundImageY:m,foregroundImageWidth:f,foregroundImageHeight:v,foregroundImagePadding:p,foregroundImageBackgroundColor:C,foregroundImageBorderRadius:b,foregroundImageShadowOffsetX:k,foregroundImageShadowOffsetY:y,foregroundImageShadowBlur:w,foregroundImageShadowColor:I}=this;i&&o.push({name:"area",type:"area",color:i,x:0,y:0,width:t,height:t}),n&&o.push({name:"backgroundImage",type:"image",imageSrc:n,mappingName:"backgroundImageSrc",x:a,y:d,width:u,height:s,alpha:g,borderRadius:l});for(var B=0;B<r;B++)for(var S=0;S<r;S++){var P=e[B][S];P.isDrawn||(P.type.includes("foreground")?o.push({name:"foreground",type:"tile",color:P.color,destX:P.destX,destY:P.destY,destWidth:P.destWidth,destHeight:P.destHeight,x:P.x,y:P.y,width:P.width,height:P.height,paddingTop:P.paddingTop,paddingRight:P.paddingRight,paddingBottom:P.paddingBottom,paddingLeft:P.paddingLeft,rowIndex:B,colIndex:S}):o.push({name:"background",type:"tile",color:P.color,destX:P.destX,destY:P.destY,destWidth:P.destWidth,destHeight:P.destHeight,x:P.x,y:P.y,width:P.width,height:P.height,paddingTop:P.paddingTop,paddingRight:P.paddingRight,paddingBottom:P.paddingBottom,paddingLeft:P.paddingLeft,rowIndex:B,colIndex:S}),P.isDrawn=!0);}return h&&o.push({name:"foregroundImage",type:"image",imageSrc:h,mappingName:"foregroundImageSrc",x:c,y:m,width:f,height:v,padding:p,backgroundColor:C,borderRadius:b,shadowOffsetX:k,shadowOffsetY:y,shadowBlur:w,shadowColor:I}),o},b.prototype.isBlack=function(o,e){var r=this.moduleCount;return !(0>o||0>e||o>=r||e>=r)&&this.modules[o][e].isBlack},b.prototype.drawCanvas=function(){let{isMaked:o,canvasContext:e,useDynamicSize:r,dynamicSize:t,foregroundColor:i,foregroundPadding:n,backgroundColor:a,backgroundPadding:d,drawReserve:u,margin:s}=this;if(!o)return console.error("[uQRCode]: please execute the make method first!"),Promise.reject(new b.Error("please execute the make method first!"));let g=this.getDrawModules(),l=async(o,r)=>{try{e.clearRect(0,0,t,t),e.draw(!1);for(var i=0;i<g.length;i++){var n=g[i];switch(e.save(),n.type){case"area":e.setFillStyle(n.color),e.fillRect(n.x,n.y,n.width,n.height);break;case"tile":var a=n.x,d=n.y,s=n.width,l=n.height;e.setFillStyle(n.color),e.fillRect(a,d,s,l);break;case"image":if("backgroundImage"===n.name){a=Math.round(n.x),d=Math.round(n.y),s=Math.round(n.width),l=Math.round(n.height);s<2*(c=Math.round(n.borderRadius))&&(c=s/2),l<2*c&&(c=l/2),e.setGlobalAlpha(n.alpha),c>0&&(e.beginPath(),e.moveTo(a+c,d),e.arcTo(a+s,d,a+s,d+l,c),e.arcTo(a+s,d+l,a,d+l,c),e.arcTo(a,d+l,a,d,c),e.arcTo(a,d,a+s,d,c),e.closePath(),e.setStrokeStyle("rgba(0,0,0,0)"),e.stroke(),e.clip());try{var h=await this.loadImage(n.imageSrc);e.drawImage(h,a,d,s,l);}catch(o){throw console.error(`[uQRCode]: ${n.mappingName} invalid!`),new b.Error(`${n.mappingName} invalid!`)}}else if("foregroundImage"===n.name){a=Math.round(n.x),d=Math.round(n.y),s=Math.round(n.width),l=Math.round(n.height);var c,m=Math.round(n.padding);s<2*(c=Math.round(n.borderRadius))&&(c=s/2),l<2*c&&(c=l/2);var f=a-m,v=d-m,p=s+2*m,C=l+2*m,k=Math.round(p/s*c);p<2*k&&(k=p/2),C<2*k&&(k=C/2),e.save(),e.setShadow(n.shadowOffsetX,n.shadowOffsetY,n.shadowBlur,n.shadowColor),k>0?(e.beginPath(),e.moveTo(f+k,v),e.arcTo(f+p,v,f+p,v+C,k),e.arcTo(f+p,v+C,f,v+C,k),e.arcTo(f,v+C,f,v,k),e.arcTo(f,v,f+p,v,k),e.closePath(),e.setFillStyle(n.backgroundColor),e.fill()):(e.setFillStyle(n.backgroundColor),e.fillRect(f,v,p,C)),e.restore(),e.save(),k>0?(e.beginPath(),e.moveTo(f+k,v),e.arcTo(f+p,v,f+p,v+C,k),e.arcTo(f+p,v+C,f,v+C,k),e.arcTo(f,v+C,f,v,k),e.arcTo(f,v,f+p,v,k),e.closePath(),e.setFillStyle(m>0?n.backgroundColor:"rgba(0,0,0,0)"),e.fill()):(e.setFillStyle(m>0?n.backgroundColor:"rgba(0,0,0,0)"),e.fillRect(f,v,p,C)),e.restore(),c>0&&(e.beginPath(),e.moveTo(a+c,d),e.arcTo(a+s,d,a+s,d+l,c),e.arcTo(a+s,d+l,a,d+l,c),e.arcTo(a,d+l,a,d,c),e.arcTo(a,d,a+s,d,c),e.closePath(),e.setStrokeStyle("rgba(0,0,0,0)"),e.stroke(),e.clip());try{h=await this.loadImage(n.imageSrc);e.drawImage(h,a,d,s,l);}catch(o){throw console.error(`[uQRCode]: ${n.mappingName} invalid!`),new b.Error(`${n.mappingName} invalid!`)}}}u&&e.draw(!0),e.restore();}e.draw(!0),setTimeout(o,150);}catch(o){if(!(o instanceof b.Error))throw o;r(o);}};return new Promise(((o,e)=>{l(o,e);}))},b.prototype.draw=function(){return this.drawCanvas()},b.prototype.register=function(o){o&&o(b,this,!0);};export{b as default};
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/queue.js b/uni_modules/uv-qrcode/components/uv-qrcode/queue.js
new file mode 100644
index 0000000..be6b1d2
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/queue.js
@@ -0,0 +1,41 @@
+function Queue() {
+  let waitingQueue = this.waitingQueue = [];
+  let isRunning = this.isRunning = false; // 璁板綍鏄惁鏈夋湭瀹屾垚鐨勪换鍔�
+
+  function execute(task, resolve, reject) {
+    task()
+      .then((data) => {
+        resolve(data);
+      })
+      .catch((e) => {
+        reject(e);
+      })
+      .finally(() => {
+        // 绛夊緟浠诲姟闃熷垪涓鏋滄湁浠诲姟锛屽垯瑙﹀彂瀹冿紱鍚﹀垯璁剧疆isRunning = false,琛ㄧず鏃犱换鍔$姸鎬�
+        if (waitingQueue.length) {
+          const next = waitingQueue.shift();
+          execute(next.task, next.resolve, next.reject);
+        } else {
+          isRunning = false;
+        }
+      });
+  }
+  this.exec = function(task) {
+    return new Promise((resolve, reject) => {
+      if (isRunning) {
+        waitingQueue.push({
+          task,
+          resolve,
+          reject
+        });
+      } else {
+        isRunning = true;
+        execute(task, resolve, reject);
+      }
+    });
+  }
+}
+
+/* 闃熷垪瀹炰緥锛屾煇浜涘钩鍙颁竴璧蜂娇鐢ㄥ涓粍浠舵椂闇�瑕侀�氳繃闃熷垪閫愪竴缁樺埗锛屽惁鍒欓儴鍒嗙粯鍒舵柟娉曞紓甯革紝nvue绔殑iOS gcanvas灏ゅ叾鏄庢樉锛屽湪涓嶉�氳繃闃熷垪缁樺埗鏃朵細鍑虹幇鍥剧墖涓㈠け鐨勬儏鍐� */
+export const queueDraw = new Queue();
+export const queueLoadImage = new Queue();
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue b/uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue
new file mode 100644
index 0000000..dd8cfc0
--- /dev/null
+++ b/uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue
@@ -0,0 +1,1038 @@
+<template>
+	<view class="uqrcode"
+		:class="{ 'uqrcode-hide': hide }"
+		:style="{ width: `${templateOptions.width}px`, height: `${templateOptions.height}px` }">
+		<view class="uqrcode-canvas-wrapper">
+			<!-- 鐢诲竷 -->
+			<!-- #ifndef APP-NVUE -->
+			<canvas class="uqrcode-canvas"
+				:id="canvasId"
+				:canvas-id="canvasId"
+				:type="canvasType"
+				:style="{
+          width: `${templateOptions.canvasWidth}px`,
+          height: `${templateOptions.canvasHeight}px`,
+          transform: templateOptions.canvasTransform
+        }"
+				v-if="templateOptions.canvasDisplay"
+				@click="onClick"></canvas>
+			<!-- #endif -->
+
+			<!-- nvue鐢╣canvas -->
+			<!-- #ifdef APP-NVUE -->
+			<gcanvas class="uqrcode-canvas"
+				ref="gcanvas"
+				:style="{
+          width: `${templateOptions.canvasWidth}px`,
+          height: `${templateOptions.canvasHeight}px`
+        }"
+				v-if="templateOptions.canvasDisplay"
+				@click="onClick"></gcanvas>
+			<!-- #endif -->
+		</view>
+
+		<!-- 鍔犺浇鏁堟灉 -->
+		<view class="uqrcode-makeing"
+			v-if="loading === undefined || !loading ? makeing : loading">
+			<slot name="loading">
+				<image class="uqrcode-makeing-image"
+					:style="{ width: `${templateOptions.size / 4}px`, height: `${templateOptions.size / 4}px` }"
+					src="data:image/gif;base64,R0lGODlhAAEAAfIEAOHh4SSsWuDg4N3d3f///wAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDYuMC1jMDAyIDc5LjE2NDQ4OCwgMjAyMC8wNy8xMC0yMjowNjo1MyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjAyODhGMzM4RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjAyODhGMzM5RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDI4OEYzMzZEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4OEYzMzdEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4B//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+OjYyLiomIh4aFhIOCgYB/fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAAAh+QQFFAAEACwAAAAAAAEAAQAD/0i63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSCwaj8ikcslsOp/QqHRKrVqv2Kx2y+16v+CweEwum8/otHrNbrvf8Lh8Tq/b7/i8fs/v+/+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanigCqq6ytrieusbISAbW2t7i5uru8vb66bLLCrLDDw7S/ycrLzLXBxsLF0LHIzdbXzc/Trybb1BHY4eK92t6r0uaq1ePs4+Xp6PDg7fTh7+bx+PP1/Mz33vkA7utH0Ne/bQERDizIMNfBaQkhLmxIMcBDaBExTqzI8P+isYwfN3Ik6PFYt3TnRI7kVzLaSZQA1q0s2HLWS5QyZ/ar+a0ETHUqdbLjyc3nz5xC6RFtBdIkhKQ01/yMeVPeU6g7pR6tqu8q1npLiXEV6PVru7ApjcJEquyEPa1rxyosm83EWzVTm7qk688uNrRA1eIMatDvNcBUBVt9cJdEYzR55Urku8ztX7iDFXdlfLnE4zORNZPlfNiwNcR6bVJua7ou3q2i55I+3brv67ixJ8927bhzmtAkgDv4HIJ4GeEikDMw/oH5GOUgoCtw3oF6GOkesFvfsP0L9g7afY/o7uU7h/ClPYsHDTt4++Hri8c//j55/eXzm+d/fj96/+n/+1UX4HX/ZVcgeRggyIV5G6BHmycMauAgb5xEmMGEtnViIQYYVvbJhhd0yBqEBYJ34ICUgGiBiMmAomIFLP7iYonnnZiehjQ2aOODOE7l449MERbVai1iBuSRO67EVpG3IenkYvDptKSMRj5pZUhENjRlYU1e6aVqu420JTlVfmlmYGFyNCYviJ2ZWZoVrblLm25uFuVMcgJTZp1X5gmWkGzuyeeTfioF6JyCDopkoWcdqmeXilrJ6FCOOpRopD9O6k6luNCJ6V5wUqSpRZd+mqSYnN7iqalFhaplqrasyqpYWXYEqzOlzmpnA0mNKquuiblqa61kQgrsqWreSqqx/8e+eaeSyqIi7bTUVmvttdhmq+223Hbr7bejCCDuuOSWa+656Kar7rrnSjDAu/DGK++89NZr77340vsru/z2224E+QYs8MAEw7uvvwj3627BDDfM8MEJR5zuwg5XbHG9EEusMbkUX+zxxRlvvHHHH5f8cK4ip+wvySa3HHDIKifMsss0Y4xyzDijO3PNPBt8c85Aj7tzzzzDHPS6QxNNs9FHTwyw0lAPwHTT/0IQNdRTU11u0ld/nLXWQj/dddE/g50y12Nb/LXZaKft8Npgt+32ycyafbTccxMMt9Z45y3w3lT37Xe+qEnGruDxzihxalU/ULHiETNuLuI+k7i44f9Ii013j5Fjri7l70Ius+dOW/32hxpLvrXmBYuOsOocs6436pfndrjsA7u+Muk64/437Z3bnrnpDeuuMO+NO/A48KML/7nvLzP/OvKTQ0+49Ls7X7rjp1sevHu1c1889sdr3zvxm1eYOvWro986+fzCHrb7s3vfPPjfK9895/ePMLL1+DKe3c6Hv/fZb4DPM5++4IfA9hWwfvxrIAH9tz/1STCBD8wdAy8oNfYlboMXlF/oQChBEXbwgByMnQLnJcAUmrCFHDTh4FhYNrZ5cIY2q5sLb4hDGuowhjzs4Qd/GMIgCnGERCyhEY8IOAxS8IgVZE8Kk2cfKI4viQ2UIRPAaxi3JQqxiXcDoBXtVbgVOlB/YzTgb9ZnRhWKL40axCIVQ/A/+sExgFwU1wvFeMchrjF8T8xfA/oYxz8Kko5sfCMh71XGDJZPkYvMoSH7V8VDLiCS15Nj9do4P0hiUl6NDCQlGfBJRoLrlKhMpSpXycpWuvKVsIylLGdJy1ra8pa4zKUud8nLXvryl8AMpjCHScxiGvOYyEymMpfJzGY685nQjKY0p0nNalrzmtjMpja3yc1uevOb4AynOMdJhwQAACH5BAUUAAQALDIAMgCcAJwAAAP/KLrcTjDKSWt0OFsIuv9gKI5kaZ6Ztq1s6iorKs90/apsTt1pbP/AIA+mK16Gj41wyWwan8ikpUmtRp/GaMNn7Xq3WJ2Wwf2arWHxmDg9u6np3JpdeduX8da8fO8j83xXSn6EQ4CDa4GFi2CHO3uIjJJkjo+JkZOTlZZjipmFmxNzAp6ffqESo6Wmd6hHl22sjK4ckLGyoLSqmLh9tAS7t72+urZ1QL+LycacNcuEz528M9HErsHHP9WtxbDZNtt24YbTMuNu5zerJulm7S7rJe9e8zjfzt2n+VrxJPVo+wQJo/GvSsFG9wgGFLeQ3EBqDdFFVFcOxUEnE1/0G3GR/0lHOs0UXss10ltIiCX1peRX8cRHIS83iniJLVRNUcgyfonZkp1Oej/tnTT3K87NSkdfgSuaJukhp8ByMsUCNQ/UIFPDVDXKDKe2rFC6IhWrFB/YIlubkq319awak5uuSnWrB+5Yu2VF0pUpBZXctnt7jhqMl63KhMMIU3z4hm9ixY4xMn6sGENkj4IpVyaVuctlzdImn/kMWiDixp1L/z08VPVm0lhTuw59WqLo2YNhz22NO7dsOL9789ANmLfwwlGhBT8Obzke58wtQ499O/qf6bu9WvddHWj37RqxF9cOHrky8ZvTs/wOkH2IwPDjy59Pv779+/jz69/Pv7////8ABijggAQWaOCBCCao4FQDNOjggxBGKOGEFFZooYQrBKDhhhx26OGHIIYo4ogfXmjiiSim6GCGJLbo4oswaqjijDTSyGKMOOYYY4089ljhjToGKWSJPhZpJJBDJimkkUz2iKSSUO7Y5JQqPhnllSRSqeWJVmLpJZFbhjlhl1+WKaOYaEJIpplfpulmg2uyieWbbsYpZ5R0pmnnnUrmieaefA7pp5iABhrkoGEWamiOiG6p6KJSNjrlo5C+KCmVlFba4qWTbqCpl5w2memnIvLIkwVB6mdqUBh6qqOqNZ5aQar5rbpSiqMGAKuNrEaY664zykoBrfjZ6lesruYIbJX/vaqZLI7L4trsg7/WiuytKFZb7LXH8orqq9Z6222wz8YYbbbTrlgujOdymS6c677YronCTkDsfcbaxO2w4G4rrr7/2tsvvvvGVbAE99qXr8EBIzywwgc7srDDyoZLLrbufluxv6EOUFTC9XWsLi0g0ycyvCQ/HPLJH6tsMsu/lDzfyR7H7PLMMKe8McEit7wzxD3b/PPKQesMrcWh+kxqnzm7sjSeTaPyNJQ0Kz31oVGHcnWSVQu9tY5dG/01jmE7PTbYWW9yNtpFm712pDQ3HMHbZEf8lN0E0A03sxjTG6/eIU4sMd6AW4q3VYQXvunhXMkNgeKLOw6I4I9DPiLlGZMnbnngjKsl+ealdq6V5qB7iDnin5f+YQIAIfkEBRQABAAsMgAyAJwAnAAAA/84utxOMMpJa3Q4Wyi6/2AojmRpnpm2rWzqKisqz3T9qmxO3Wls/8AgD6YrXoaPjXDJbBqfyKSlSa1Gn8Zow2fterdYnZbB/ZqtYfGYOD27qencml1525fx1rx87yPzfFdKfoRDgINrgYWLYIc7e4iMkmSOj4mRk5OVlmOKmYWbE3MDnp9+oRKjpaZ3qEeXbayMrhyQsbKgtKqYuH20BLu3vb66tnVAv4vJxpw1y4TPnbwz0cSuwcc/1a3FsNk223bhhtMy427nN6sm6WbtLusl717zON/O3af5WvEk9Wj7BAmj8a9KwUb3CAYUt5DcQGoN0UVUVw7FQScTX/QbcZH/SUc6zRReyzXSW0iIJfWl5FfxxEchLzeKeIktVE1RyDJ+idmSnU56P+2dNPcrzs1KR1+BK5om6SGnwHIyxQI1D9QgU8NUNcoMp7asULoiFasUH9giW5uSrfX1rBqTm65KdasH7li7ZUXSlSkFldy2e3uOGoyXrcqEwwhTfPiGb2LFjjEyfqwYQ2SPgilXJpW5y2XN0iaf+QxaIOLGnUv/PTxU9WbSWFO7Dn1aoujZg2HPbY07t2w4v3vz0A2Yt/DCUaEFPw5vOR7nzC1Dj307+p/pu71a910daPftGrEX1w4euTLxm9Oz/A6QfYjA8OPLn0+/vv37+PPr38+/v////wAGKOCABBZo4IEIJqjgVAE06OCDEEYo4YQUVmihhMQBoOGGHHbo4YcghsjhhSSWaOKJDmYo4oostqghijDGGKOKLtZo44sy5qgjhTTe6OOKOwYpZAA9/mikh0MmKWORRzYJgJJQnsikk0ZGaeWFU1Lp45VcTpilljZ2KeaDX4Lp4pholmkmi2iOqeaaIrYp5ptwgihnl3TWieSdV+ap54h8WunnnzgGCuWghBoaJaJ/KnooeoTW6KiSjOo5aZKV1pnjL5tCp1+nroBaG4ufLkmLqMaJWOqMp5rqXoerwsipq6OuGCuKs7L6Koe3StmqrrWqmh+qmxCbipG9mpirrP+eDktrKMbmVWOyJS6La7P4RXuItsn5SC2J1vq664bfYvkrs+NqWK6F4SqL7X3c5sHtketW2G6179oXbxzzIusssNA+S56N9fJ47rXpAlCwlweLG2yIC7fJU7aXkhnUhxGnebGHGbu5Maz/Vkzkx7yGXPHE8IrcIMr6qjzySgSbfCnL9bn8sl/+UqwyTZHeaDPPPUvqMtBBt/gzyUVvOTTSSYe5NMxNr3k01FGDOTXOVWv6NNZZS721TV3DaXO/YZu5bxpkl63l2WGkrbaTbGPh9ttHxv3E3HT/aLcReOfts8CV9O230AAXC7i0gxOOLiqCJ87m4dtC3q3jThceuOQElP+YAAAh+QQFFAAEACwyADIAnACcAAAD/xi63E4wyklrdDhbOLr/YCiOZGmKWcpsbEuoMHvOdG17sOruVJ7Kt6Aw6NPwjq/iYzNsOkvKJXIXbQCfWGx1NaVuFdesWPgFd13lQHjMpqXP6PK6TSe94ay7pc6HyvEbehV9hCGCgBOHE4WMHYqIEI8RjYySiJYElIWYeJiahJxwnp98oWejpHSmXaipbKtTra5isEiys1p/kIm6g7hjtUe3v03BPMM0uxTFvcpJX3M1zhLM0NORzYtD1xxDxl7We9vc1Vvcz+ZM49flVefIM+ftUe/Z1OvT80r14b5C8t7sQYJ3AiAZgZcQZsLnTF8RfunE/SMXsJ8zgiYMElHYSf9hE403vsWxqG0iu4oRp2EsAdKGyBYrSbSs8TKPR4bKHPqA6E6dyXwoe16LOWKmG46ibv5sGJQeN6IijM6oGUhpkHMdSe6CGgJrUq0Drd7wegppWbDdlpIFl/KiWBtrY5ll9VZaXGFz5aJdqPZu1b1Z25a86petUJV1kxUeKXhr4niLYaaZTFmKP03RjlbePDkzIc8nOIt+3Ae0idGonUrE7HNj6tc6WlMy7Qe2bcvLSNG2c7v3gt1tgKPw7Vv4GOMgiBeX3Qj5B+W9nWOR7gi6bepOsFu/zpyR9u2vsX/srhn8aPE47x00f578Z/eh2bdfPRv+afmi0fed1BQ/VzH/3/lXmX6E0eeSgAPaV0eACP6XBXaRRSjhhBRWaOGFGGao4YYcdujhhyCGKOKIJJZo4okopqjiimQB4OKLMMYo44w01mjjjTMSKMCOPPbo449ABinkkDgWaeSROOpI5JJMNonkk1BGqaSTVFYZ5ZVY3jillVx2meWXSG7p5Zhkgmmmi2KWqeaZbBqZ5ppwtilnjG/GaeecbNZ55554Yqknn4D2eeSfgRYqaI2EGqrooS8muiijkDr6KKSCSjoppXNaeimmeSq46aec2qgpqKH66SmpqJYKwKipqjroqa3yKVWSsP64oaknSVmrj7deOauWu/bYq665QgmhhrgCRexl/1UOayxFy+bGpbNP/ipqsDxSGya0zxropLavFlsttjuC6ya343rbpLlFWosouQKwS6u426rLpLzA0hsus1Tie62+59q7pL/vAtwuvATT6K7CCCPrK7r18vutw9Hm9LDARCacI8T7SmulxjIuvDHGQ4JMJ8cBS7wuxa6GjPK9LLcMo8i2xiwzmi8PbPPNNPO6s8w9C/tzy0FnO7SrRZd7tKpJx7t0qU2bzGjUT4fadKxYn2xw1lwfvHXXYDP8ddhkN5pz2WhfjTbQZ68dttpuM9123De7PDbddZvJatZUk4x3xbsk6/Hfa/atMuGCWww4f4gXPrfYhzferbKTDy554hmBXxz55R0rXvlgnGvO1OJphS665+luTncCADs=">
+				</image>
+			</slot>
+		</view>
+
+		<!-- 閿欒澶勭悊 -->
+		<view class="uqrcode-error"
+			v-if="isError"
+			@click="onClick">
+			<slot name="error"
+				:error="error">
+				<text class="uqrcode-error-message">{{ error.errMsg }}</text>
+			</slot>
+		</view>
+
+		<!-- H5淇濆瓨鎻愮ず -->
+		<!-- #ifdef H5 -->
+		<view class="uqrcode-h5-save"
+			v-if="isH5Save">
+			<slot name="h5save"
+				:tempFilePath="tempFilePath">
+				<image class="uqrcode-h5-save-image"
+					:src="tempFilePath"></image>
+				<text class="uqrcode-h5-save-text">{{ h5SaveIsDownload ? '鑻ヤ繚瀛樺け璐ワ紝' : '' }}璇烽暱鎸変簩缁寸爜杩涜淇濆瓨</text>
+			</slot>
+			<view class="uqrcode-h5-save-close"
+				@click.stop="isH5Save = false">
+				<view class="uqrcode-h5-save-close-before"></view>
+				<view class="uqrcode-h5-save-close-after"></view>
+			</view>
+		</view>
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
+	import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
+	// #ifdef VUE3
+	import { toRaw } from 'vue';
+	// #endif
+	/* 寮曞叆uvQRCode鏍稿績js */
+	import UQRCode from './qrcode';
+	/* 寮曞叆nvue鎵�闇�妯″潡 */
+	// #ifdef APP-NVUE
+	import { enable, WeexBridge } from './gcanvas';
+	const modal = weex.requireModule('modal');
+	// #endif
+	/* 寮曞叆闃熷垪 */
+	import { queueDraw, queueLoadImage } from './queue';
+	/* 寮曞叆缂撳瓨鍥剧墖 */
+	import { cacheImageList } from './cache';
+	let instance = null;
+	/**
+	 * qrcode 浜岀淮鐮�
+	 * @description 浜岀淮鐮佺敓鎴愭彃浠讹紝鍙墿灞曟�ч珮锛屽畠鏀寔鑷畾涔夋覆鏌撲簩缁寸爜锛屽彲閫氳繃uQRCode API寰楀埌浜岀淮鐮佺粯鍒跺叧閿俊鎭悗锛屼娇鐢╟anvas銆乻vg鎴杍s鎿嶄綔dom鐨勬柟寮忕粯鍒朵簩缁寸爜鍥炬銆傝繕鍙嚜瀹氫箟浜岀淮鐮佹牱寮忥紝濡傞殢鏈洪鑹层�佸渾鐐广�佹柟鍧椼�佸潡涓庡潡涔嬮棿鐨勯棿璺濈瓑銆�
+	 * @tutorial https://www.uvui.cn/components/qrcode.html
+	 * @property {String}	 value	 浜岀淮鐮佸唴瀹� (start涓簍rue鏃跺繀濉� )
+	 * @property {Object}	 options  浜岀淮鐮侀厤缃�夐」 (data|size|margin...)
+	 * @property {String}	 fileType  瀵煎嚭鐨勬枃浠剁被鍨�  (jpg | png)  
+	 * @property {String}	 start  鏄惁鍒濆鍖栫粍浠跺悗灏卞紑濮嬬敓鎴� (榛樿 true)
+	 * @property {String}	 auto  鏄惁鏁版嵁鍙戠敓鏀瑰彉鑷姩閲嶇粯 (榛樿 false)
+	 * @property {String}	 hide  闅愯棌缁勪欢銆傚鏋滃彧闇�瑕佸鍑轰簩缁寸爜浣滀负鍥剧墖浣跨敤锛屽彲璁剧疆涓簍rue锛屼笉鑳藉湪缁勪欢鎴栫粍浠剁埗绾у厓绱犺缃畍-if="false"銆乿-show="false"銆乻tyle="display:none;"绛夊疄鐜伴殣钘忔晥鏋滐紝杩欐牱浼氬鑷村鍑轰簩缁寸爜绌虹櫧  (榛樿 false)
+	 * @property {String}	 type  canvas缁勪欢绫诲瀷銆傚井淇″皬绋嬪簭榛樿2d (榛樿 undefined)
+	 * @property {String}	 queue  闃熷垪缁樺埗 (榛樿 false)
+	 * @property {String}	 isQueueLoadImage  鏄惁闃熷垪鍔犺浇鍥剧墖锛岄�夋嫨true灏嗛�氳繃闃熷垪缂撳瓨鎵�闇�瑕佸姞杞界殑鍥剧墖銆備紭鐐规槸鍔犺浇閲嶅璧勬簮鍙噺灏戣祫婧愯姹傛鏁帮紝鑺傜渷缃戠粶璧勬簮锛岀己鐐规槸浼氳浆鍖栦负鍚屾璇锋眰锛岃祫婧愪笉閲嶅涓斿鐨勬儏鍐典笅锛岀瓑寰呮椂闂翠細鏇翠箙銆傛�讳箣锛岃姹傞噸澶嶈祫婧愯緝澶氬垯閫夋嫨true锛岃姹備笉閲嶅璧勬簮杈冨鍒欓�夋嫨false (榛樿 false)
+	 * @property {String}	 loading  loading鎬� (榛樿 false)
+	 * @property {String}	 h5SaveIsDownload  H5淇濆瓨鍗宠嚜鍔ㄤ笅杞斤紙鍦ㄦ敮鎸佺殑鐜涓嬶級锛岄粯璁alse涓轰粎寮瑰眰鎻愮ず鐢ㄦ埛闇�瑕侀暱鎸夊浘鐗囦繚瀛橈紝涓嶄細鑷姩涓嬭浇 (榛樿 false)
+	 * @property {String}	 h5DownloadName  H5涓嬭浇鍚嶇О 
+	 * @property {String}	 h5SaveTip  H5淇濆瓨浜岀淮鐮佹椂鍊欐槸鍚︽樉绀烘彁绀�
+	 * @example <uv-qrcode ref="uvqrcode" size="400rpx" canvas-id="qrcode" value="https://www.uvui.cn"></uv-qrcode>
+	 */
+	export default {
+		name: 'uv-qrcode',
+		mixins: [mpMixin,mixin,props],
+		emits: ['click','change','complete'],
+		data() {
+			return {
+				canvasId: "",
+				canvas: undefined,
+				canvasType: undefined,
+				canvasContext: undefined,
+				makeDelegate: undefined,
+				drawDelegate: undefined,
+				toTempFilePathDelegate: undefined,
+				makeExecuted: false,
+				makeing: false,
+				drawing: false,
+				isError: false,
+				error: undefined,
+				isH5Save: false,
+				tempFilePath: '',
+				templateOptions: {
+					size: 0,
+					width: 0, // 缁勪欢瀹藉害
+					height: 0,
+					canvasWidth: 0, // canvas瀹藉害
+					canvasHeight: 0,
+					canvasTransform: '',
+					canvasDisplay: false
+				},
+				uqrcodeOptions: {
+					data: ''
+				},
+				plugins: [],
+				makeingPattern: [
+					[
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true]
+					],
+					[
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, false, false, false],
+						[true, true, true, true, true, true, false, true, true, true],
+						[true, true, true, true, true, true, false, true, true, true],
+						[true, true, true, true, true, true, false, true, true, true]
+					],
+					[
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, true, true, true, true, false, false, false],
+						[true, true, true, true, true, true, true, false, false, false],
+						[true, true, true, true, true, true, true, false, false, false],
+						[true, true, true, false, false, false, false, true, true, true],
+						[true, true, true, false, false, false, false, true, true, true]
+					],
+					[
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, false, false, false, false, false, false, false],
+						[true, true, true, false, false, false, false, false, false, false],
+						[true, true, true, false, false, false, false, false, false, false],
+						[true, true, true, false, false, false, false, false, false, false],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true],
+						[true, true, true, true, true, true, true, true, true, true]
+					]
+				]
+			};
+		},
+		watch: {
+			type: {
+				handler(val) {
+					const types = ['2d'];
+					if (types.includes(val)) {
+						this.canvasType = val;
+					} else {
+						this.canvasType = undefined;
+					}
+				},
+				immediate: true
+			},
+			value: {
+				handler() {
+					if (this.auto) {
+						this.remake();
+					}
+				}
+			},
+			size: {
+				handler() {
+					if (this.auto) {
+						this.remake();
+					}
+				}
+			},
+			options: {
+				handler() {
+					if (this.auto) {
+						this.remake();
+					}
+				},
+				deep: true
+			},
+			makeing: {
+				handler(val) {
+					if (!val) {
+						if (typeof this.toTempFilePathDelegate === 'function') {
+							this.toTempFilePathDelegate();
+						}
+					}
+				}
+			}
+		},
+		created() {
+			this.canvasId = this.$uv.guid();
+		},
+		mounted() {
+			this.templateOptions.size = this.$uv.getPx(this.size);
+			this.templateOptions.width = this.templateOptions.size;
+			this.templateOptions.height = this.templateOptions.size;
+			this.templateOptions.canvasWidth = this.templateOptions.size;
+			this.templateOptions.canvasHeight = this.templateOptions.size;
+			if (this.canvasType == '2d') {
+				// #ifndef MP-WEIXIN
+				this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+        this.templateOptions.canvasHeight})`;
+				// #endif
+			} else {
+				this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+        this.templateOptions.canvasHeight})`;
+			}
+			if (this.start) {
+				this.$nextTick(()=>{
+					this.make();
+				})
+			}
+		},
+		methods: {
+			/**
+			 * 鑾峰彇妯℃澘閫夐」
+			 */
+			getTemplateOptions() {
+				var size = this.$uv.getPx(this.size);
+				return deepReplace(this.templateOptions, {
+					size,
+					width: size,
+					height: size
+				});
+			},
+			/**
+			 * 鑾峰彇鎻掍欢閫夐」
+			 */
+			getUqrcodeOptions() {
+				return deepReplace(this.options, {
+					data: String(this.value),
+					size: Number(this.templateOptions.size)
+				});
+			},
+			/**
+			 * 閲嶇疆鐢诲竷
+			 */
+			resetCanvas(callback) {
+				this.templateOptions.canvasDisplay = false;
+				this.$nextTick(() => {
+					this.templateOptions.canvasDisplay = true;
+					this.$nextTick(() => {
+						callback && callback();
+					});
+				});
+			},
+			/**
+			 * 缁樺埗浜岀淮鐮�
+			 */
+			async draw(callback = {}, isDrawDelegate = false) {
+				if (typeof callback.success != 'function') {
+					callback.success = () => {};
+				}
+				if (typeof callback.fail != 'function') {
+					callback.fail = () => {};
+				}
+				if (typeof callback.complete != 'function') {
+					callback.complete = () => {};
+				}
+
+				if (this.drawing) {
+					if (!isDrawDelegate) {
+						this.drawDelegate = () => {
+							this.draw(callback, true);
+						};
+						return;
+					}
+				} else {
+					this.drawing = true;
+				}
+
+				if (!this.canvasId) {
+					console.error('[uQRCode]: canvasId must be set!');
+					this.isError = true;
+					this.drawing = false;
+					callback.fail({
+						errMsg: '[uQRCode]: canvasId must be set!'
+					});
+					callback.complete({
+						errMsg: '[uQRCode]: canvasId must be set!'
+					});
+					return;
+				}
+				if (!this.value) {
+					console.error('[uQRCode]: value must be set!');
+					this.isError = true;
+					this.drawing = false;
+					callback.fail({
+						errMsg: '[uQRCode]: value must be set!'
+					});
+					callback.complete({
+						errMsg: '[uQRCode]: value must be set!'
+					});
+					return;
+				}
+
+				/* 缁勪欢鏁版嵁 */
+				this.templateOptions = this.getTemplateOptions();
+				/* uQRCode閫夐」 */
+				this.uqrcodeOptions = this.getUqrcodeOptions();
+				/* 绾犻敊绛夌骇鍏煎瀛楁瘝鍐欐硶 */
+				if (typeof this.uqrcodeOptions.errorCorrectLevel === 'string') {
+					this.uqrcodeOptions.errorCorrectLevel = UQRCode.errorCorrectLevel[this.uqrcodeOptions.errorCorrectLevel];
+				}
+				/* nvue涓嶆敮鎸佸姩鎬佷慨鏀筭canvas灏哄锛岄櫎nvue澶栵紝榛樿浣跨敤useDynamicSize */
+				// #ifndef APP-NVUE
+				if (typeof this.options.useDynamicSize === 'undefined') {
+					this.uqrcodeOptions.useDynamicSize = true;
+				}
+				// #endif
+				// #ifdef APP-NVUE
+				if (typeof this.options.useDynamicSize === 'undefined') {
+					this.uqrcodeOptions.useDynamicSize = false;
+				}
+				// if (typeof this.options.drawReserve === 'undefined') {
+				//   this.uqrcodeOptions.drawReserve = true;
+				// }
+				// #endif
+
+				/* 鑾峰彇uQRCode瀹炰緥 */
+				const qr = instance = new UQRCode();
+				/* 娉ㄥ唽鎵╁睍 */
+				this.plugins.forEach(p => qr.register(p.plugin));
+				/* 璁剧疆uQRCode閫夐」 */
+				qr.setOptions(this.uqrcodeOptions);
+				/* 璋冪敤鍒朵綔浜岀淮鐮佹柟娉� */
+				qr.make();
+
+				/* 鑾峰彇canvas涓婁笅鏂� */
+				let canvasContext = null;
+				// #ifndef APP-NVUE
+				if (this.canvasType === '2d') {
+					// #ifdef MP-WEIXIN
+					/* 寰俊灏忕▼搴忚幏鍙朿anvas2d涓婁笅鏂囨柟寮� */
+					const canvas = (this.canvas = await new Promise(resolve => {
+						uni
+							.createSelectorQuery()
+							.in(this) // 鍦ㄧ粍浠跺唴浣跨敤闇�瑕�
+							.select(`#${this.canvasId}`)
+							.fields({
+								node: true,
+								size: true
+							})
+							.exec(res => {
+								resolve(res[0].node);
+							});
+					}));
+					canvasContext = this.canvasContext = canvas.getContext('2d');
+					/* 2d鐨勭粍浠惰缃楂樹笌瀹為檯canvas缁樺埗瀹介珮涓嶆槸涓�涓紝鎵撲釜姣旀柟锛岀粍浠秙ize=200锛宑anvas.width璁剧疆涓�100锛岄偅涔堢粯鍒跺嚭鏉ュ氨鏄�100=200锛岀粍浠秙ize=400锛宑anvas.width璁剧疆涓�800锛岀粯鍒跺ぇ灏忚繕鏄�800=400锛屾墍浠ユ棤闇�鐞嗕細涓嬫柟杩斿洖鐨刣ynamicSize鏄灏戯紝鎸塪pr閲嶆柊璧嬪�肩粰canvas鍗冲彲 */
+					this.templateOptions.canvasWidth = qr.size;
+					this.templateOptions.canvasHeight = qr.size;
+					this.templateOptions.canvasTransform = '';
+					/* 浣跨敤dynamicSize+scale锛屽彲浠ヨВ鍐冲皬鍧楅棿鍑虹幇鐧界嚎闂锛宒pr鍙互瑙e喅妯$硦闂 */
+					const dpr = uni.getSystemInfoSync().pixelRatio;
+					canvas.width = qr.dynamicSize * dpr;
+					canvas.height = qr.dynamicSize * dpr;
+					canvasContext.scale(dpr, dpr);
+					/* 寰俊灏忕▼搴忚幏鍙栧浘鍍忔柟寮� */
+					qr.loadImage = this.getLoadImage(function(src) {
+						/* 灏忕▼搴忎笅鑾峰彇缃戠粶鍥剧墖淇℃伅闇�鍏堥厤缃甦ownload鍩熷悕鐧藉悕鍗曟墠鑳界敓鏁� */
+						return new Promise((resolve, reject) => {
+							const img = canvas.createImage();
+							img.src = src;
+							img.onload = () => {
+								resolve(img);
+							};
+							img.onerror = err => {
+								reject(err);
+							};
+						});
+					});
+					// #endif
+					// #ifndef MP-WEIXIN
+					/* 闈炲井淇″皬绋嬪簭涓嶆敮鎸�2d锛屽垏鎹㈠洖uniapp鑾峰彇canvas涓婁笅鏂囨柟寮� */
+					canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
+					/* 浣跨敤dynamicSize锛屽彲浠ヨВ鍐冲皬鍧楅棿鍑虹幇鐧界嚎闂锛屽啀閫氳繃scale缂╂斁鑷硈ize锛屼娇鍏惰揪鍒版墍璁惧昂瀵� */
+					this.templateOptions.canvasWidth = qr.dynamicSize;
+					this.templateOptions.canvasHeight = qr.dynamicSize;
+					this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+          this.templateOptions.canvasHeight})`;
+					/* uniapp鑾峰彇鍥惧儚鏂瑰紡 */
+					qr.loadImage = this.getLoadImage(function(src) {
+						return new Promise((resolve, reject) => {
+							if (src.startsWith('http')) {
+								uni.getImageInfo({
+									src,
+									success: res => {
+										resolve(res.path);
+									},
+									fail: err => {
+										reject(err);
+									}
+								});
+							} else {
+								if (src.startsWith('.')) {
+									console.error('[uQRCode]: 鏈湴鍥剧墖璺緞浠呮敮鎸佺粷瀵硅矾寰勶紒');
+									throw new Error('[uQRCode]: local image path only supports absolute path!');
+								} else {
+									resolve(src);
+								}
+							}
+						});
+					});
+					// #endif
+				} else {
+					/* uniapp鑾峰彇canvas涓婁笅鏂囨柟寮� */
+					canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
+					/* 浣跨敤dynamicSize锛屽彲浠ヨВ鍐冲皬鍧楅棿鍑虹幇鐧界嚎闂锛屽啀閫氳繃scale缂╂斁鑷硈ize锛屼娇鍏惰揪鍒版墍璁惧昂瀵� */
+					this.templateOptions.canvasWidth = qr.dynamicSize;
+					this.templateOptions.canvasHeight = qr.dynamicSize;
+					this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+          this.templateOptions.canvasHeight})`;
+					/* uniapp鑾峰彇鍥惧儚鏂瑰紡 */
+					qr.loadImage = this.getLoadImage(function(src) {
+						return new Promise((resolve, reject) => {
+							/* getImageInfo鍦ㄥ井淇″皬绋嬪簭鐨刡ug锛氭湰鍦拌矾寰勮繑鍥炶矾寰勪細鎶婂紑澶寸殑/鎴�../绉婚櫎锛屽鑷磋矾寰勯敊璇紝瑙e喅鏂规硶锛氶檺鍒跺彧鑳戒娇鐢ㄧ粷瀵硅矾寰� */
+							if (src.startsWith('http')) {
+								uni.getImageInfo({
+									src,
+									success: res => {
+										resolve(res.path);
+									},
+									fail: err => {
+										reject(err);
+									}
+								});
+							} else {
+								if (src.startsWith('.')) {
+									console.error('[uQRCode]: 鏈湴鍥剧墖璺緞浠呮敮鎸佺粷瀵硅矾寰勶紒');
+									throw new Error('[uQRCode]: local image path only supports absolute path!');
+								} else {
+									resolve(src);
+								}
+							}
+						});
+					});
+				}
+				// #endif
+				// #ifdef APP-NVUE
+				/* NVue鑾峰彇canvas涓婁笅鏂囨柟寮� */
+				const gcanvas = this.$refs['gcanvas'];
+				const canvas = enable(gcanvas, {
+					bridge: WeexBridge
+				});
+				canvasContext = this.canvasContext = canvas.getContext('2d');
+				/* NVue鑾峰彇鍥惧儚鏂瑰紡 */
+				qr.loadImage = this.getLoadImage(function(src) {
+					return new Promise((resolve, reject) => {
+						/* getImageInfo鍦╪vue鐨刡ug锛氳幏鍙栧悓涓�涓矾寰勭殑鍥剧墖淇℃伅锛屽悓涓�鏃堕棿绗竴娆¤幏鍙栨垚鍔燂紝鍚庣画澶辫触锛岀寽娴嬫槸鍐欏叆鏈湴鏃朵骇鐢熸枃浠跺啓鍏ュ啿绐侊紝鎵�浠ユ病鏈夎繑鍥烇紝鐗瑰埆鏄浜庣綉缁滆祫婧� --- 宸插疄鐜伴槦鍒楃粯鍒讹紝宸茶В鍐虫闂 */
+						if (src.startsWith('.')) {
+							console.error('[uQRCode]: 鏈湴鍥剧墖璺緞浠呮敮鎸佺粷瀵硅矾寰勶紒');
+							throw new Error('[uQRCode]: local image path only supports absolute path!');
+						} else {
+							uni.getImageInfo({
+								src,
+								success: res => {
+									resolve(res.path);
+								},
+								fail: err => {
+									reject(err);
+								}
+							});
+						}
+					});
+				});
+				// #endif
+
+				/* 璁剧疆uQRCode瀹炰緥鐨刢anvas涓婁笅鏂� */
+				qr.canvasContext = canvasContext;
+				/* 寤舵椂绛夊緟椤甸潰閲嶆柊缁樺埗瀹屾瘯 */
+				setTimeout(() => {
+					/* 浠庢彃浠惰幏鍙栧叿浣撹璋冪敤鍝竴涓墿灞曞嚱鏁� */
+					var plugin = this.plugins.find(p => p.name == qr.style);
+					var drawCanvasName = plugin ? plugin.drawCanvas : 'drawCanvas';
+					/* 铏界劧qr[drawCanvasName]鏄洿鎺ヨ繑鍥濸romise鐨勶紝浣嗙敱浜巎s鍐呴儴this鎸囧悜闂锛屾晠涓嶈兘鐩存帴exec(qr[drawCanvasName])姝ゆ柟寮忔墽琛岋紝闇�瑕佹敼鎴恊xec(() => qr[drawCanvasName]())鎵嶈兘姝g‘鑾峰彇this */
+					var drawCanvas;
+					if (this.queue) {
+						drawCanvas = () => queueDraw.exec(() => qr[drawCanvasName]());
+						// drawCanvas = () => queueDraw.exec(() => new Promise((resolve, reject) => {
+						//   setTimeout(() => {
+						//     qr[drawCanvasName]().then(resolve).catch(reject);
+						//   }, 1000);
+						// }));
+					} else {
+						drawCanvas = () => qr[drawCanvasName]();
+					}
+					/* 璋冪敤缁樺埗鏂规硶灏嗕簩缁寸爜鍥炬缁樺埗鍒癱anvas涓� */
+					drawCanvas()
+						.then(() => {
+							if (this.drawDelegate) {
+								/* 楂橀閲嶇粯绾犳 */
+								let delegate = this.drawDelegate;
+								this.drawDelegate = undefined;
+								delegate();
+							} else {
+								this.drawing = false;
+								callback.success();
+							}
+						})
+						.catch(err => {
+							console.log(err);
+							if (this.drawDelegate) {
+								/* 楂橀閲嶇粯绾犳 */
+								let delegate = this.drawDelegate;
+								this.drawDelegate = undefined;
+								delegate();
+							} else {
+								this.drawing = false;
+								this.isError = true;
+								callback.fail(err);
+							}
+						})
+						.finally(() => {
+							callback.complete();
+						});
+				}, 300);
+			},
+			/**
+			 * 鐢熸垚浜岀淮鐮�
+			 */
+			make(callback = {}) {
+				this.makeExecuted = true;
+				this.makeing = true;
+				this.isError = false;
+
+				if (typeof callback.success != 'function') {
+					callback.success = () => {};
+				}
+				if (typeof callback.fail != 'function') {
+					callback.fail = () => {};
+				}
+				if (typeof callback.complete != 'function') {
+					callback.complete = () => {};
+				}
+
+				this.resetCanvas(() => {
+					clearTimeout(this.makeDelegate);
+					this.makeDelegate = setTimeout(() => {
+						this.draw({
+							success: () => {
+								setTimeout(() => {
+									callback.success();
+									this.complete(true);
+								}, 300);
+							},
+							fail: err => {
+								callback.fail(err);
+								this.error = err;
+								this.complete(false, err.errMsg);
+							},
+							complete: () => {
+								callback.complete();
+								this.makeing = false;
+							}
+						});
+					}, 300);
+				});
+			},
+			/**
+			 * 閲嶆柊鐢熸垚
+			 */
+			remake(callback) {
+				this.$emit('change');
+				this.make(callback);
+			},
+			/**
+			 * 鐢熸垚瀹屾垚
+			 */
+			complete(success = true, errMsg = '') {
+				if (success) {
+					this.$emit('complete', {
+						success
+					});
+				} else {
+					this.$emit('complete', {
+						success,
+						errMsg
+					});
+				}
+			},
+			/**
+			 * 瀵煎嚭涓存椂璺緞
+			 */
+			toTempFilePath(callback = {}) {
+				if (typeof callback.success != 'function') {
+					callback.success = () => {};
+				}
+				if (typeof callback.fail != 'function') {
+					callback.fail = () => {};
+				}
+				if (typeof callback.complete != 'function') {
+					callback.complete = () => {};
+				}
+
+				if (!this.makeExecuted) {
+					console.error('[uQRCode]: make() 鏂规硶浠庢湭璋冪敤锛佽鍏堟垚鍔熻皟鐢� make() 鍚庡啀杩涜鎿嶄綔銆�');
+					var err = {
+						errMsg: '[uQRCode]: make() method has never been executed! please execute make() successfully before operating.'
+					};
+					callback.fail(err);
+					callback.complete(err);
+					return;
+				}
+
+				if (this.isError) {
+					callback.fail(this.error);
+					callback.complete(this.error);
+					return;
+				}
+
+				if (this.makeing) {
+					/* 濡傛灉杩樺湪鐢熸垚鐘舵�侊紝閭e綋鍓嶆搷浣滃皢鎵樼鍒板鎵橈紝鐩戝惉鐢熸垚瀹屾垚鍚庡啀閫氳繃濮旀墭澶嶈皟褰撳墠鏂规硶 */
+					this.toTempFilePathDelegate = () => {
+						this.toTempFilePath(callback);
+					};
+					return;
+				} else {
+					this.toTempFilePathDelegate = null;
+				}
+
+				// #ifndef APP-NVUE
+				if (this.canvasType === '2d') {
+					// #ifdef MP-WEIXIN
+					try {
+						let dataURL = null;
+						// #ifdef VUE3
+						dataURL = toRaw(this.canvas)
+							.toDataURL();
+						// #endif
+						// #ifndef VUE3
+						dataURL = this.canvas.toDataURL();
+						// #endif
+						callback.success({
+							tempFilePath: dataURL
+						});
+						callback.complete({
+							tempFilePath: dataURL
+						});
+					} catch (e) {
+						callback.fail(e);
+						callback.complete(e);
+					}
+					// #endif
+				} else {
+					uni.canvasToTempFilePath({
+							canvasId: this.canvasId,
+							fileType: this.fileType,
+							width: Number(this.templateOptions.canvasWidth),
+							height: Number(this.templateOptions.canvasHeight),
+							destWidth: Number(this.templateOptions.size),
+							destHeight: Number(this.templateOptions.size),
+							success: res => {
+								callback.success(res);
+							},
+							fail: err => {
+								callback.fail(err);
+							},
+							complete: () => {
+								callback.complete();
+							}
+						},
+						this
+					);
+				}
+				// #endif
+				// #ifdef APP-NVUE
+				const dpr = uni.getSystemInfoSync().pixelRatio;
+				this.canvasContext.toTempFilePath(
+					0,
+					0,
+					this.templateOptions.canvasWidth * dpr,
+					this.templateOptions.canvasHeight * dpr,
+					this.templateOptions.size * dpr,
+					this.templateOptions.size * dpr,
+					'',
+					1,
+					res => {
+						callback.success(res);
+						callback.complete(res);
+					}
+				);
+				// #endif
+			},
+			/**
+			 * 淇濆瓨
+			 */
+			save(callback = {}) {
+				if (typeof callback.success != 'function') {
+					callback.success = () => {};
+				}
+				if (typeof callback.fail != 'function') {
+					callback.fail = () => {};
+				}
+				if (typeof callback.complete != 'function') {
+					callback.complete = () => {};
+				}
+
+				this.toTempFilePath({
+					success: res => {
+						// #ifndef H5
+						if (this.canvasType === '2d') {
+							// #ifdef MP-WEIXIN
+							/* 闇�瑕佸皢 data:image/png;base64, 杩欐鍘婚櫎 writeFile 鎵嶈兘姝e父鎵撳紑鏂囦欢锛屽惁鍒欐槸鎹熷潖鏂囦欢锛屾棤娉曟墦寮� */
+							const reg = new RegExp('^data:image/png;base64,', 'g');
+							const dataURL = res.tempFilePath.replace(reg, '');
+							const fs = wx.getFileSystemManager();
+							const tempFilePath = `${wx.env.USER_DATA_PATH}/${new Date().getTime()}${
+                Math.random()
+                  .toString()
+                  .split('.')[1]
+              }.png`;
+							fs.writeFile({
+								filePath: tempFilePath, // 瑕佸啓鍏ョ殑鏂囦欢璺緞 (鏈湴璺緞)
+								data: dataURL, // base64鍥剧墖
+								encoding: 'base64',
+								success: res1 => {
+									uni.saveImageToPhotosAlbum({
+										filePath: tempFilePath,
+										success: res2 => {
+											callback.success(res2);
+										},
+										fail: err2 => {
+											callback.fail(err2);
+										},
+										complete: () => {
+											callback.complete();
+										}
+									});
+								},
+								fail: err => {
+									callback.fail(err);
+								},
+								complete: () => {
+									callback.complete();
+								}
+							});
+							// #endif
+						} else {
+							uni.saveImageToPhotosAlbum({
+								filePath: res.tempFilePath,
+								success: res1 => {
+									callback.success(res1);
+								},
+								fail: err1 => {
+									callback.fail(err1);
+								},
+								complete: () => {
+									callback.complete();
+								}
+							});
+						}
+						// #endif
+
+						// #ifdef H5
+						/* 鍙互鍦ㄧ數鑴戞祻瑙堝櫒涓嬭浇锛岀Щ鍔ㄧiOS涓嶈锛屽畨鍗撳井淇℃祻瑙堝櫒涓嶈锛屽畨鍗撳閮ㄦ祻瑙堝櫒鍙互 */
+						this.isH5Save = this.h5SaveTip;
+						this.tempFilePath = res.tempFilePath;
+						if (this.h5SaveIsDownload) {
+							const aEle = document.createElement('a');
+							aEle.download = this.h5DownloadName; // 璁剧疆涓嬭浇鐨勬枃浠跺悕锛岄粯璁ゆ槸'涓嬭浇'
+							aEle.href = res.tempFilePath;
+							document.body.appendChild(aEle);
+							aEle.click();
+							aEle.remove(); // 涓嬭浇涔嬪悗鎶婂垱寤虹殑鍏冪礌鍒犻櫎
+						}
+						callback.success({
+							errMsg: 'ok'
+						});
+						callback.complete({
+							errMsg: 'ok'
+						});
+						// #endif
+					},
+					fail: err => {
+						callback.fail(err);
+						callback.complete(err);
+					}
+				});
+			},
+			/**
+			 * 娉ㄥ唽click浜嬩欢
+			 */
+			onClick(e) {
+				this.$emit('click', e);
+			},
+			/**
+			 * 鑾峰彇瀹炰緥
+			 */
+			getInstance() {
+				return instance;
+			},
+			/**
+			 * 娉ㄥ唽鎵╁睍锛岀粍浠朵粎鏀寔娉ㄥ唽type涓簊tyle鐨刣rawCanvas鎵╁睍
+			 * @param {Object} plugin
+			 */
+			registerStyle(plugin) {
+				if (plugin.Type != 'style') {
+					console.warn('[uQRCode]: registerStyle 浠呮敮鎸佹敞鍐� style 绫诲瀷鐨勬墿灞曪紒');
+					return {
+						errMsg: 'registerStyle 浠呮敮鎸佹敞鍐� style 绫诲瀷鐨勬墿灞曪紒'
+					};
+				}
+				if (typeof plugin === 'function') {
+					this.plugins.push({
+						plugin,
+						name: plugin.Name,
+						drawCanvas: plugin.DrawCanvas
+					});
+				}
+			},
+			getLoadImage(loadImage) {
+				var that = this;
+				if (typeof loadImage == 'function') {
+					return function(src) {
+						/* 鍒ゆ柇鏄惁鏄槦鍒楀姞杞藉浘鐗囩殑 */
+						if (that.isQueueLoadImage) {
+							/* 瑙e喅iOS APP||NVUE鍚屾椂缁樺埗澶氫釜浜岀淮鐮佸鑷村浘鐗囦涪澶遍渶浣跨敤闃熷垪 */
+							return queueLoadImage.exec(() => {
+								return new Promise((resolve, reject) => {
+									setTimeout(() => {
+										const cache = cacheImageList.find(x => x.src == src);
+										if (cache) {
+											resolve(cache.img);
+										} else {
+											loadImage(src)
+												.then(img => {
+													cacheImageList.push({
+														src,
+														img
+													});
+													resolve(img);
+												})
+												.catch(err => {
+													reject(err);
+												});
+										}
+									}, 10);
+								});
+							});
+						} else {
+							return loadImage(src);
+						}
+					};
+				} else {
+					return function(src) {
+						return Promise.resolve(src);
+					};
+				}
+			}
+		}
+	};
+
+	/**
+	 * 瀵硅薄灞炴�ф繁搴︽浛鎹�
+	 * @param {Object} o 鍘熷瀵硅薄/榛樿瀵硅薄/琚浛鎹㈢殑瀵硅薄
+	 * @param {Object} r 浠庤繖涓璞¢噷鍙栧�兼浛鎹㈠埌o瀵硅薄閲�
+	 * @return {Object} 鏇挎崲鍚庣殑鏂板璞�
+	 */
+	function deepReplace(o = {}, r = {}, c = false) {
+		let obj;
+		if (c) {
+			// 浠庢簮鏇挎崲
+			obj = o;
+		} else {
+			// 涓嶆浛鎹㈡簮锛宑opy涓�浠藉浠芥潵鏇挎崲
+			obj = {
+				...o
+			};
+		}
+		for (let k in r) {
+			var vr = r[k];
+			if (vr != undefined) {
+				if (vr.constructor == Object) {
+					obj[k] = this.deepReplace(obj[k], vr);
+				} else if (vr.constructor == String && !vr) {
+					obj[k] = obj[k];
+				} else {
+					obj[k] = vr;
+				}
+			}
+		}
+		return obj;
+	}
+</script>
+
+<style scoped>
+	.uqrcode {
+		position: relative;
+	}
+	.uqrcode-hide {
+		position: fixed;
+		left: 7500rpx;
+	}
+	.uqrcode-canvas {
+		transform-origin: top left;
+	}
+	.uqrcode-makeing {
+		position: absolute;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		z-index: 10;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+	}
+	.uqrcode-makeing-image {
+		/* #ifndef APP-NVUE */
+		display: block;
+		max-width: 120px;
+		max-height: 120px;
+		/* #endif */
+	}
+	.uqrcode-error {
+		position: absolute;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+	}
+	.uqrcode-error-message {
+		font-size: 12px;
+		color: #939291;
+	}
+	/* #ifdef H5 */
+	.uqrcode-h5-save {
+		position: fixed;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		z-index: 100;
+		background-color: rgba(0, 0, 0, 0.68);
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	}
+	.uqrcode-h5-save-image {
+		width: 512rpx;
+		height: 512rpx;
+		padding: 32rpx;
+	}
+	.uqrcode-h5-save-text {
+		margin-top: 20rpx;
+		font-size: 32rpx;
+		font-weight: 700;
+		color: #ffffff;
+	}
+	.uqrcode-h5-save-close {
+		position: relative;
+		margin-top: 72rpx;
+		width: 60rpx;
+		height: 60rpx;
+		border: 2rpx solid #ffffff;
+		border-radius: 60rpx;
+		padding: 10rpx;
+	}
+	.uqrcode-h5-save-close-before {
+		position: absolute;
+		top: 50%;
+		left: 50%;
+		transform: translate(-50%, -50%) rotate(45deg);
+		width: 40rpx;
+		height: 4rpx;
+		background: #ffffff;
+	}
+	.uqrcode-h5-save-close-after {
+		position: absolute;
+		top: 50%;
+		left: 50%;
+		transform: translate(-50%, -50%) rotate(-45deg);
+		width: 40rpx;
+		height: 4rpx;
+		background: #ffffff;
+	}
+	/* #endif */
+</style>
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/package.json b/uni_modules/uv-qrcode/package.json
new file mode 100644
index 0000000..c85e74f
--- /dev/null
+++ b/uni_modules/uv-qrcode/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uv-qrcode",
+  "displayName": "uv-qrcode 浜岀淮鐮� 鍏ㄩ潰鍏煎vue3+2銆乤pp銆乭5銆佸皬绋嬪簭绛夊绔�",
+  "version": "1.0.5",
+  "description": "璇ョ粍浠舵槸瓒呯骇寮哄ぇ浜岀淮鐮佺敓鎴愬姛鑳斤紝鍙墿灞曟�ч珮銆傝嚜瀹氫箟浜岀淮鐮佹牱寮忥紝濡傞殢鏈洪鑹层�佸渾鐐广�佹柟鍧椼�佸潡涓庡潡涔嬮棿鐨勯棿璺濈瓑绛夛紝鍏蜂綋璇锋煡鐪嬫枃妗c��",
+  "keywords": [
+    "uv-qrcode",
+    "qrcode",
+    "uvui",
+    "uv-ui",
+    "浜岀淮鐮�"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "type": "component-vue",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+    	"ads": "鏃�",
+    	"data": "鎻掍欢涓嶉噰闆嗕换浣曟暟鎹�",
+    	"permissions": "鏃�"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uv-ui-tools"
+		],
+    "encrypt": [],
+    "platforms": {
+			"cloud": {
+				"tcb": "y",
+				"aliyun": "y"
+			},
+			"client": {
+				"Vue": {
+					"vue2": "y",
+					"vue3": "y"
+				},
+				"App": {
+					"app-vue": "y",
+					"app-nvue": "y"
+				},
+				"H5-mobile": {
+					"Safari": "y",
+					"Android Browser": "y",
+					"寰俊娴忚鍣�(Android)": "y",
+					"QQ娴忚鍣�(Android)": "y"
+				},
+				"H5-pc": {
+					"Chrome": "y",
+					"IE": "y",
+					"Edge": "y",
+					"Firefox": "y",
+					"Safari": "y"
+				},
+				"灏忕▼搴�": {
+					"寰俊": "y",
+					"闃块噷": "y",
+					"鐧惧害": "y",
+					"瀛楄妭璺冲姩": "y",
+					"QQ": "y",
+					"閽夐拤": "u",
+					"蹇墜": "u",
+					"椋炰功": "u",
+					"浜笢": "u"
+				},
+				"蹇簲鐢�": {
+					"鍗庝负": "u",
+					"鑱旂洘": "u"
+				}
+			}
+		}
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-qrcode/readme.md b/uni_modules/uv-qrcode/readme.md
new file mode 100644
index 0000000..fd4acfe
--- /dev/null
+++ b/uni_modules/uv-qrcode/readme.md
@@ -0,0 +1,21 @@
+## QRCode 浜岀淮鐮佺敓鎴愬櫒
+
+> **缁勪欢鍚嶏細uv-qrcode**
+
+瓒呯骇寮哄ぇ浜岀淮鐮佺敓鎴愮粍浠讹紝鍙墿灞曟�ч珮銆傝嚜瀹氫箟浜岀淮鐮佹牱寮忥紝濡傞殢鏈洪鑹层�佸渾鐐广�佹柟鍧椼�佸潡涓庡潡涔嬮棿鐨勯棿璺濈瓑绛夛紝鍏蜂綋璇峰湪涓嬫柟鏌ョ湅鏂囨。銆�
+
+鐏垫椿閰嶇疆锛屽紑绠卞嵆鐢紝鏂囨。鍏ㄩ潰锛屾敮鎸佽嚜瀹氫箟浜岀淮鐮侀鏍笺��
+
+# <a href="https://www.uvui.cn/components/qrcode.html" target="_blank">鏌ョ湅鏂囨。</a>
+
+## [涓嬭浇瀹屾暣绀轰緥椤圭洰](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small style="font-size:14px;font-weight:700;">锛堣涓嶈 涓嬭浇鎻掍欢ZIP锛�</small>
+
+### [鏇村鎻掍欢锛岃鍏虫敞uv-ui缁勪欢搴揮(https://ext.dcloud.net.cn/plugin?name=uv-ui)
+
+<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
+
+![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png)
+
+</a>
+
+#### 濡備娇鐢ㄨ繃绋嬩腑鏈変换浣曢棶棰樺弽棣堬紝鎴栬�呮偍瀵箄v-ui鏈変竴浜涘ソ鐨勫缓璁紝娆㈣繋鍔犲叆uv-ui瀹樻柟浜ゆ祦缇わ細<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">瀹樻柟QQ缇�</a>
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/changelog.md b/uni_modules/uv-ui-tools/changelog.md
new file mode 100644
index 0000000..998373e
--- /dev/null
+++ b/uni_modules/uv-ui-tools/changelog.md
@@ -0,0 +1,76 @@
+## 1.1.25锛�2024-01-20锛�
+1.1.20鐗堟湰鏇存柊
+## 1.1.24锛�2023-12-21锛�
+1. luch-request鏇存柊
+## 1.1.23锛�2023-12-12锛�
+1. 1.1.19鐗堟湰
+## 1.1.22锛�2023-11-28锛�
+1. 浼樺寲
+## 1.1.21锛�2023-11-10锛�
+1. 1.1.17鐗堟湰
+## 1.1.20锛�2023-10-30锛�
+1. 1.1.16鐗堟湰
+## 1.1.19锛�2023-10-13锛�
+1. 鍏煎vue3
+## 1.1.18锛�2023-10-12锛�
+1. 1.1.15鐗堟湰
+## 1.1.17锛�2023-09-27锛�
+1. 1.1.14鐗堟湰鍙戝竷
+## 1.1.16锛�2023-09-15锛�
+1. 1.1.13鐗堟湰鍙戝竷
+## 1.1.15锛�2023-09-15锛�
+1. 鏇存柊button.js鐩稿叧鎸夐挳鏀寔open-type="agreePrivacyAuthorization"
+## 1.1.14锛�2023-09-14锛�
+1. 浼樺寲dayjs
+## 1.1.13锛�2023-09-13锛�
+1. 浼樺寲锛�$uv涓鍔爑nit鍙傛暟锛屾柟渚跨粍浠朵腑浣跨敤
+## 1.1.12锛�2023-09-10锛�
+1. 鍗囩骇鐗堟湰
+## 1.1.11锛�2023-09-04锛�
+1. 1.1.11鐗堟湰
+## 1.1.10锛�2023-08-31锛�
+1. 淇customStyle鍜宑ustomClass瀛樺湪鍐茬獊鐨勯棶棰�
+## 1.1.9锛�2023-08-27锛�
+1. 鐗堟湰鍗囩骇
+2. 浼樺寲
+## 1.1.8锛�2023-08-24锛�
+1. 鐗堟湰鍗囩骇
+## 1.1.7锛�2023-08-22锛�
+1. 鐗堟湰鍗囩骇
+## 1.1.6锛�2023-08-18锛�
+uvui鐗堟湰锛�1.1.6
+## 1.0.15锛�2023-08-14锛�
+1. 鏇存柊uvui鐗堟湰鍙�
+## 1.0.13锛�2023-08-06锛�
+1. 浼樺寲
+## 1.0.12锛�2023-08-06锛�
+1. 淇敼鐗堟湰鍙�
+## 1.0.11锛�2023-08-06锛�
+1. 璺敱澧炲姞events鍙傛暟
+2. 璺敱鎷︽埅淇
+## 1.0.10锛�2023-08-01锛�
+1. 浼樺寲
+## 1.0.9锛�2023-06-28锛�
+浼樺寲openType.js
+## 1.0.8锛�2023-06-15锛�
+1. 淇敼鏀粯瀹濇姤閿欑殑BUG
+## 1.0.7锛�2023-06-07锛�
+1. 瑙e喅寰俊灏忕▼搴忎娇鐢╱vui鎻愮ず Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors
+2. 瑙e喅涓婅堪鎻愮ず锛岄渶瑕佸湪uni.scss閰嶇疆$uvui-nvue-style: false; 鐒跺悗鍦ˋPP.vue涓嬮潰寮曞叆uvui鍐呯疆鐨勫熀纭�鏍峰紡:@import '@/uni_modules/uv-ui-tools/index.scss';
+## 1.0.6锛�2023-06-04锛�
+1.  uv-ui-tools 浼樺寲宸ュ叿缁勪欢锛屽吋瀹规洿澶氬姛鑳�
+2.  灏忕▼搴忓垎浜姛鑳戒紭鍖栫瓑
+## 1.0.5锛�2023-06-02锛�
+1. 淇敼鎵╁睍浣跨敤mixin涓柟娉曠殑闂
+## 1.0.4锛�2023-05-23锛�
+1. 鍏煎鐧惧害灏忕▼搴忎慨鏀筨em鍑芥暟
+## 1.0.3锛�2023-05-16锛�
+1. 浼樺寲缁勪欢渚濊禆锛屼慨鏀瑰悗鏃犻渶鍏ㄥ眬寮曞叆锛岀粍浠跺鍏ュ嵆鍙娇鐢�
+2. 浼樺寲閮ㄥ垎鍔熻兘
+## 1.0.2锛�2023-05-10锛�
+1. 澧炲姞Http璇锋眰灏佽
+2. 浼樺寲
+## 1.0.1锛�2023-05-04锛�
+1. 淇敼鍚嶇О鍙婂娉�
+## 1.0.0锛�2023-05-04锛�
+1. uv-ui宸ュ叿闆嗛娆″彂甯�
diff --git a/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue b/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue
new file mode 100644
index 0000000..baf45e9
--- /dev/null
+++ b/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue
@@ -0,0 +1,6 @@
+<template>
+</template>
+<script>
+</script>
+<style>
+</style>
diff --git a/uni_modules/uv-ui-tools/index.js b/uni_modules/uv-ui-tools/index.js
new file mode 100644
index 0000000..71a8b66
--- /dev/null
+++ b/uni_modules/uv-ui-tools/index.js
@@ -0,0 +1,79 @@
+// 鍏ㄥ眬鎸傝浇寮曞叆http鐩稿叧璇锋眰鎷︽埅鎻掍欢
+import Request from './libs/luch-request'
+
+// 寮曞叆鍏ㄥ眬mixin
+import mixin from './libs/mixin/mixin.js'
+// 灏忕▼搴忕壒鏈夌殑mixin
+import mpMixin from './libs/mixin/mpMixin.js'
+// #ifdef MP
+import mpShare from './libs/mixin/mpShare.js'
+// #endif
+
+// 璺敱灏佽
+import route from './libs/util/route.js'
+// 鍏叡宸ュ叿鍑芥暟
+import * as index from './libs/function/index.js'
+// 闃叉姈鏂规硶
+import debounce from './libs/function/debounce.js'
+// 鑺傛祦鏂规硶
+import throttle from './libs/function/throttle.js'
+// 瑙勫垯妫�楠�
+import * as test from './libs/function/test.js'
+
+// 棰滆壊娓愬彉鐩稿叧,colorGradient-棰滆壊娓愬彉,hexToRgb-鍗佸叚杩涘埗棰滆壊杞瑀gb棰滆壊,rgbToHex-rgb杞崄鍏繘鍒�
+import * as colorGradient from './libs/function/colorGradient.js'
+
+// 閰嶇疆淇℃伅
+import config from './libs/config/config.js'
+// 骞冲彴
+import platform from './libs/function/platform'
+
+const $uv = {
+	route,
+	config,
+	test,
+	date: index.timeFormat, // 鍙﹀悕date
+	...index,
+	colorGradient: colorGradient.colorGradient,
+	hexToRgb: colorGradient.hexToRgb,
+	rgbToHex: colorGradient.rgbToHex,
+	colorToRgba: colorGradient.colorToRgba,
+	http: new Request(),
+	debounce,
+	throttle,
+	platform,
+	mixin,
+	mpMixin
+}
+uni.$uv = $uv;
+const install = (Vue,options={}) => {
+		// #ifndef APP-NVUE
+		const cloneMixin = index.deepClone(mixin);
+		delete cloneMixin?.props?.customClass;
+		delete cloneMixin?.props?.customStyle;
+		Vue.mixin(cloneMixin);
+		// #ifdef MP
+		if(options.mpShare){
+			Vue.mixin(mpShare);
+		}
+		// #endif
+		// #endif
+		// #ifdef VUE2
+		// 鏃堕棿鏍煎紡鍖栵紝鍚屾椂涓や釜鍚嶇О锛宒ate鍜宼imeFormat
+		Vue.filter('timeFormat', (timestamp, format) => uni.$uv.timeFormat(timestamp, format));
+		Vue.filter('date', (timestamp, format) => uni.$uv.timeFormat(timestamp, format));
+		// 灏嗗涔呬互鍓嶇殑鏂规硶锛屾敞鍏ュ埌鍏ㄥ眬杩囨护鍣�
+		Vue.filter('timeFrom', (timestamp, format) => uni.$uv.timeFrom(timestamp, format));
+		// 鍚屾椂鎸傝浇鍒皍ni鍜孷ue.prototype涓�
+		// #ifndef APP-NVUE
+		// 鍙湁vue锛屾寕杞藉埌Vue.prototype鎵嶆湁鎰忎箟锛屽洜涓簄vue涓叏灞�Vue.prototype鍜孷ue.mixin鏄棤鏁堢殑
+		Vue.prototype.$uv = $uv;
+		// #endif
+		// #endif
+		// #ifdef VUE3
+		Vue.config.globalProperties.$uv = $uv;
+		// #endif
+}
+export default {
+	install
+}
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/index.scss b/uni_modules/uv-ui-tools/index.scss
new file mode 100644
index 0000000..8d05b8d
--- /dev/null
+++ b/uni_modules/uv-ui-tools/index.scss
@@ -0,0 +1,7 @@
+// 寮曞叆鍏叡鍩虹绫�
+@import "./libs/css/common.scss";
+
+// 闈瀗vue鐨勬牱寮�
+/* #ifndef APP-NVUE */
+@import "./libs/css/vue.scss";
+/* #endif */
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/libs/config/config.js b/uni_modules/uv-ui-tools/libs/config/config.js
new file mode 100644
index 0000000..f18ae74
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/config/config.js
@@ -0,0 +1,34 @@
+// 姝ょ増鏈彂甯冧簬2024-01-20
+const version = '1.1.20'
+
+// 寮�鍙戠幆澧冩墠鎻愮ず锛岀敓浜х幆澧冧笉浼氭彁绀�
+if (process.env.NODE_ENV === 'development') {
+	console.log(`\n %c uvui V${version} https://www.uvui.cn/ \n\n`, 'color: #ffffff; background: #3c9cff; padding:5px 0; border-radius: 5px;');
+}
+
+export default {
+    v: version,
+    version,
+    // 涓婚鍚嶇О
+    type: [
+        'primary',
+        'success',
+        'info',
+        'error',
+        'warning'
+    ],
+    // 棰滆壊閮ㄥ垎锛屾湰鏉ュ彲浠ラ�氳繃scss鐨�:export瀵煎嚭渚沯s浣跨敤锛屼絾鏄浣昻vue涓嶆敮鎸�
+    color: {
+        'uv-primary': '#2979ff',
+        'uv-warning': '#ff9900',
+        'uv-success': '#19be6b',
+        'uv-error': '#fa3534',
+        'uv-info': '#909399',
+        'uv-main-color': '#303133',
+        'uv-content-color': '#606266',
+        'uv-tips-color': '#909399',
+        'uv-light-color': '#c0c4cc'
+    },
+	// 榛樿鍗曚綅锛屽彲浠ラ�氳繃閰嶇疆涓簉px锛岄偅涔堝湪鐢ㄤ簬浼犲叆缁勪欢澶у皬鍙傛暟涓烘暟鍊兼椂锛屽氨榛樿涓簉px
+	unit: 'px'
+}
diff --git a/uni_modules/uv-ui-tools/libs/css/color.scss b/uni_modules/uv-ui-tools/libs/css/color.scss
new file mode 100644
index 0000000..ce65743
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/css/color.scss
@@ -0,0 +1,32 @@
+$uv-main-color: #303133 !default;
+$uv-content-color: #606266 !default;
+$uv-tips-color: #909193 !default;
+$uv-light-color: #c0c4cc !default;
+$uv-border-color: #dadbde !default;
+$uv-bg-color: #f3f4f6 !default;
+$uv-disabled-color: #c8c9cc !default;
+
+$uv-primary: #3c9cff !default;
+$uv-primary-dark: #398ade !default;
+$uv-primary-disabled: #9acafc !default;
+$uv-primary-light: #ecf5ff !default;
+
+$uv-warning: #f9ae3d !default;
+$uv-warning-dark: #f1a532 !default;
+$uv-warning-disabled: #f9d39b !default;
+$uv-warning-light: #fdf6ec !default;
+
+$uv-success: #5ac725 !default;
+$uv-success-dark: #53c21d !default;
+$uv-success-disabled: #a9e08f !default;
+$uv-success-light: #f5fff0;
+
+$uv-error: #f56c6c !default;
+$uv-error-dark: #e45656 !default;
+$uv-error-disabled: #f7b2b2 !default;
+$uv-error-light: #fef0f0 !default;
+
+$uv-info: #909399 !default;
+$uv-info-dark: #767a82 !default;
+$uv-info-disabled: #c4c6c9 !default;
+$uv-info-light: #f4f4f5 !default;
diff --git a/uni_modules/uv-ui-tools/libs/css/common.scss b/uni_modules/uv-ui-tools/libs/css/common.scss
new file mode 100644
index 0000000..7ab99f8
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/css/common.scss
@@ -0,0 +1,100 @@
+// 瓒呭嚭琛屾暟锛岃嚜鍔ㄦ樉绀鸿灏剧渷鐣ュ彿锛屾渶澶�5琛�
+// 鏉ヨ嚜uvui鐨勬俯棣ㄦ彁绀猴細褰撴偍鍦ㄦ帶鍒跺彴鐪嬪埌姝ゆ姤閿欙紝璇存槑闇�瑕佸湪App.vue鐨剆tyle鏍囩鍔犱笂銆恖ang="scss"銆�
+@for $i from 1 through 5 {
+	.uv-line-#{$i} {
+		/* #ifdef APP-NVUE */
+		// nvue涓嬶紝鍙互鐩存帴浣跨敤lines灞炴�э紝杩欐槸weex鐗规湁鏍峰紡
+		lines: $i;
+		text-overflow: ellipsis;
+		overflow: hidden;
+		flex: 1;
+		/* #endif */
+
+		/* #ifndef APP-NVUE */
+		// vue涓嬶紝鍗曡鍜屽琛屾樉绀虹渷鐣ュ彿闇�瑕佸崟鐙鐞�
+		@if $i == '1' {
+			overflow: hidden;
+			white-space: nowrap;
+			text-overflow: ellipsis;
+		} @else {
+			display: -webkit-box!important;
+			overflow: hidden;
+			text-overflow: ellipsis;
+			word-break: break-all;
+			-webkit-line-clamp: $i;
+			-webkit-box-orient: vertical!important;
+		}
+		/* #endif */
+	}
+}
+$uv-bordercolor: #dadbde;
+@if variable-exists(uv-border-color) {
+	$uv-bordercolor: $uv-border-color;
+}
+
+// 姝ゅ鍔犱笂!important骞堕潪闅忔剰涔辩敤锛岃�屾槸鍥犱负鐩墠*.nvue椤甸潰缂栬瘧鍒癏5鏃讹紝
+// App.vue鐨勬牱寮忎細琚玼ni-app鐨剉iew鍏冪礌鐨勮嚜甯order灞炴�ц鐩栵紝瀵艰嚧鏃犳晥
+// 缁间笂锛岃繖鏄痷ni-app鐨勭己闄峰鑷存垜浠负浜嗗绔吋瀹癸紝鑰屽繀椤昏鍔犱笂!important
+// 绉诲姩绔吋瀹规�ц緝濂斤紝鐩存帴浣跨敤0.5px鍘诲疄鐜扮粏杈规锛屼笉浣跨敤浼厓绱犲舰寮忓疄鐜�
+.uv-border {
+	border-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-style: solid;
+}
+
+.uv-border-top {
+	border-top-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-top-style: solid;
+}
+
+.uv-border-left {
+	border-left-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-left-style: solid;
+}
+
+.uv-border-right {
+	border-right-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-right-style: solid;
+}
+
+.uv-border-bottom {
+	border-bottom-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-bottom-style: solid;
+}
+
+.uv-border-top-bottom {
+	border-top-width: 0.5px!important;
+	border-bottom-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-top-style: solid;
+    border-bottom-style: solid;
+}
+
+// 鍘婚櫎button鐨勬墍鏈夐粯璁ゆ牱寮忥紝璁╁叾琛ㄧ幇璺熸櫘閫氱殑view銆乼ext鍏冪礌涓�鏍�
+.uv-reset-button {
+	padding: 0;
+	background-color: transparent;
+	/* #ifndef APP-PLUS */
+	font-size: inherit;
+	line-height: inherit;
+	color: inherit;
+	/* #endif */
+	/* #ifdef APP-NVUE */
+	border-width: 0;
+	/* #endif */
+}
+
+/* #ifndef APP-NVUE */
+.uv-reset-button::after {
+   border: none;
+}
+/* #endif */
+
+.uv-hover-class {
+	opacity: 0.7;
+}
+
diff --git a/uni_modules/uv-ui-tools/libs/css/components.scss b/uni_modules/uv-ui-tools/libs/css/components.scss
new file mode 100644
index 0000000..81ce15d
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/css/components.scss
@@ -0,0 +1,23 @@
+@mixin flex($direction: row) {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: $direction;
+}
+
+/* #ifndef APP-NVUE */
+// 鐢变簬uvui鏄熀浜巒vue鐜杩涜寮�鍙戠殑锛屾鐜涓櫘閫氬厓绱犻粯璁や负flex-direction: column;
+// 鎵�浠ュ湪闈瀗vue涓紝闇�瑕佸鍏冪礌杩涜閲嶇疆涓篺lex-direction: column; 鍚﹀垯鍙兘浼氳〃鐜板紓甯�
+$uvui-nvue-style: true !default;
+@if $uvui-nvue-style == true {
+	view, scroll-view, swiper-item {
+		display: flex;
+		flex-direction: column;
+		flex-shrink: 0;
+		flex-grow: 0;
+		flex-basis: auto;
+		align-items: stretch;
+		align-content: flex-start;
+	}
+}
+/* #endif */
diff --git a/uni_modules/uv-ui-tools/libs/css/variable.scss b/uni_modules/uv-ui-tools/libs/css/variable.scss
new file mode 100644
index 0000000..63903c9
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/css/variable.scss
@@ -0,0 +1,111 @@
+// 瓒呭嚭琛屾暟锛岃嚜鍔ㄦ樉绀鸿灏剧渷鐣ュ彿锛屾渶澶�5琛�
+// 鏉ヨ嚜uvui鐨勬俯棣ㄦ彁绀猴細褰撴偍鍦ㄦ帶鍒跺彴鐪嬪埌姝ゆ姤閿欙紝璇存槑闇�瑕佸湪App.vue鐨剆tyle鏍囩鍔犱笂銆恖ang="scss"銆�
+@if variable-exists(show-lines) {
+	@for $i from 1 through 5 {
+		.uv-line-#{$i} {
+			/* #ifdef APP-NVUE */
+			// nvue涓嬶紝鍙互鐩存帴浣跨敤lines灞炴�э紝杩欐槸weex鐗规湁鏍峰紡
+			lines: $i;
+			text-overflow: ellipsis;
+			overflow: hidden;
+			flex: 1;
+			/* #endif */
+
+			/* #ifndef APP-NVUE */
+			// vue涓嬶紝鍗曡鍜屽琛屾樉绀虹渷鐣ュ彿闇�瑕佸崟鐙鐞�
+			@if $i == '1' {
+				overflow: hidden;
+				white-space: nowrap;
+				text-overflow: ellipsis;
+			} @else {
+				display: -webkit-box!important;
+				overflow: hidden;
+				text-overflow: ellipsis;
+				word-break: break-all;
+				-webkit-line-clamp: $i;
+				-webkit-box-orient: vertical!important;
+			}
+			/* #endif */
+		}
+	}
+}
+@if variable-exists(show-border) {
+	$uv-bordercolor: #dadbde;
+	@if variable-exists(uv-border-color) {
+		$uv-bordercolor: $uv-border-color;
+	}
+	// 姝ゅ鍔犱笂!important骞堕潪闅忔剰涔辩敤锛岃�屾槸鍥犱负鐩墠*.nvue椤甸潰缂栬瘧鍒癏5鏃讹紝
+	// App.vue鐨勬牱寮忎細琚玼ni-app鐨剉iew鍏冪礌鐨勮嚜甯order灞炴�ц鐩栵紝瀵艰嚧鏃犳晥
+	// 缁间笂锛岃繖鏄痷ni-app鐨勭己闄峰鑷存垜浠负浜嗗绔吋瀹癸紝鑰屽繀椤昏鍔犱笂!important
+	// 绉诲姩绔吋瀹规�ц緝濂斤紝鐩存帴浣跨敤0.5px鍘诲疄鐜扮粏杈规锛屼笉浣跨敤浼厓绱犲舰寮忓疄鐜�
+	@if variable-exists(show-border-surround) {
+		.uv-border {
+			border-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-style: solid;
+		}
+	}
+	@if variable-exists(show-border-top) {
+		.uv-border-top {
+			border-top-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-top-style: solid;
+		}
+	}
+	@if variable-exists(show-border-left) {
+		.uv-border-left {
+			border-left-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-left-style: solid;
+		}
+	}
+	@if variable-exists(show-border-right) {
+		.uv-border-right {
+			border-right-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-right-style: solid;
+		}
+	}
+	@if variable-exists(show-border-bottom) {
+		.uv-border-bottom {
+			border-bottom-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+				border-bottom-style: solid;
+		}
+	}
+	@if variable-exists(show-border-top-bottom) {
+		.uv-border-top-bottom {
+			border-top-width: 0.5px!important;
+			border-bottom-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-top-style: solid;
+			border-bottom-style: solid;
+		}
+	}
+}
+@if variable-exists(show-reset-button) {
+	// 鍘婚櫎button鐨勬墍鏈夐粯璁ゆ牱寮忥紝璁╁叾琛ㄧ幇璺熸櫘閫氱殑view銆乼ext鍏冪礌涓�鏍�
+	.uv-reset-button {
+		padding: 0;
+		background-color: transparent;
+		/* #ifndef APP-PLUS */
+		font-size: inherit;
+		line-height: inherit;
+		color: inherit;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		border-width: 0;
+		/* #endif */
+	}
+
+	/* #ifndef APP-NVUE */
+	.uv-reset-button::after {
+		 border: none;
+	}
+	/* #endif */
+}
+@if variable-exists(show-hover) {
+	.uv-hover-class {
+		opacity: 0.7;
+	}
+}
diff --git a/uni_modules/uv-ui-tools/libs/css/vue.scss b/uni_modules/uv-ui-tools/libs/css/vue.scss
new file mode 100644
index 0000000..bdbefdd
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/css/vue.scss
@@ -0,0 +1,40 @@
+// 鍘嗛亶鐢熸垚4涓柟鍚戠殑搴曢儴瀹夊叏鍖�
+@each $d in top, right, bottom, left {
+	.uv-safe-area-inset-#{$d} {
+		padding-#{$d}: 0;
+		padding-#{$d}: constant(safe-area-inset-#{$d});  
+		padding-#{$d}: env(safe-area-inset-#{$d});  
+	}
+}
+
+//鎻愬崌H5绔痷ni.toast()鐨勫眰绾э紝閬垮厤琚玼vui鐨刴odal绛夐伄鐩�
+/* #ifdef H5 */
+uni-toast {
+    z-index: 10090;
+}
+uni-toast .uni-toast {
+   z-index: 10090;
+}
+/* #endif */
+
+// 闅愯棌scroll-view鐨勬粴鍔ㄦ潯
+::-webkit-scrollbar {
+    display: none;  
+    width: 0 !important;  
+    height: 0 !important;  
+    -webkit-appearance: none;  
+    background: transparent;  
+}
+
+$uvui-nvue-style: true !default;
+@if $uvui-nvue-style == false {
+	view, scroll-view, swiper-item {
+		display: flex;
+		flex-direction: column;
+		flex-shrink: 0;
+		flex-grow: 0;
+		flex-basis: auto;
+		align-items: stretch;
+		align-content: flex-start;
+	}
+}
diff --git a/uni_modules/uv-ui-tools/libs/function/colorGradient.js b/uni_modules/uv-ui-tools/libs/function/colorGradient.js
new file mode 100644
index 0000000..55c188f
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/function/colorGradient.js
@@ -0,0 +1,134 @@
+/**
+ * 姹備袱涓鑹蹭箣闂寸殑娓愬彉鍊�
+ * @param {string} startColor 寮�濮嬬殑棰滆壊
+ * @param {string} endColor 缁撴潫鐨勯鑹�
+ * @param {number} step 棰滆壊绛夊垎鐨勪唤棰�
+ * */
+function colorGradient(startColor = 'rgb(0, 0, 0)', endColor = 'rgb(255, 255, 255)', step = 10) {
+    const startRGB = hexToRgb(startColor, false) // 杞崲涓簉gb鏁扮粍妯″紡
+    const startR = startRGB[0]
+    const startG = startRGB[1]
+    const startB = startRGB[2]
+
+    const endRGB = hexToRgb(endColor, false)
+    const endR = endRGB[0]
+    const endG = endRGB[1]
+    const endB = endRGB[2]
+
+    const sR = (endR - startR) / step // 鎬诲樊鍊�
+    const sG = (endG - startG) / step
+    const sB = (endB - startB) / step
+    const colorArr = []
+    for (let i = 0; i < step; i++) {
+        // 璁$畻姣忎竴姝ョ殑hex鍊�
+        let hex = rgbToHex(`rgb(${Math.round((sR * i + startR))},${Math.round((sG * i + startG))},${Math.round((sB
+			* i + startB))})`)
+        // 纭繚绗竴涓鑹插�间负startColor鐨勫��
+        if (i === 0) hex = rgbToHex(startColor)
+        // 纭繚鏈�鍚庝竴涓鑹插�间负endColor鐨勫��
+        if (i === step - 1) hex = rgbToHex(endColor)
+        colorArr.push(hex)
+    }
+    return colorArr
+}
+
+// 灏唄ex琛ㄧず鏂瑰紡杞崲涓簉gb琛ㄧず鏂瑰紡(杩欓噷杩斿洖rgb鏁扮粍妯″紡)
+function hexToRgb(sColor, str = true) {
+    const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
+    sColor = String(sColor).toLowerCase()
+    if (sColor && reg.test(sColor)) {
+        if (sColor.length === 4) {
+            let sColorNew = '#'
+            for (let i = 1; i < 4; i += 1) {
+                sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
+            }
+            sColor = sColorNew
+        }
+        // 澶勭悊鍏綅鐨勯鑹插��
+        const sColorChange = []
+        for (let i = 1; i < 7; i += 2) {
+            sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
+        }
+        if (!str) {
+            return sColorChange
+        }
+        return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})`
+    } if (/^(rgb|RGB)/.test(sColor)) {
+        const arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
+        return arr.map((val) => Number(val))
+    }
+    return sColor
+}
+
+// 灏唕gb琛ㄧず鏂瑰紡杞崲涓篽ex琛ㄧず鏂瑰紡
+function rgbToHex(rgb) {
+    const _this = rgb
+    const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
+    if (/^(rgb|RGB)/.test(_this)) {
+        const aColor = _this.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
+        let strHex = '#'
+        for (let i = 0; i < aColor.length; i++) {
+            let hex = Number(aColor[i]).toString(16)
+            hex = String(hex).length == 1 ? `${0}${hex}` : hex // 淇濊瘉姣忎釜rgb鐨勫�间负2浣�
+            if (hex === '0') {
+                hex += hex
+            }
+            strHex += hex
+        }
+        if (strHex.length !== 7) {
+            strHex = _this
+        }
+        return strHex
+    } if (reg.test(_this)) {
+        const aNum = _this.replace(/#/, '').split('')
+        if (aNum.length === 6) {
+            return _this
+        } if (aNum.length === 3) {
+            let numHex = '#'
+            for (let i = 0; i < aNum.length; i += 1) {
+                numHex += (aNum[i] + aNum[i])
+            }
+            return numHex
+        }
+    } else {
+        return _this
+    }
+}
+
+/**
+* JS棰滆壊鍗佸叚杩涘埗杞崲涓簉gb鎴杛gba,杩斿洖鐨勬牸寮忎负 rgba锛�255锛�255锛�255锛�0.5锛夊瓧绗︿覆
+* sHex涓轰紶鍏ョ殑鍗佸叚杩涘埗鐨勮壊鍊�
+* alpha涓簉gba鐨勯�忔槑搴�
+*/
+function colorToRgba(color, alpha) {
+    color = rgbToHex(color)
+    // 鍗佸叚杩涘埗棰滆壊鍊肩殑姝e垯琛ㄨ揪寮�
+    const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
+    /* 16杩涘埗棰滆壊杞负RGB鏍煎紡 */
+    let sColor = String(color).toLowerCase()
+    if (sColor && reg.test(sColor)) {
+        if (sColor.length === 4) {
+            let sColorNew = '#'
+            for (let i = 1; i < 4; i += 1) {
+                sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
+            }
+            sColor = sColorNew
+        }
+        // 澶勭悊鍏綅鐨勯鑹插��
+        const sColorChange = []
+        for (let i = 1; i < 7; i += 2) {
+            sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
+        }
+        // return sColorChange.join(',')
+        return `rgba(${sColorChange.join(',')},${alpha})`
+    }
+
+    return sColor
+}
+
+export {
+    colorGradient,
+    hexToRgb,
+    rgbToHex,
+    colorToRgba
+}
diff --git a/uni_modules/uv-ui-tools/libs/function/debounce.js b/uni_modules/uv-ui-tools/libs/function/debounce.js
new file mode 100644
index 0000000..ad3996b
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/function/debounce.js
@@ -0,0 +1,29 @@
+let timeout = null
+
+/**
+ * 闃叉姈鍘熺悊锛氫竴瀹氭椂闂村唴锛屽彧鏈夋渶鍚庝竴娆℃搷浣滐紝鍐嶈繃wait姣鍚庢墠鎵ц鍑芥暟
+ *
+ * @param {Function} func 瑕佹墽琛岀殑鍥炶皟鍑芥暟
+ * @param {Number} wait 寤舵椂鐨勬椂闂�
+ * @param {Boolean} immediate 鏄惁绔嬪嵆鎵ц
+ * @return null
+ */
+function debounce(func, wait = 500, immediate = false) {
+    // 娓呴櫎瀹氭椂鍣�
+    if (timeout !== null) clearTimeout(timeout)
+    // 绔嬪嵆鎵ц锛屾绫绘儏鍐典竴鑸敤涓嶅埌
+    if (immediate) {
+        const callNow = !timeout
+        timeout = setTimeout(() => {
+            timeout = null
+        }, wait)
+        if (callNow) typeof func === 'function' && func()
+    } else {
+        // 璁剧疆瀹氭椂鍣紝褰撴渶鍚庝竴娆℃搷浣滃悗锛宼imeout涓嶄細鍐嶈娓呴櫎锛屾墍浠ュ湪寤舵椂wait姣鍚庢墽琛宖unc鍥炶皟鏂规硶
+        timeout = setTimeout(() => {
+            typeof func === 'function' && func()
+        }, wait)
+    }
+}
+
+export default debounce
diff --git a/uni_modules/uv-ui-tools/libs/function/digit.js b/uni_modules/uv-ui-tools/libs/function/digit.js
new file mode 100644
index 0000000..c8260a0
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/function/digit.js
@@ -0,0 +1,167 @@
+let _boundaryCheckingState = true; // 鏄惁杩涜瓒婄晫妫�鏌ョ殑鍏ㄥ眬寮�鍏�
+
+/**
+ * 鎶婇敊璇殑鏁版嵁杞
+ * @private
+ * @example strip(0.09999999999999998)=0.1
+ */
+function strip(num, precision = 15) {
+  return +parseFloat(Number(num).toPrecision(precision));
+}
+
+/**
+ * Return digits length of a number
+ * @private
+ * @param {*number} num Input number
+ */
+function digitLength(num) {
+  // Get digit length of e
+  const eSplit = num.toString().split(/[eE]/);
+  const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
+  return len > 0 ? len : 0;
+}
+
+/**
+ * 鎶婂皬鏁拌浆鎴愭暣鏁�,濡傛灉鏄皬鏁板垯鏀惧ぇ鎴愭暣鏁�
+ * @private
+ * @param {*number} num 杈撳叆鏁�
+ */
+function float2Fixed(num) {
+  if (num.toString().indexOf('e') === -1) {
+    return Number(num.toString().replace('.', ''));
+  }
+  const dLen = digitLength(num);
+  return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);
+}
+
+/**
+ * 妫�娴嬫暟瀛楁槸鍚﹁秺鐣岋紝濡傛灉瓒婄晫缁欏嚭鎻愮ず
+ * @private
+ * @param {*number} num 杈撳叆鏁�
+ */
+function checkBoundary(num) {
+  if (_boundaryCheckingState) {
+    if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
+      console.warn(`${num} 瓒呭嚭浜嗙簿搴﹂檺鍒讹紝缁撴灉鍙兘涓嶆纭甡);
+    }
+  }
+}
+
+/**
+ * 鎶婇�掑綊鎿嶄綔鎵佸钩杩唬鍖�
+ * @param {number[]} arr 瑕佹搷浣滅殑鏁板瓧鏁扮粍
+ * @param {function} operation 杩唬鎿嶄綔
+ * @private
+ */
+function iteratorOperation(arr, operation) {
+  const [num1, num2, ...others] = arr;
+  let res = operation(num1, num2);
+
+  others.forEach((num) => {
+    res = operation(res, num);
+  });
+
+  return res;
+}
+
+/**
+ * 楂樼簿搴︿箻娉�
+ * @export
+ */
+export function times(...nums) {
+  if (nums.length > 2) {
+    return iteratorOperation(nums, times);
+  }
+
+  const [num1, num2] = nums;
+  const num1Changed = float2Fixed(num1);
+  const num2Changed = float2Fixed(num2);
+  const baseNum = digitLength(num1) + digitLength(num2);
+  const leftValue = num1Changed * num2Changed;
+
+  checkBoundary(leftValue);
+
+  return leftValue / Math.pow(10, baseNum);
+}
+
+/**
+ * 楂樼簿搴﹀姞娉�
+ * @export
+ */
+export function plus(...nums) {
+  if (nums.length > 2) {
+    return iteratorOperation(nums, plus);
+  }
+
+  const [num1, num2] = nums;
+  // 鍙栨渶澶х殑灏忔暟浣�
+  const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
+  // 鎶婂皬鏁伴兘杞负鏁存暟鐒跺悗鍐嶈绠�
+  return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
+}
+
+/**
+ * 楂樼簿搴﹀噺娉�
+ * @export
+ */
+export function minus(...nums) {
+  if (nums.length > 2) {
+    return iteratorOperation(nums, minus);
+  }
+
+  const [num1, num2] = nums;
+  const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
+  return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
+}
+
+/**
+ * 楂樼簿搴﹂櫎娉�
+ * @export
+ */
+export function divide(...nums) {
+  if (nums.length > 2) {
+    return iteratorOperation(nums, divide);
+  }
+
+  const [num1, num2] = nums;
+  const num1Changed = float2Fixed(num1);
+  const num2Changed = float2Fixed(num2);
+  checkBoundary(num1Changed);
+  checkBoundary(num2Changed);
+  // 閲嶈锛岃繖閲屽繀椤荤敤strip杩涜淇
+  return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
+}
+
+/**
+ * 鍥涜垗浜斿叆
+ * @export
+ */
+export function round(num, ratio) {
+  const base = Math.pow(10, ratio);
+  let result = divide(Math.round(Math.abs(times(num, base))), base);
+  if (num < 0 && result !== 0) {
+    result = times(result, -1);
+  }
+  // 浣嶆暟涓嶈冻鍒欒ˉ0
+  return result;
+}
+
+/**
+ * 鏄惁杩涜杈圭晫妫�鏌ワ紝榛樿寮�鍚�
+ * @param flag 鏍囪寮�鍏筹紝true 涓哄紑鍚紝false 涓哄叧闂紝榛樿涓� true
+ * @export
+ */
+export function enableBoundaryChecking(flag = true) {
+  _boundaryCheckingState = flag;
+}
+
+
+export default {
+  times,
+  plus,
+  minus,
+  divide,
+  round,
+  enableBoundaryChecking,
+};
+
diff --git a/uni_modules/uv-ui-tools/libs/function/index.js b/uni_modules/uv-ui-tools/libs/function/index.js
new file mode 100644
index 0000000..b35e0ab
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/function/index.js
@@ -0,0 +1,734 @@
+import { number, empty } from './test.js'
+import { round } from './digit.js'
+/**
+ * @description 濡傛灉value灏忎簬min锛屽彇min锛涘鏋渧alue澶т簬max锛屽彇max
+ * @param {number} min
+ * @param {number} max
+ * @param {number} value
+ */
+function range(min = 0, max = 0, value = 0) {
+	return Math.max(min, Math.min(max, Number(value)))
+}
+
+/**
+ * @description 鐢ㄤ簬鑾峰彇鐢ㄦ埛浼犻�掑�肩殑px鍊�  濡傛灉鐢ㄦ埛浼犻�掍簡"xxpx"鎴栬��"xxrpx"锛屽彇鍑哄叾鏁板�奸儴鍒嗭紝濡傛灉鏄�"xxxrpx"杩橀渶瑕佺敤杩噓ni.upx2px杩涜杞崲
+ * @param {number|string} value 鐢ㄦ埛浼犻�掑�肩殑px鍊�
+ * @param {boolean} unit
+ * @returns {number|string}
+ */
+function getPx(value, unit = false) {
+	if (number(value)) {
+		return unit ? `${value}px` : Number(value)
+	}
+	// 濡傛灉甯︽湁rpx锛屽厛鍙栧嚭鍏舵暟鍊奸儴鍒嗭紝鍐嶈浆涓簆x鍊�
+	if (/(rpx|upx)$/.test(value)) {
+		return unit ? `${uni.upx2px(parseInt(value))}px` : Number(uni.upx2px(parseInt(value)))
+	}
+	return unit ? `${parseInt(value)}px` : parseInt(value)
+}
+
+/**
+ * @description 杩涜寤舵椂锛屼互杈惧埌鍙互绠�鍐欎唬鐮佺殑鐩殑 姣斿: await uni.$uv.sleep(20)灏嗕細闃诲20ms
+ * @param {number} value 鍫靛鏃堕棿 鍗曚綅ms 姣
+ * @returns {Promise} 杩斿洖promise
+ */
+function sleep(value = 30) {
+	return new Promise((resolve) => {
+		setTimeout(() => {
+			resolve()
+		}, value)
+	})
+}
+/**
+ * @description 杩愯鏈熷垽鏂钩鍙�
+ * @returns {string} 杩斿洖鎵�鍦ㄥ钩鍙�(灏忓啓)
+ * @link 杩愯鏈熷垽鏂钩鍙� https://uniapp.dcloud.io/frame?id=鍒ゆ柇骞冲彴
+ */
+function os() {
+	return uni.getSystemInfoSync().platform.toLowerCase()
+}
+/**
+ * @description 鑾峰彇绯荤粺淇℃伅鍚屾鎺ュ彛
+ * @link 鑾峰彇绯荤粺淇℃伅鍚屾鎺ュ彛 https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync
+ */
+function sys() {
+	return uni.getSystemInfoSync()
+}
+
+/**
+ * @description 鍙栦竴涓尯闂存暟
+ * @param {Number} min 鏈�灏忓��
+ * @param {Number} max 鏈�澶у��
+ */
+function random(min, max) {
+	if (min >= 0 && max > 0 && max >= min) {
+		const gab = max - min + 1
+		return Math.floor(Math.random() * gab + min)
+	}
+	return 0
+}
+
+/**
+ * @param {Number} len uuid鐨勯暱搴�
+ * @param {Boolean} firstU 灏嗚繑鍥炵殑棣栧瓧姣嶇疆涓�"u"
+ * @param {Nubmer} radix 鐢熸垚uuid鐨勫熀鏁�(鎰忓懗鐫�杩斿洖鐨勫瓧绗︿覆閮芥槸杩欎釜鍩烘暟),2-浜岃繘鍒�,8-鍏繘鍒�,10-鍗佽繘鍒�,16-鍗佸叚杩涘埗
+ */
+function guid(len = 32, firstU = true, radix = null) {
+	const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
+	const uuid = []
+	radix = radix || chars.length
+
+	if (len) {
+		// 濡傛灉鎸囧畾uuid闀垮害,鍙槸鍙栭殢鏈虹殑瀛楃,0|x涓轰綅杩愮畻,鑳藉幓鎺墄鐨勫皬鏁颁綅,杩斿洖鏁存暟浣�
+		for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
+	} else {
+		let r
+		// rfc4122鏍囧噯瑕佹眰杩斿洖鐨剈uid涓�,鏌愪簺浣嶄负鍥哄畾鐨勫瓧绗�
+		uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
+		uuid[14] = '4'
+
+		for (let i = 0; i < 36; i++) {
+			if (!uuid[i]) {
+				r = 0 | Math.random() * 16
+				uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]
+			}
+		}
+	}
+	// 绉婚櫎绗竴涓瓧绗�,骞剁敤u鏇夸唬,鍥犱负绗竴涓瓧绗︿负鏁板�兼椂,璇uuid涓嶈兘鐢ㄤ綔id鎴栬�卌lass
+	if (firstU) {
+		uuid.shift()
+		return `u${uuid.join('')}`
+	}
+	return uuid.join('')
+}
+
+/**
+* @description 鑾峰彇鐖剁粍浠剁殑鍙傛暟锛屽洜涓烘敮浠樺疂灏忕▼搴忎笉鏀寔provide/inject鐨勫啓娉�
+   this.$parent鍦ㄩ潪H5涓紝鍙互鍑嗙‘鑾峰彇鍒扮埗缁勪欢锛屼絾鏄湪H5涓紝闇�瑕佸娆his.$parent.$parent.xxx
+   杩欓噷榛樿鍊肩瓑浜巙ndefined鏈夊畠鐨勫惈涔夛紝鍥犱负鏈�椤跺眰鍏冪礌(缁勪欢)鐨�$parent灏辨槸undefined锛屾剰鍛崇潃涓嶄紶name
+   鍊�(榛樿涓簎ndefined)锛屽氨鏄煡鎵炬渶椤跺眰鐨�$parent
+*  @param {string|undefined} name 鐖剁粍浠剁殑鍙傛暟鍚�
+*/
+function $parent(name = undefined) {
+	let parent = this.$parent
+	// 閫氳繃while鍘嗛亶锛岃繖閲屼富瑕佹槸涓轰簡H5闇�瑕佸灞傝В鏋愮殑闂
+	while (parent) {
+		// 鐖剁粍浠�
+		if (parent.$options && parent.$options.name !== name) {
+			// 濡傛灉缁勪欢鐨刵ame涓嶇浉绛夛紝缁х画涓婁竴绾у鎵�
+			parent = parent.$parent
+		} else {
+			return parent
+		}
+	}
+	return false
+}
+
+/**
+ * @description 鏍峰紡杞崲
+ * 瀵硅薄杞瓧绗︿覆锛屾垨鑰呭瓧绗︿覆杞璞�
+ * @param {object | string} customStyle 闇�瑕佽浆鎹㈢殑鐩爣
+ * @param {String} target 杞崲鐨勭洰鐨勶紝object-杞负瀵硅薄锛宻tring-杞负瀛楃涓�
+ * @returns {object|string}
+ */
+function addStyle(customStyle, target = 'object') {
+	// 瀛楃涓茶浆瀛楃涓诧紝瀵硅薄杞璞℃儏褰紝鐩存帴杩斿洖
+	if (empty(customStyle) || typeof(customStyle) === 'object' && target === 'object' || target === 'string' &&
+		typeof(customStyle) === 'string') {
+		return customStyle
+	}
+	// 瀛楃涓茶浆瀵硅薄
+	if (target === 'object') {
+		// 鍘婚櫎瀛楃涓叉牱寮忎腑鐨勪袱绔┖鏍�(涓棿鐨勭┖鏍间笉鑳藉幓鎺夛紝姣斿padding: 20px 0濡傛灉鍘绘帀浜嗗氨閿欎簡)锛岀┖鏍兼槸鏃犵敤鐨�
+		customStyle = trim(customStyle)
+		// 鏍规嵁";"灏嗗瓧绗︿覆杞负鏁扮粍褰㈠紡
+		const styleArray = customStyle.split(';')
+		const style = {}
+		// 鍘嗛亶鏁扮粍锛屾嫾鎺ユ垚瀵硅薄
+		for (let i = 0; i < styleArray.length; i++) {
+			// 'font-size:20px;color:red;'锛屽姝ゆ渶鍚庡瓧绗︿覆鏈�";"鐨勮瘽锛屼細瀵艰嚧styleArray鏈�鍚庝竴涓厓绱犱负绌哄瓧绗︿覆锛岃繖閲岄渶瑕佽繃婊�
+			if (styleArray[i]) {
+				const item = styleArray[i].split(':')
+				style[trim(item[0])] = trim(item[1])
+			}
+		}
+		return style
+	}
+	// 杩欓噷涓哄璞¤浆瀛楃涓插舰寮�
+	let string = ''
+	for (const i in customStyle) {
+		// 椹煎嘲杞负涓垝绾跨殑褰㈠紡锛屽惁鍒檆ss鍐呰仈鏍峰紡锛屾棤娉曡瘑鍒┘宄版牱寮忓睘鎬у悕
+		const key = i.replace(/([A-Z])/g, '-$1').toLowerCase()
+		string += `${key}:${customStyle[i]};`
+	}
+	// 鍘婚櫎涓ょ绌烘牸
+	return trim(string)
+}
+
+/**
+ * @description 娣诲姞鍗曚綅锛屽鏋滄湁rpx锛寀px锛�%锛宲x绛夊崟浣嶇粨灏炬垨鑰呭�间负auto锛岀洿鎺ヨ繑鍥烇紝鍚﹀垯鍔犱笂px鍗曚綅缁撳熬
+ * @param {string|number} value 闇�瑕佹坊鍔犲崟浣嶇殑鍊�
+ * @param {string} unit 娣诲姞鐨勫崟浣嶅悕 姣斿px
+ */
+function addUnit(value = 'auto', unit = uni?.$uv?.config?.unit ? uni?.$uv?.config?.unit : 'px') {
+	value = String(value)
+	// 鐢╱vui鍐呯疆楠岃瘉瑙勫垯涓殑number鍒ゆ柇鏄惁涓烘暟鍊�
+	return number(value) ? `${value}${unit}` : value
+}
+
+/**
+ * @description 娣卞害鍏嬮殕
+ * @param {object} obj 闇�瑕佹繁搴﹀厠闅嗙殑瀵硅薄
+ * @param cache 缂撳瓨
+ * @returns {*} 鍏嬮殕鍚庣殑瀵硅薄鎴栬�呭師鍊硷紙涓嶆槸瀵硅薄锛�
+ */
+function deepClone(obj, cache = new WeakMap()) {
+	if (obj === null || typeof obj !== 'object') return obj;
+	if (cache.has(obj)) return cache.get(obj);
+	let clone;
+	if (obj instanceof Date) {
+		clone = new Date(obj.getTime());
+	} else if (obj instanceof RegExp) {
+		clone = new RegExp(obj);
+	} else if (obj instanceof Map) {
+		clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)]));
+	} else if (obj instanceof Set) {
+		clone = new Set(Array.from(obj, value => deepClone(value, cache)));
+	} else if (Array.isArray(obj)) {
+		clone = obj.map(value => deepClone(value, cache));
+	} else if (Object.prototype.toString.call(obj) === '[object Object]') {
+		clone = Object.create(Object.getPrototypeOf(obj));
+		cache.set(obj, clone);
+		for (const [key, value] of Object.entries(obj)) {
+			clone[key] = deepClone(value, cache);
+		}
+	} else {
+		clone = Object.assign({}, obj);
+	}
+	cache.set(obj, clone);
+	return clone;
+}
+
+/**
+ * @description JS瀵硅薄娣卞害鍚堝苟
+ * @param {object} target 闇�瑕佹嫹璐濈殑瀵硅薄
+ * @param {object} source 鎷疯礉鐨勬潵婧愬璞�
+ * @returns {object|boolean} 娣卞害鍚堝苟鍚庣殑瀵硅薄鎴栬�協alse锛堝叆鍙傛湁涓嶆槸瀵硅薄锛�
+ */
+function deepMerge(target = {}, source = {}) {
+	target = deepClone(target)
+	if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return target;
+	const merged = Array.isArray(target) ? target.slice() : Object.assign({}, target);
+	for (const prop in source) {
+		if (!source.hasOwnProperty(prop)) continue;
+		const sourceValue = source[prop];
+		const targetValue = merged[prop];
+		if (sourceValue instanceof Date) {
+			merged[prop] = new Date(sourceValue);
+		} else if (sourceValue instanceof RegExp) {
+			merged[prop] = new RegExp(sourceValue);
+		} else if (sourceValue instanceof Map) {
+			merged[prop] = new Map(sourceValue);
+		} else if (sourceValue instanceof Set) {
+			merged[prop] = new Set(sourceValue);
+		} else if (typeof sourceValue === 'object' && sourceValue !== null) {
+			merged[prop] = deepMerge(targetValue, sourceValue);
+		} else {
+			merged[prop] = sourceValue;
+		}
+	}
+	return merged;
+}
+
+/**
+ * @description error鎻愮ず
+ * @param {*} err 閿欒鍐呭
+ */
+function error(err) {
+	// 寮�鍙戠幆澧冩墠鎻愮ず锛岀敓浜х幆澧冧笉浼氭彁绀�
+	if (process.env.NODE_ENV === 'development') {
+		console.error(`uvui鎻愮ず锛�${err}`)
+	}
+}
+
+/**
+ * @description 鎵撲贡鏁扮粍
+ * @param {array} array 闇�瑕佹墦涔辩殑鏁扮粍
+ * @returns {array} 鎵撲贡鍚庣殑鏁扮粍
+ */
+function randomArray(array = []) {
+	// 鍘熺悊鏄痵ort鎺掑簭,Math.random()浜х敓0<= x < 1涔嬮棿鐨勬暟,浼氬鑷磝-0.05澶т簬鎴栬�呭皬浜�0
+	return array.sort(() => Math.random() - 0.5)
+}
+
+// padStart 鐨� polyfill锛屽洜涓烘煇浜涙満鍨嬫垨鎯呭喌锛岃繕鏃犳硶鏀寔es7鐨刾adStart锛屾瘮濡傜數鑴戠増鐨勫井淇″皬绋嬪簭
+// 鎵�浠ヨ繖閲屽仛涓�涓吋瀹筽olyfill鐨勫吋瀹瑰鐞�
+if (!String.prototype.padStart) {
+	// 涓轰簡鏂逛究琛ㄧず杩欓噷 fillString 鐢ㄤ簡ES6 鐨勯粯璁ゅ弬鏁帮紝涓嶅奖鍝嶇悊瑙�
+	String.prototype.padStart = function(maxLength, fillString = ' ') {
+		if (Object.prototype.toString.call(fillString) !== '[object String]') {
+			throw new TypeError(
+				'fillString must be String'
+			)
+		}
+		const str = this
+		// 杩斿洖 String(str) 杩欓噷鏄负浜嗕娇杩斿洖鐨勫�兼槸瀛楃涓插瓧闈㈤噺锛屽湪鎺у埗鍙颁腑鏇寸鍚堢洿瑙�
+		if (str.length >= maxLength) return String(str)
+
+		const fillLength = maxLength - str.length
+		let times = Math.ceil(fillLength / fillString.length)
+		while (times >>= 1) {
+			fillString += fillString
+			if (times === 1) {
+				fillString += fillString
+			}
+		}
+		return fillString.slice(0, fillLength) + str
+	}
+}
+
+/**
+ * @description 鏍煎紡鍖栨椂闂�
+ * @param {String|Number} dateTime 闇�瑕佹牸寮忓寲鐨勬椂闂存埑
+ * @param {String} fmt 鏍煎紡鍖栬鍒� yyyy:mm:dd|yyyy:mm|yyyy骞磎m鏈坉d鏃yyyy骞磎m鏈坉d鏃� hh鏃禡M鍒嗙瓑,鍙嚜瀹氫箟缁勫悎 榛樿yyyy-mm-dd
+ * @returns {string} 杩斿洖鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+function timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') {
+	let date
+	// 鑻ヤ紶鍏ユ椂闂翠负鍋囧�硷紝鍒欏彇褰撳墠鏃堕棿
+	if (!dateTime) {
+		date = new Date()
+	}
+	// 鑻ヤ负unix绉掓椂闂存埑锛屽垯杞负姣鏃堕棿鎴筹紙閫昏緫鏈夌偣濂囨�紝浣嗕笉鏁㈡敼锛屼互淇濊瘉鍘嗗彶鍏煎锛�
+	else if (/^\d{10}$/.test(dateTime?.toString().trim())) {
+		date = new Date(dateTime * 1000)
+	}
+	// 鑻ョ敤鎴蜂紶鍏ュ瓧绗︿覆鏍煎紡鏃堕棿鎴筹紝new Date鏃犳硶瑙f瀽锛岄渶鍋氬吋瀹�
+	else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) {
+		date = new Date(Number(dateTime))
+	}
+	// 澶勭悊骞冲彴鎬у樊寮傦紝鍦⊿afari/Webkit涓紝new Date浠呮敮鎸�/浣滀负鍒嗗壊绗︾殑瀛楃涓叉椂闂�
+	// 澶勭悊 '2022-07-10 01:02:03'锛岃烦杩� '2022-07-10T01:02:03'
+	else if (typeof dateTime === 'string' && dateTime.includes('-') && !dateTime.includes('T')) {
+		date = new Date(dateTime.replace(/-/g, '/'))
+	}
+	// 鍏朵粬閮借涓虹鍚� RFC 2822 瑙勮寖
+	else {
+		date = new Date(dateTime)
+	}
+
+	const timeSource = {
+		'y': date.getFullYear().toString(), // 骞�
+		'm': (date.getMonth() + 1).toString().padStart(2, '0'), // 鏈�
+		'd': date.getDate().toString().padStart(2, '0'), // 鏃�
+		'h': date.getHours().toString().padStart(2, '0'), // 鏃�
+		'M': date.getMinutes().toString().padStart(2, '0'), // 鍒�
+		's': date.getSeconds().toString().padStart(2, '0') // 绉�
+		// 鏈夊叾浠栨牸寮忓寲瀛楃闇�姹傚彲浠ョ户缁坊鍔狅紝蹇呴』杞寲鎴愬瓧绗︿覆
+	}
+
+	for (const key in timeSource) {
+		const [ret] = new RegExp(`${key}+`).exec(formatStr) || []
+		if (ret) {
+			// 骞村彲鑳藉彧闇�灞曠ず涓や綅
+			const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0
+			formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex))
+		}
+	}
+
+	return formatStr
+}
+
+/**
+ * @description 鏃堕棿鎴宠浆涓哄涔呬箣鍓�
+ * @param {String|Number} timestamp 鏃堕棿鎴�
+ * @param {String|Boolean} format
+ * 鏍煎紡鍖栬鍒欏鏋滀负鏃堕棿鏍煎紡瀛楃涓诧紝瓒呭嚭涓�瀹氭椂闂磋寖鍥达紝杩斿洖鍥哄畾鐨勬椂闂存牸寮忥紱
+ * 濡傛灉涓哄竷灏斿�糵alse锛屾棤璁轰粈涔堟椂闂达紝閮借繑鍥炲涔呬互鍓嶇殑鏍煎紡
+ * @returns {string} 杞寲鍚庣殑鍐呭
+ */
+function timeFrom(timestamp = null, format = 'yyyy-mm-dd') {
+	if (timestamp == null) timestamp = Number(new Date())
+	timestamp = parseInt(timestamp)
+	// 鍒ゆ柇鐢ㄦ埛杈撳叆鐨勬椂闂存埑鏄杩樻槸姣,涓�鑸墠绔痡s鑾峰彇鐨勬椂闂存埑鏄绉�(13浣�),鍚庣浼犺繃鏉ョ殑涓虹(10浣�)
+	if (timestamp.toString().length == 10) timestamp *= 1000
+	let timer = (new Date()).getTime() - timestamp
+	timer = parseInt(timer / 1000)
+	// 濡傛灉灏忎簬5鍒嗛挓,鍒欒繑鍥�"鍒氬垰",鍏朵粬浠ユ绫绘帹
+	let tips = ''
+	switch (true) {
+		case timer < 300:
+			tips = '鍒氬垰'
+			break
+		case timer >= 300 && timer < 3600:
+			tips = `${parseInt(timer / 60)}鍒嗛挓鍓峘
+			break
+		case timer >= 3600 && timer < 86400:
+			tips = `${parseInt(timer / 3600)}灏忔椂鍓峘
+			break
+		case timer >= 86400 && timer < 2592000:
+			tips = `${parseInt(timer / 86400)}澶╁墠`
+			break
+		default:
+			// 濡傛灉format涓篺alse锛屽垯鏃犺浠�涔堟椂闂存埑锛岄兘鏄剧ずxx涔嬪墠
+			if (format === false) {
+				if (timer >= 2592000 && timer < 365 * 86400) {
+					tips = `${parseInt(timer / (86400 * 30))}涓湀鍓峘
+				} else {
+					tips = `${parseInt(timer / (86400 * 365))}骞村墠`
+				}
+			} else {
+				tips = timeFormat(timestamp, format)
+			}
+	}
+	return tips
+}
+
+/**
+ * @description 鍘婚櫎绌烘牸
+ * @param String str 闇�瑕佸幓闄ょ┖鏍肩殑瀛楃涓�
+ * @param String pos both(宸﹀彸)|left|right|all 榛樿both
+ */
+function trim(str, pos = 'both') {
+	str = String(str)
+	if (pos == 'both') {
+		return str.replace(/^\s+|\s+$/g, '')
+	}
+	if (pos == 'left') {
+		return str.replace(/^\s*/, '')
+	}
+	if (pos == 'right') {
+		return str.replace(/(\s*$)/g, '')
+	}
+	if (pos == 'all') {
+		return str.replace(/\s+/g, '')
+	}
+	return str
+}
+
+/**
+ * @description 瀵硅薄杞瑄rl鍙傛暟
+ * @param {object} data,瀵硅薄
+ * @param {Boolean} isPrefix,鏄惁鑷姩鍔犱笂"?"
+ * @param {string} arrayFormat 瑙勫垯 indices|brackets|repeat|comma
+ */
+function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') {
+	const prefix = isPrefix ? '?' : ''
+	const _result = []
+	if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets'
+	for (const key in data) {
+		const value = data[key]
+		// 鍘绘帀涓虹┖鐨勫弬鏁�
+		if (['', undefined, null].indexOf(value) >= 0) {
+			continue
+		}
+		// 濡傛灉鍊间负鏁扮粍锛屽彟琛屽鐞�
+		if (value.constructor === Array) {
+			// e.g. {ids: [1, 2, 3]}
+			switch (arrayFormat) {
+				case 'indices':
+					// 缁撴灉: ids[0]=1&ids[1]=2&ids[2]=3
+					for (let i = 0; i < value.length; i++) {
+						_result.push(`${key}[${i}]=${value[i]}`)
+					}
+					break
+				case 'brackets':
+					// 缁撴灉: ids[]=1&ids[]=2&ids[]=3
+					value.forEach((_value) => {
+						_result.push(`${key}[]=${_value}`)
+					})
+					break
+				case 'repeat':
+					// 缁撴灉: ids=1&ids=2&ids=3
+					value.forEach((_value) => {
+						_result.push(`${key}=${_value}`)
+					})
+					break
+				case 'comma':
+					// 缁撴灉: ids=1,2,3
+					let commaStr = ''
+					value.forEach((_value) => {
+						commaStr += (commaStr ? ',' : '') + _value
+					})
+					_result.push(`${key}=${commaStr}`)
+					break
+				default:
+					value.forEach((_value) => {
+						_result.push(`${key}[]=${_value}`)
+					})
+			}
+		} else {
+			_result.push(`${key}=${value}`)
+		}
+	}
+	return _result.length ? prefix + _result.join('&') : ''
+}
+
+/**
+ * 鏄剧ず娑堟伅鎻愮ず妗�
+ * @param {String} title 鎻愮ず鐨勫唴瀹癸紝闀垮害涓� icon 鍙栧�兼湁鍏炽��
+ * @param {Number} duration 鎻愮ず鐨勫欢杩熸椂闂达紝鍗曚綅姣锛岄粯璁わ細2000
+ */
+function toast(title, duration = 2000) {
+	uni.showToast({
+		title: String(title),
+		icon: 'none',
+		duration
+	})
+}
+
+/**
+ * @description 鏍规嵁涓婚type鍊�,鑾峰彇瀵瑰簲鐨勫浘鏍�
+ * @param {String} type 涓婚鍚嶇О,primary|info|error|warning|success
+ * @param {boolean} fill 鏄惁浣跨敤fill濉厖瀹炰綋鐨勫浘鏍�
+ */
+function type2icon(type = 'success', fill = false) {
+	// 濡傛灉闈為缃��,榛樿涓簊uccess
+	if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success'
+	let iconName = ''
+	// 鐩墠(2019-12-12),info鍜宲rimary浣跨敤鍚屼竴涓浘鏍�
+	switch (type) {
+		case 'primary':
+			iconName = 'info-circle'
+			break
+		case 'info':
+			iconName = 'info-circle'
+			break
+		case 'error':
+			iconName = 'close-circle'
+			break
+		case 'warning':
+			iconName = 'error-circle'
+			break
+		case 'success':
+			iconName = 'checkmark-circle'
+			break
+		default:
+			iconName = 'checkmark-circle'
+	}
+	// 鏄惁鏄疄浣撶被鍨�,鍔犱笂-fill,鍦╥con缁勪欢搴撲腑,瀹炰綋鐨勭被鍚嶆槸鍚庨潰鍔�-fill鐨�
+	if (fill) iconName += '-fill'
+	return iconName
+}
+
+/**
+ * @description 鏁板瓧鏍煎紡鍖�
+ * @param {number|string} number 瑕佹牸寮忓寲鐨勬暟瀛�
+ * @param {number} decimals 淇濈暀鍑犱綅灏忔暟
+ * @param {string} decimalPoint 灏忔暟鐐圭鍙�
+ * @param {string} thousandsSeparator 鍗冨垎浣嶇鍙�
+ * @returns {string} 鏍煎紡鍖栧悗鐨勬暟瀛�
+ */
+function priceFormat(number, decimals = 0, decimalPoint = '.', thousandsSeparator = ',') {
+	number = (`${number}`).replace(/[^0-9+-Ee.]/g, '')
+	const n = !isFinite(+number) ? 0 : +number
+	const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
+	const sep = (typeof thousandsSeparator === 'undefined') ? ',' : thousandsSeparator
+	const dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint
+	let s = ''
+
+	s = (prec ? round(n, prec) + '' : `${Math.round(n)}`).split('.')
+	const re = /(-?\d+)(\d{3})/
+	while (re.test(s[0])) {
+		s[0] = s[0].replace(re, `$1${sep}$2`)
+	}
+
+	if ((s[1] || '').length < prec) {
+		s[1] = s[1] || ''
+		s[1] += new Array(prec - s[1].length + 1).join('0')
+	}
+	return s.join(dec)
+}
+
+/**
+ * @description 鑾峰彇duration鍊�
+ * 濡傛灉甯︽湁ms鎴栬�卻鐩存帴杩斿洖锛屽鏋滃ぇ浜庝竴瀹氬�硷紝璁や负鏄痬s鍗曚綅锛屽皬浜庝竴瀹氬�硷紝璁や负鏄痵鍗曚綅
+ * 姣斿浠�30浣嶉槇鍊硷紝閭d箞300澶т簬30锛屽彲浠ョ悊瑙d负鐢ㄦ埛鎯宠鐨勬槸300ms锛岃�屼笉鏄兂鑺�300s鍘绘墽琛屼竴涓姩鐢�
+ * @param {String|number} value 姣斿: "1s"|"100ms"|1|100
+ * @param {boolean} unit  鎻愮ず: 濡傛灉鏄痜alse 榛樿杩斿洖number
+ * @return {string|number}
+ */
+function getDuration(value, unit = true) {
+	const valueNum = parseInt(value)
+	if (unit) {
+		if (/s$/.test(value)) return value
+		return value > 30 ? `${value}ms` : `${value}s`
+	}
+	if (/ms$/.test(value)) return valueNum
+	if (/s$/.test(value)) return valueNum > 30 ? valueNum : valueNum * 1000
+	return valueNum
+}
+
+/**
+ * @description 鏃ユ湡鐨勬湀鎴栨棩琛ラ浂鎿嶄綔
+ * @param {String} value 闇�瑕佽ˉ闆剁殑鍊�
+ */
+function padZero(value) {
+	return `00${value}`.slice(-2)
+}
+
+/**
+ * @description 鍦╱v-form鐨勫瓙缁勪欢鍐呭鍙戠敓鍙樺寲锛屾垨鑰呭け鍘荤劍鐐规椂锛屽皾璇曢�氱煡uv-form鎵ц鏍¢獙鏂规硶
+ * @param {*} instance
+ * @param {*} event
+ */
+function formValidate(instance, event) {
+	const formItem = $parent.call(instance, 'uv-form-item')
+	const form = $parent.call(instance, 'uv-form')
+	// 濡傛灉鍙戠敓鍙樺寲鐨刬nput鎴栬�卼extarea绛夛紝鍏剁埗缁勪欢涓湁uv-form-item鎴栬�卽v-form绛夛紝灏辨墽琛宖orm鐨剉alidate鏂规硶
+	// 鍚屾椂灏唂orm-item鐨刾ros浼犻�掔粰form锛岃鍏惰繘琛岀簿纭璞¢獙璇�
+	if (formItem && form) {
+		form.validateField(formItem.prop, () => {}, event)
+	}
+}
+
+/**
+ * @description 鑾峰彇鏌愪釜瀵硅薄涓嬬殑灞炴�э紝鐢ㄤ簬閫氳繃绫讳技'a.b.c'鐨勫舰寮忓幓鑾峰彇涓�涓璞$殑鐨勫睘鎬х殑褰㈠紡
+ * @param {object} obj 瀵硅薄
+ * @param {string} key 闇�瑕佽幏鍙栫殑灞炴�у瓧娈�
+ * @returns {*}
+ */
+function getProperty(obj, key) {
+	if (!obj) {
+		return
+	}
+	if (typeof key !== 'string' || key === '') {
+		return ''
+	}
+	if (key.indexOf('.') !== -1) {
+		const keys = key.split('.')
+		let firstObj = obj[keys[0]] || {}
+
+		for (let i = 1; i < keys.length; i++) {
+			if (firstObj) {
+				firstObj = firstObj[keys[i]]
+			}
+		}
+		return firstObj
+	}
+	return obj[key]
+}
+
+/**
+ * @description 璁剧疆瀵硅薄鐨勫睘鎬у�硷紝濡傛灉'a.b.c'鐨勫舰寮忚繘琛岃缃�
+ * @param {object} obj 瀵硅薄
+ * @param {string} key 闇�瑕佽缃殑灞炴��
+ * @param {string} value 璁剧疆鐨勫��
+ */
+function setProperty(obj, key, value) {
+	if (!obj) {
+		return
+	}
+	// 閫掑綊璧嬪��
+	const inFn = function(_obj, keys, v) {
+		// 鏈�鍚庝竴涓睘鎬ey
+		if (keys.length === 1) {
+			_obj[keys[0]] = v
+			return
+		}
+		// 0~length-1涓猭ey
+		while (keys.length > 1) {
+			const k = keys[0]
+			if (!_obj[k] || (typeof _obj[k] !== 'object')) {
+				_obj[k] = {}
+			}
+			const key = keys.shift()
+			// 鑷皟鐢ㄥ垽鏂槸鍚﹀瓨鍦ㄥ睘鎬э紝涓嶅瓨鍦ㄥ垯鑷姩鍒涘缓瀵硅薄
+			inFn(_obj[k], keys, v)
+		}
+	}
+
+	if (typeof key !== 'string' || key === '') {
+
+	} else if (key.indexOf('.') !== -1) { // 鏀寔澶氬眰绾ц祴鍊兼搷浣�
+		const keys = key.split('.')
+		inFn(obj, keys, value)
+	} else {
+		obj[key] = value
+	}
+}
+
+/**
+ * @description 鑾峰彇褰撳墠椤甸潰璺緞
+ */
+function page() {
+	const pages = getCurrentPages();
+	const route = pages[pages.length - 1]?.route;
+	// 鏌愪簺鐗规畩鎯呭喌涓�(姣斿椤甸潰杩涜redirectTo鏃剁殑涓�浜涙椂鏈�)锛宲ages鍙兘涓虹┖鏁扮粍
+	return `/${route ? route : ''}`
+}
+
+/**
+ * @description 鑾峰彇褰撳墠璺敱鏍堝疄渚嬫暟缁�
+ */
+function pages() {
+	const pages = getCurrentPages()
+	return pages
+}
+
+/**
+ * 鑾峰彇椤甸潰鍘嗗彶鏍堟寚瀹氬眰瀹炰緥
+ * @param back {number} [0] - 0鎴栬�呰礋鏁帮紝琛ㄧず鑾峰彇鍘嗗彶鏍堢殑鍝竴灞傦紝0琛ㄧず鑾峰彇褰撳墠椤甸潰瀹炰緥锛�-1 琛ㄧず鑾峰彇涓婁竴涓〉闈㈠疄渚嬨�傞粯璁�0銆�
+ */
+function getHistoryPage(back = 0) {
+	const pages = getCurrentPages()
+	const len = pages.length
+	return pages[len - 1 + back]
+}
+
+
+
+/**
+ * @description 淇敼uvui鍐呯疆灞炴�у��
+ * @param {object} props 淇敼鍐呯疆props灞炴��
+ * @param {object} config 淇敼鍐呯疆config灞炴��
+ * @param {object} color 淇敼鍐呯疆color灞炴��
+ * @param {object} zIndex 淇敼鍐呯疆zIndex灞炴��
+ */
+function setConfig({
+	props = {},
+	config = {},
+	color = {},
+	zIndex = {}
+}) {
+	const {
+		deepMerge,
+	} = uni.$uv
+	uni.$uv.config = deepMerge(uni.$uv.config, config)
+	uni.$uv.props = deepMerge(uni.$uv.props, props)
+	uni.$uv.color = deepMerge(uni.$uv.color, color)
+	uni.$uv.zIndex = deepMerge(uni.$uv.zIndex, zIndex)
+}
+
+export {
+	range,
+	getPx,
+	sleep,
+	os,
+	sys,
+	random,
+	guid,
+	$parent,
+	addStyle,
+	addUnit,
+	deepClone,
+	deepMerge,
+	error,
+	randomArray,
+	timeFormat,
+	timeFrom,
+	trim,
+	queryParams,
+	toast,
+	type2icon,
+	priceFormat,
+	getDuration,
+	padZero,
+	formValidate,
+	getProperty,
+	setProperty,
+	page,
+	pages,
+	getHistoryPage,
+	setConfig
+}
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/libs/function/platform.js b/uni_modules/uv-ui-tools/libs/function/platform.js
new file mode 100644
index 0000000..d6b926e
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/function/platform.js
@@ -0,0 +1,75 @@
+/**
+ * 娉ㄦ剰锛�
+ * 姝ら儴鍒嗗唴瀹癸紝鍦╲ue-cli妯″紡涓嬶紝闇�瑕佸湪vue.config.js鍔犲叆濡備笅鍐呭鎵嶆湁鏁堬細
+ * module.exports = {
+ *     transpileDependencies: ['uview-v2']
+ * }
+ */
+
+let platform = 'none'
+
+// #ifdef VUE3
+platform = 'vue3'
+// #endif
+
+// #ifdef VUE2
+platform = 'vue2'
+// #endif
+
+// #ifdef APP-PLUS
+platform = 'plus'
+// #endif
+
+// #ifdef APP-NVUE
+platform = 'nvue'
+// #endif
+
+// #ifdef H5
+platform = 'h5'
+// #endif
+
+// #ifdef MP-WEIXIN
+platform = 'weixin'
+// #endif
+
+// #ifdef MP-ALIPAY
+platform = 'alipay'
+// #endif
+
+// #ifdef MP-BAIDU
+platform = 'baidu'
+// #endif
+
+// #ifdef MP-TOUTIAO
+platform = 'toutiao'
+// #endif
+
+// #ifdef MP-QQ
+platform = 'qq'
+// #endif
+
+// #ifdef MP-KUAISHOU
+platform = 'kuaishou'
+// #endif
+
+// #ifdef MP-360
+platform = '360'
+// #endif
+
+// #ifdef MP
+platform = 'mp'
+// #endif
+
+// #ifdef QUICKAPP-WEBVIEW
+platform = 'quickapp-webview'
+// #endif
+
+// #ifdef QUICKAPP-WEBVIEW-HUAWEI
+platform = 'quickapp-webview-huawei'
+// #endif
+
+// #ifdef QUICKAPP-WEBVIEW-UNION
+platform = 'quckapp-webview-union'
+// #endif
+
+export default platform
diff --git a/uni_modules/uv-ui-tools/libs/function/test.js b/uni_modules/uv-ui-tools/libs/function/test.js
new file mode 100644
index 0000000..7c8b747
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/function/test.js
@@ -0,0 +1,287 @@
+/**
+ * 楠岃瘉鐢靛瓙閭鏍煎紡
+ */
+function email(value) {
+    return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value)
+}
+
+/**
+ * 楠岃瘉鎵嬫満鏍煎紡
+ */
+function mobile(value) {
+    return /^1([3589]\d|4[5-9]|6[1-2,4-7]|7[0-8])\d{8}$/.test(value)
+}
+
+/**
+ * 楠岃瘉URL鏍煎紡
+ */
+function url(value) {
+    return /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/
+        .test(value)
+}
+
+/**
+ * 楠岃瘉鏃ユ湡鏍煎紡
+ */
+function date(value) {
+    if (!value) return false
+    // 鍒ゆ柇鏄惁鏁板�兼垨鑰呭瓧绗︿覆鏁板��(鎰忓懗鐫�涓烘椂闂存埑)锛岃浆涓烘暟鍊硷紝鍚﹀垯new Date鏃犳硶璇嗗埆瀛楃涓叉椂闂存埑
+    if (number(value)) value = +value
+    return !/Invalid|NaN/.test(new Date(value).toString())
+}
+
+/**
+ * 楠岃瘉ISO绫诲瀷鐨勬棩鏈熸牸寮�
+ */
+function dateISO(value) {
+    return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)
+}
+
+/**
+ * 楠岃瘉鍗佽繘鍒舵暟瀛�
+ */
+function number(value) {
+    return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value)
+}
+
+/**
+ * 楠岃瘉瀛楃涓�
+ */
+function string(value) {
+    return typeof value === 'string'
+}
+
+/**
+ * 楠岃瘉鏁存暟
+ */
+function digits(value) {
+    return /^\d+$/.test(value)
+}
+
+/**
+ * 楠岃瘉韬唤璇佸彿鐮�
+ */
+function idCard(value) {
+    return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
+        value
+    )
+}
+
+/**
+ * 鏄惁杞︾墝鍙�
+ */
+function carNo(value) {
+    // 鏂拌兘婧愯溅鐗�
+    const xreg = /^[浜触娌笣鍐�璞簯杈介粦婀樼殩椴佹柊鑻忔禉璧i剛妗傜敇鏅嬭挋闄曞悏闂借吹绮ら潚钘忓窛瀹佺惣浣块A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
+    // 鏃ц溅鐗�
+    const creg = /^[浜触娌笣鍐�璞簯杈介粦婀樼殩椴佹柊鑻忔禉璧i剛妗傜敇鏅嬭挋闄曞悏闂借吹绮ら潚钘忓窛瀹佺惣浣块A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9鎸傚璀︽腐婢砞{1}$/
+    if (value.length === 7) {
+        return creg.test(value)
+    } if (value.length === 8) {
+        return xreg.test(value)
+    }
+    return false
+}
+
+/**
+ * 閲戦,鍙厑璁�2浣嶅皬鏁�
+ */
+function amount(value) {
+    // 閲戦锛屽彧鍏佽淇濈暀涓や綅灏忔暟
+    return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value)
+}
+
+/**
+ * 涓枃
+ */
+function chinese(value) {
+    const reg = /^[\u4e00-\u9fa5]+$/gi
+    return reg.test(value)
+}
+
+/**
+ * 鍙兘杈撳叆瀛楁瘝
+ */
+function letter(value) {
+    return /^[a-zA-Z]*$/.test(value)
+}
+
+/**
+ * 鍙兘鏄瓧姣嶆垨鑰呮暟瀛�
+ */
+function enOrNum(value) {
+    // 鑻辨枃鎴栬�呮暟瀛�
+    const reg = /^[0-9a-zA-Z]*$/g
+    return reg.test(value)
+}
+
+/**
+ * 楠岃瘉鏄惁鍖呭惈鏌愪釜鍊�
+ */
+function contains(value, param) {
+    return value.indexOf(param) >= 0
+}
+
+/**
+ * 楠岃瘉涓�涓�艰寖鍥碵min, max]
+ */
+function range(value, param) {
+    return value >= param[0] && value <= param[1]
+}
+
+/**
+ * 楠岃瘉涓�涓暱搴﹁寖鍥碵min, max]
+ */
+function rangeLength(value, param) {
+    return value.length >= param[0] && value.length <= param[1]
+}
+
+/**
+ * 鏄惁鍥哄畾鐢佃瘽
+ */
+function landline(value) {
+    const reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/
+    return reg.test(value)
+}
+
+/**
+ * 鍒ゆ柇鏄惁涓虹┖
+ */
+function empty(value) {
+    switch (typeof value) {
+    case 'undefined':
+        return true
+    case 'string':
+        if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true
+        break
+    case 'boolean':
+        if (!value) return true
+        break
+    case 'number':
+        if (value === 0 || isNaN(value)) return true
+        break
+    case 'object':
+        if (value === null || value.length === 0) return true
+        for (const i in value) {
+            return false
+        }
+        return true
+    }
+    return false
+}
+
+/**
+ * 鏄惁json瀛楃涓�
+ */
+function jsonString(value) {
+    if (typeof value === 'string') {
+        try {
+            const obj = JSON.parse(value)
+            if (typeof obj === 'object' && obj) {
+                return true
+            }
+            return false
+        } catch (e) {
+            return false
+        }
+    }
+    return false
+}
+
+/**
+ * 鏄惁鏁扮粍
+ */
+function array(value) {
+    if (typeof Array.isArray === 'function') {
+        return Array.isArray(value)
+    }
+    return Object.prototype.toString.call(value) === '[object Array]'
+}
+
+/**
+ * 鏄惁瀵硅薄
+ */
+function object(value) {
+    return Object.prototype.toString.call(value) === '[object Object]'
+}
+
+/**
+ * 鏄惁鐭俊楠岃瘉鐮�
+ */
+function code(value, len = 6) {
+    return new RegExp(`^\\d{${len}}$`).test(value)
+}
+
+/**
+ * 鏄惁鍑芥暟鏂规硶
+ * @param {Object} value
+ */
+function func(value) {
+    return typeof value === 'function'
+}
+
+/**
+ * 鏄惁promise瀵硅薄
+ * @param {Object} value
+ */
+function promise(value) {
+    return object(value) && func(value.then) && func(value.catch)
+}
+
+/** 鏄惁鍥剧墖鏍煎紡
+ * @param {Object} value
+ */
+function image(value) {
+    const newValue = value.split('?')[0]
+    const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i
+    return IMAGE_REGEXP.test(newValue)
+}
+
+/**
+ * 鏄惁瑙嗛鏍煎紡
+ * @param {Object} value
+ */
+function video(value) {
+    const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i
+    return VIDEO_REGEXP.test(value)
+}
+
+/**
+ * 鏄惁涓烘鍒欏璞�
+ * @param {Object}
+ * @return {Boolean}
+ */
+function regExp(o) {
+    return o && Object.prototype.toString.call(o) === '[object RegExp]'
+}
+
+export {
+    email,
+    mobile,
+    url,
+    date,
+    dateISO,
+    number,
+    digits,
+    idCard,
+    carNo,
+    amount,
+    chinese,
+    letter,
+    enOrNum,
+    contains,
+    range,
+    rangeLength,
+    empty,
+    jsonString,
+    landline,
+    object,
+    array,
+    code,
+    func,
+    promise,
+    video,
+    image,
+    regExp,
+    string
+}
diff --git a/uni_modules/uv-ui-tools/libs/function/throttle.js b/uni_modules/uv-ui-tools/libs/function/throttle.js
new file mode 100644
index 0000000..2f33611
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/function/throttle.js
@@ -0,0 +1,30 @@
+let timer; let
+    flag
+/**
+ * 鑺傛祦鍘熺悊锛氬湪涓�瀹氭椂闂村唴锛屽彧鑳借Е鍙戜竴娆�
+ *
+ * @param {Function} func 瑕佹墽琛岀殑鍥炶皟鍑芥暟
+ * @param {Number} wait 寤舵椂鐨勬椂闂�
+ * @param {Boolean} immediate 鏄惁绔嬪嵆鎵ц
+ * @return null
+ */
+function throttle(func, wait = 500, immediate = true) {
+    if (immediate) {
+        if (!flag) {
+            flag = true
+            // 濡傛灉鏄珛鍗虫墽琛岋紝鍒欏湪wait姣鍐呭紑濮嬫椂鎵ц
+            typeof func === 'function' && func()
+            timer = setTimeout(() => {
+                flag = false
+            }, wait)
+        }
+    } else if (!flag) {
+        flag = true
+        // 濡傛灉鏄潪绔嬪嵆鎵ц锛屽垯鍦╳ait姣鍐呯殑缁撴潫澶勬墽琛�
+        timer = setTimeout(() => {
+            flag = false
+            typeof func === 'function' && func()
+        }, wait)
+    }
+}
+export default throttle
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js b/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js
new file mode 100644
index 0000000..31a5cfc
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js
@@ -0,0 +1,132 @@
+import buildURL from '../helpers/buildURL'
+import buildFullPath from '../core/buildFullPath'
+import settle from '../core/settle'
+import {isUndefined} from "../utils"
+
+/**
+ * 杩斿洖鍙�夊�煎瓨鍦ㄧ殑閰嶇疆
+ * @param {Array} keys - 鍙�夊�兼暟缁�
+ * @param {Object} config2 - 閰嶇疆
+ * @return {{}} - 瀛樺湪鐨勯厤缃」
+ */
+const mergeKeys = (keys, config2) => {
+  let config = {}
+  keys.forEach(prop => {
+    if (!isUndefined(config2[prop])) {
+      config[prop] = config2[prop]
+    }
+  })
+  return config
+}
+export default (config) => {
+  return new Promise((resolve, reject) => {
+    let fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params, config.paramsSerializer)
+    const _config = {
+      url: fullPath,
+      header: config.header,
+      complete: (response) => {
+        config.fullPath = fullPath
+        response.config = config
+        response.rawData = response.data
+        try {
+          let jsonParseHandle = false
+          const forcedJSONParsingType = typeof config.forcedJSONParsing
+          if (forcedJSONParsingType === 'boolean') {
+            jsonParseHandle = config.forcedJSONParsing
+          } else if (forcedJSONParsingType === 'object') {
+            const includesMethod = config.forcedJSONParsing.include || []
+            jsonParseHandle = includesMethod.includes(config.method)
+          }
+
+          // 瀵瑰彲鑳藉瓧绗︿覆涓嶆槸json 鐨勬儏鍐靛閿�
+          if (jsonParseHandle && typeof response.data === 'string') {
+            response.data = JSON.parse(response.data)
+          }
+          // eslint-disable-next-line no-empty
+        } catch (e) {
+        }
+        settle(resolve, reject, response)
+      }
+    }
+    let requestTask
+    if (config.method === 'UPLOAD') {
+      delete _config.header['content-type']
+      delete _config.header['Content-Type']
+      let otherConfig = {
+        // #ifdef MP-ALIPAY
+        fileType: config.fileType,
+        // #endif
+        filePath: config.filePath,
+        name: config.name
+      }
+      const optionalKeys = [
+        // #ifdef APP-PLUS || H5
+        'files',
+        // #endif
+        // #ifdef H5
+        'file',
+        // #endif
+        // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+        'timeout',
+        // #endif
+        'formData'
+      ]
+      requestTask = uni.uploadFile({..._config, ...otherConfig, ...mergeKeys(optionalKeys, config)})
+    } else if (config.method === 'DOWNLOAD') {
+      const optionalKeys = [
+        // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+        'timeout',
+        // #endif
+        // #ifdef MP
+        'filePath',
+        // #endif
+      ]
+      requestTask = uni.downloadFile({..._config, ...mergeKeys(optionalKeys, config)})
+    } else {
+      const optionalKeys = [
+        'data',
+        'method',
+        // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+        'timeout',
+        // #endif
+        'dataType',
+        // #ifndef MP-ALIPAY
+        'responseType',
+        // #endif
+        // #ifdef APP-PLUS
+        'sslVerify',
+        // #endif
+        // #ifdef H5
+        'withCredentials',
+        // #endif
+        // #ifdef APP-PLUS
+        'firstIpv4',
+        // #endif
+        // #ifdef MP-WEIXIN
+        'enableHttp2',
+        'enableQuic',
+        // #endif
+        // #ifdef MP-TOUTIAO || MP-WEIXIN
+        'enableCache',
+        // #endif
+        // #ifdef MP-WEIXIN
+        'enableHttpDNS',
+        'httpDNSServiceId',
+        'enableChunked',
+        'forceCellularNetwork',
+        // #endif
+        // #ifdef MP-ALIPAY
+        'enableCookie',
+        // #endif
+        // #ifdef MP-BAIDU
+        'cloudCache',
+        'defer'
+        // #endif
+      ]
+      requestTask = uni.request({..._config, ...mergeKeys(optionalKeys, config)})
+    }
+    if (config.getTask) {
+      config.getTask(requestTask, config)
+    }
+  })
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js b/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js
new file mode 100644
index 0000000..3ea0d5e
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js
@@ -0,0 +1,51 @@
+'use strict'
+
+
+function InterceptorManager() {
+  this.handlers = []
+}
+
+/**
+ * Add a new interceptor to the stack
+ *
+ * @param {Function} fulfilled The function to handle `then` for a `Promise`
+ * @param {Function} rejected The function to handle `reject` for a `Promise`
+ *
+ * @return {Number} An ID used to remove interceptor later
+ */
+InterceptorManager.prototype.use = function use(fulfilled, rejected) {
+  this.handlers.push({
+    fulfilled: fulfilled,
+    rejected: rejected
+  })
+  return this.handlers.length - 1
+}
+
+/**
+ * Remove an interceptor from the stack
+ *
+ * @param {Number} id The ID that was returned by `use`
+ */
+InterceptorManager.prototype.eject = function eject(id) {
+  if (this.handlers[id]) {
+    this.handlers[id] = null
+  }
+}
+
+/**
+ * Iterate over all the registered interceptors
+ *
+ * This method is particularly useful for skipping over any
+ * interceptors that may have become `null` calling `eject`.
+ *
+ * @param {Function} fn The function to call for each interceptor
+ */
+InterceptorManager.prototype.forEach = function forEach(fn) {
+  this.handlers.forEach(h => {
+    if (h !== null) {
+      fn(h)
+    }
+  })
+}
+
+export default InterceptorManager
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js b/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js
new file mode 100644
index 0000000..96c89a8
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js
@@ -0,0 +1,201 @@
+/**
+ * @Class Request
+ * @description luch-request http璇锋眰鎻掍欢
+ * @Author lu-ch
+ * @Email webwork.s@qq.com
+ * 鏂囨。: https://www.quanzhan.co/luch-request/
+ * github: https://github.com/lei-mu/luch-request
+ * DCloud: http://ext.dcloud.net.cn/plugin?id=392
+ */
+
+
+import dispatchRequest from './dispatchRequest'
+import InterceptorManager from './InterceptorManager'
+import mergeConfig from './mergeConfig'
+import defaults from './defaults'
+import { isPlainObject } from '../utils'
+import clone from '../utils/clone'
+
+export default class Request {
+  /**
+   * @param {Object} arg - 鍏ㄥ眬閰嶇疆
+   * @param {String} arg.baseURL - 鍏ㄥ眬鏍硅矾寰�
+   * @param {Object} arg.header - 鍏ㄥ眬header
+   * @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 鍏ㄥ眬榛樿璇锋眰鏂瑰紡
+   * @param {String} arg.dataType = [json] - 鍏ㄥ眬榛樿鐨刣ataType
+   * @param {String} arg.responseType = [text|arraybuffer] - 鍏ㄥ眬榛樿鐨剅esponseType銆傛敮浠樺疂灏忕▼搴忎笉鏀寔
+   * @param {Object} arg.custom - 鍏ㄥ眬榛樿鐨勮嚜瀹氫箟鍙傛暟
+   * @param {Number} arg.timeout - 鍏ㄥ眬榛樿鐨勮秴鏃舵椂闂达紝鍗曚綅 ms銆傞粯璁�60000銆侶5(HBuilderX 2.9.9+)銆丄PP(HBuilderX 2.9.9+)銆佸井淇″皬绋嬪簭锛�2.10.0锛夈�佹敮浠樺疂灏忕▼搴�
+   * @param {Boolean} arg.sslVerify - 鍏ㄥ眬榛樿鐨勬槸鍚﹂獙璇� ssl 璇佷功銆傞粯璁rue.浠匒pp瀹夊崜绔敮鎸侊紙HBuilderX 2.3.3+锛�
+   * @param {Boolean} arg.withCredentials - 鍏ㄥ眬榛樿鐨勮法鍩熻姹傛椂鏄惁鎼哄甫鍑瘉锛坈ookies锛夈�傞粯璁alse銆備粎H5鏀寔锛圚BuilderX 2.6.15+锛�
+   * @param {Boolean} arg.firstIpv4 - 鍏―NS瑙f瀽鏃朵紭鍏堜娇鐢╥pv4銆傞粯璁alse銆備粎 App-Android 鏀寔 (HBuilderX 2.8.0+)
+   * @param {Function(statusCode):Boolean} arg.validateStatus - 鍏ㄥ眬榛樿鐨勮嚜瀹氫箟楠岃瘉鍣ㄣ�傞粯璁tatusCode >= 200 && statusCode < 300
+   */
+  constructor(arg = {}) {
+    if (!isPlainObject(arg)) {
+      arg = {}
+      console.warn('璁剧疆鍏ㄥ眬鍙傛暟蹇呴』鎺ユ敹涓�涓狾bject')
+    }
+    this.config = clone({...defaults, ...arg})
+    this.interceptors = {
+      request: new InterceptorManager(),
+      response: new InterceptorManager()
+    }
+  }
+
+  /**
+   * @Function
+   * @param {Request~setConfigCallback} f - 璁剧疆鍏ㄥ眬榛樿閰嶇疆
+   */
+  setConfig(f) {
+    this.config = f(this.config)
+  }
+
+  middleware(config) {
+    config = mergeConfig(this.config, config)
+    let chain = [dispatchRequest, undefined]
+    let promise = Promise.resolve(config)
+
+    this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
+      chain.unshift(interceptor.fulfilled, interceptor.rejected)
+    })
+
+    this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
+      chain.push(interceptor.fulfilled, interceptor.rejected)
+    })
+
+    while (chain.length) {
+      promise = promise.then(chain.shift(), chain.shift())
+    }
+
+    return promise
+  }
+
+  /**
+   * @Function
+   * @param {Object} config - 璇锋眰閰嶇疆椤�
+   * @prop {String} options.url - 璇锋眰璺緞
+   * @prop {Object} options.data - 璇锋眰鍙傛暟
+   * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 鍝嶅簲鐨勬暟鎹被鍨�
+   * @prop {Object} [options.dataType = config.dataType] - 濡傛灉璁句负 json锛屼細灏濊瘯瀵硅繑鍥炵殑鏁版嵁鍋氫竴娆� JSON.parse
+   * @prop {Object} [options.header = config.header] - 璇锋眰header
+   * @prop {Object} [options.method = config.method] - 璇锋眰鏂规硶
+   * @returns {Promise<unknown>}
+   */
+  request(config = {}) {
+    return this.middleware(config)
+  }
+
+  get(url, options = {}) {
+    return this.middleware({
+      url,
+      method: 'GET',
+      ...options
+    })
+  }
+
+  post(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'POST',
+      ...options
+    })
+  }
+
+  // #ifndef MP-ALIPAY || MP-KUAISHOU || MP-JD
+  put(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'PUT',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+  delete(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'DELETE',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef H5 || MP-WEIXIN
+  connect(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'CONNECT',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef  H5 || MP-WEIXIN || MP-BAIDU
+  head(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'HEAD',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+  options(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'OPTIONS',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef H5 || MP-WEIXIN
+  trace(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'TRACE',
+      ...options
+    })
+  }
+
+  // #endif
+
+  upload(url, config = {}) {
+    config.url = url
+    config.method = 'UPLOAD'
+    return this.middleware(config)
+  }
+
+  download(url, config = {}) {
+    config.url = url
+    config.method = 'DOWNLOAD'
+    return this.middleware(config)
+  }
+
+  get version () {
+    return '3.1.0'
+  }
+}
+
+
+/**
+ * setConfig鍥炶皟
+ * @return {Object} - 杩斿洖鎿嶄綔鍚庣殑config
+ * @callback Request~setConfigCallback
+ * @param {Object} config - 鍏ㄥ眬榛樿config
+ */
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js b/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js
new file mode 100644
index 0000000..f2852f4
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js
@@ -0,0 +1,20 @@
+'use strict'
+
+import isAbsoluteURL from '../helpers/isAbsoluteURL'
+import combineURLs from '../helpers/combineURLs'
+
+/**
+ * Creates a new URL by combining the baseURL with the requestedURL,
+ * only when the requestedURL is not already an absolute URL.
+ * If the requestURL is absolute, this function returns the requestedURL untouched.
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} requestedURL Absolute or relative URL to combine
+ * @returns {string} The combined full path
+ */
+export default function buildFullPath(baseURL, requestedURL) {
+  if (baseURL && !isAbsoluteURL(requestedURL)) {
+    return combineURLs(baseURL, requestedURL)
+  }
+  return requestedURL
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js b/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js
new file mode 100644
index 0000000..db74609
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js
@@ -0,0 +1,33 @@
+/**
+ * 榛樿鐨勫叏灞�閰嶇疆
+ */
+
+
+export default {
+  baseURL: '',
+  header: {},
+  method: 'GET',
+  dataType: 'json',
+  paramsSerializer: null,
+  // #ifndef MP-ALIPAY
+  responseType: 'text',
+  // #endif
+  custom: {},
+  // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+  timeout: 60000,
+  // #endif
+  // #ifdef APP-PLUS
+  sslVerify: true,
+  // #endif
+  // #ifdef H5
+  withCredentials: false,
+  // #endif
+  // #ifdef APP-PLUS
+  firstIpv4: false,
+  // #endif
+  validateStatus: function validateStatus(status) {
+    return status >= 200 && status < 300
+  },
+  // 鏄惁灏濊瘯灏嗗搷搴旀暟鎹甹son鍖�
+  forcedJSONParsing: true
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js b/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js
new file mode 100644
index 0000000..c5f2c85
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js
@@ -0,0 +1,6 @@
+import adapter from '../adapters/index'
+
+
+export default (config) => {
+  return adapter(config)
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js b/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js
new file mode 100644
index 0000000..99c8ecd
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js
@@ -0,0 +1,126 @@
+import {deepMerge, isUndefined} from '../utils'
+
+/**
+ * 鍚堝苟灞�閮ㄩ厤缃紭鍏堢殑閰嶇疆锛屽鏋滃眬閮ㄦ湁璇ラ厤缃」鍒欑敤灞�閮紝濡傛灉鍏ㄥ眬鏈夎閰嶇疆椤瑰垯鐢ㄥ叏灞�
+ * @param {Array} keys - 閰嶇疆椤�
+ * @param {Object} globalsConfig - 褰撳墠鐨勫叏灞�閰嶇疆
+ * @param {Object} config2 - 灞�閮ㄩ厤缃�
+ * @return {{}}
+ */
+const mergeKeys = (keys, globalsConfig, config2) => {
+  let config = {}
+  keys.forEach(prop => {
+    if (!isUndefined(config2[prop])) {
+      config[prop] = config2[prop]
+    } else if (!isUndefined(globalsConfig[prop])) {
+      config[prop] = globalsConfig[prop]
+    }
+  })
+  return config
+}
+/**
+ *
+ * @param globalsConfig - 褰撳墠瀹炰緥鐨勫叏灞�閰嶇疆
+ * @param config2 - 褰撳墠鐨勫眬閮ㄩ厤缃�
+ * @return - 鍚堝苟鍚庣殑閰嶇疆
+ */
+export default (globalsConfig, config2 = {}) => {
+  const method = config2.method || globalsConfig.method || 'GET'
+  let config = {
+    baseURL: config2.baseURL || globalsConfig.baseURL || '',
+    method: method,
+    url: config2.url || '',
+    params: config2.params || {},
+    custom: {...(globalsConfig.custom || {}), ...(config2.custom || {})},
+    header: deepMerge(globalsConfig.header || {}, config2.header || {})
+  }
+  const defaultToConfig2Keys = ['getTask', 'validateStatus', 'paramsSerializer', 'forcedJSONParsing']
+  config = {...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2)}
+
+  // eslint-disable-next-line no-empty
+  if (method === 'DOWNLOAD') {
+    const downloadKeys = [
+      // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+      'timeout',
+      // #endif
+      // #ifdef MP
+      'filePath',
+      // #endif
+    ]
+    config = {...config, ...mergeKeys(downloadKeys, globalsConfig, config2)}
+  } else if (method === 'UPLOAD') {
+    delete config.header['content-type']
+    delete config.header['Content-Type']
+    const uploadKeys = [
+      // #ifdef APP-PLUS || H5
+      'files',
+      // #endif
+      // #ifdef MP-ALIPAY
+      'fileType',
+      // #endif
+      // #ifdef H5
+      'file',
+      // #endif
+      'filePath',
+      'name',
+      // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+      'timeout',
+      // #endif
+      'formData',
+    ]
+    uploadKeys.forEach(prop => {
+      if (!isUndefined(config2[prop])) {
+        config[prop] = config2[prop]
+      }
+    })
+    // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+    if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) {
+      config['timeout'] = globalsConfig['timeout']
+    }
+    // #endif
+  } else {
+    const defaultsKeys = [
+      'data',
+      // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+      'timeout',
+      // #endif
+      'dataType',
+      // #ifndef MP-ALIPAY
+      'responseType',
+      // #endif
+      // #ifdef APP-PLUS
+      'sslVerify',
+      // #endif
+      // #ifdef H5
+      'withCredentials',
+      // #endif
+      // #ifdef APP-PLUS
+      'firstIpv4',
+      // #endif
+      // #ifdef MP-WEIXIN
+      'enableHttp2',
+      'enableQuic',
+      // #endif
+      // #ifdef MP-TOUTIAO || MP-WEIXIN
+      'enableCache',
+      // #endif
+      // #ifdef MP-WEIXIN
+      'enableHttpDNS',
+      'httpDNSServiceId',
+      'enableChunked',
+      'forceCellularNetwork',
+      // #endif
+      // #ifdef MP-ALIPAY
+      'enableCookie',
+      // #endif
+      // #ifdef MP-BAIDU
+      'cloudCache',
+      'defer'
+      // #endif
+
+    ]
+    config = {...config, ...mergeKeys(defaultsKeys, globalsConfig, config2)}
+  }
+
+  return config
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js b/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js
new file mode 100644
index 0000000..b2f1659
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js
@@ -0,0 +1,16 @@
+/**
+ * Resolve or reject a Promise based on response status.
+ *
+ * @param {Function} resolve A function that resolves the promise.
+ * @param {Function} reject A function that rejects the promise.
+ * @param {object} response The response.
+ */
+export default function settle(resolve, reject, response) {
+  const validateStatus = response.config.validateStatus
+  const status = response.statusCode
+  if (status && (!validateStatus || validateStatus(status))) {
+    resolve(response)
+  } else {
+    reject(response)
+  }
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js b/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js
new file mode 100644
index 0000000..e90b908
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js
@@ -0,0 +1,64 @@
+'use strict'
+
+import * as utils from './../utils'
+
+function encode(val) {
+  return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']')
+}
+
+/**
+ * Build a URL by appending params to the end
+ *
+ * @param {string} url The base of the url (e.g., http://www.google.com)
+ * @param {object} [params] The params to be appended
+ * @returns {string} The formatted url
+ */
+export default function buildURL(url, params, paramsSerializer) {
+  /*eslint no-param-reassign:0*/
+  if (!params) {
+    return url
+  }
+
+  var serializedParams
+  if (paramsSerializer) {
+    serializedParams = paramsSerializer(params)
+  } else if (utils.isURLSearchParams(params)) {
+    serializedParams = params.toString()
+  } else {
+    var parts = []
+
+    utils.forEach(params, function serialize(val, key) {
+      if (val === null || typeof val === 'undefined') {
+        return
+      }
+
+      if (utils.isArray(val)) {
+        key = key + '[]'
+      } else {
+        val = [val]
+      }
+
+      utils.forEach(val, function parseValue(v) {
+        if (utils.isDate(v)) {
+          v = v.toISOString()
+        } else if (utils.isObject(v)) {
+          v = JSON.stringify(v)
+        }
+        parts.push(encode(key) + '=' + encode(v))
+      })
+    })
+
+    serializedParams = parts.join('&')
+  }
+
+  if (serializedParams) {
+    var hashmarkIndex = url.indexOf('#')
+    if (hashmarkIndex !== -1) {
+      url = url.slice(0, hashmarkIndex)
+    }
+
+    url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
+  }
+
+  return url
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js b/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js
new file mode 100644
index 0000000..7b9d1ef
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js
@@ -0,0 +1,14 @@
+'use strict'
+
+/**
+ * Creates a new URL by combining the specified URLs
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} relativeURL The relative URL
+ * @returns {string} The combined URL
+ */
+export default function combineURLs(baseURL, relativeURL) {
+  return relativeURL
+    ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
+    : baseURL
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js b/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js
new file mode 100644
index 0000000..2a82517
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js
@@ -0,0 +1,14 @@
+'use strict'
+
+/**
+ * Determines whether the specified URL is absolute
+ *
+ * @param {string} url The URL to test
+ * @returns {boolean} True if the specified URL is absolute, otherwise false
+ */
+export default function isAbsoluteURL(url) {
+  // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
+  // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
+  // by any combination of letters, digits, plus, period, or hyphen.
+  return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts b/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts
new file mode 100644
index 0000000..62d3fb9
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts
@@ -0,0 +1,197 @@
+export type HttpTask = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask;
+
+export type HttpRequestTask = UniApp.RequestTask;
+
+export type HttpUploadTask = UniApp.UploadTask;
+
+export type HttpDownloadTask = UniApp.DownloadTask;
+
+export type HttpMethod =
+    "GET"
+    | "POST"
+    | "PUT"
+    | "DELETE"
+    | "CONNECT"
+    | "HEAD"
+    | "OPTIONS"
+    | "TRACE"
+    | "UPLOAD"
+    | "DOWNLOAD";
+
+export type HttpRequestHeader = Record<string, string>;
+
+export type HttpParams = Record<string, any>;
+
+export type HttpData = Record<string, any>;
+
+export type HttpResponseType = 'arraybuffer' | 'text';
+
+export type HttpCustom = Record<string, any>;
+
+export type HttpFileType = 'image' | 'video' | 'audio';
+
+export type HttpFormData = Record<string, any>;
+
+export type HttpResponseHeader = Record<string, string> & {
+    "set-cookie"?: string[]
+};
+
+export interface HttpRequestConfig<T = HttpTask> {
+    /** @desc 璇锋眰鏈嶅姟鍣ㄦ帴鍙e湴鍧� */
+    url?: string;
+    /** @desc 璇锋眰鏂瑰紡锛岄粯璁や负 GET */
+    method?: HttpMethod;
+    /** @desc 璇锋眰鍩哄湴鍧� */
+    baseURL?: string;
+    /** @desc 璇锋眰澶翠俊鎭紝涓嶈兘璁剧疆 Referer锛孉pp銆丠5 绔細鑷姩甯︿笂 cookie锛屼笖 H5 绔笉鍙墜鍔ㄤ慨鏀� */
+    header?: HttpRequestHeader;
+    /** @desc 璇锋眰鏌ヨ鍙傛暟锛岃嚜鍔ㄦ嫾鎺ヤ负鏌ヨ瀛楃涓� */
+    params?: HttpParams;
+    /** @desc 璇锋眰浣撳弬鏁� */
+    data?: HttpData;
+    /** @desc 瓒呮椂鏃堕棿锛屽崟浣� ms锛岄粯璁や负 60000锛屼粎 H5 (HBuilderX 2.9.9+)銆丄PP (HBuilderX 2.9.9+)銆佸井淇″皬绋嬪簭 (2.10.0)銆佹敮浠樺疂灏忕▼搴忔敮鎸� */
+    timeout?: number;
+    /** @desc 璺ㄥ煙璇锋眰鏃舵槸鍚︽惡甯﹀嚟璇� (cookies)锛岄粯璁や负 false锛屼粎 H5 (HBuilderX 2.6.15+) 鏀寔 */
+    withCredentials?: boolean;
+    /** @desc 璁剧疆鍝嶅簲鐨勬暟鎹被鍨嬶紝鏀粯瀹濆皬绋嬪簭涓嶆敮鎸� */
+    responseType?: HttpResponseType;
+    /** @desc 鍏ㄥ眬鑷畾涔夐獙璇佸櫒 */
+    validateStatus?: ((statusCode: number) => boolean) | null;
+
+
+    /** params 鍙傛暟鑷畾涔夊鐞� */
+    paramsSerializer?: (params: AnyObject) => string | void;
+
+    /** @desc 榛樿涓� json锛屽鏋滆涓� json锛屼細灏濊瘯瀵硅繑鍥炵殑鏁版嵁鍋氫竴娆� JSON.parse */
+    dataType?: string;
+    /** @desc DNS 瑙f瀽鏃舵槸鍚︿紭鍏堜娇鐢� ipv4锛岄粯璁や负 false锛屼粎 App-Android (HBuilderX 2.8.0+) 鏀寔 */
+    firstIpv4?: boolean;
+    /** @desc 鏄惁楠岃瘉 SSL 璇佷功锛岄粯璁や负 true锛屼粎 App-Android (HBuilderX 2.3.3+) 鏀寔 */
+    sslVerify?: boolean;
+
+    /** @desc 寮�鍚� http2;寰俊灏忕▼搴� */
+    enableHttp2?: boolean;
+
+    /** @desc 寮�鍚� quic锛涘井淇″皬绋嬪簭 */
+    enableQuic?: boolean;
+    /** @desc 寮�鍚� cache;寰俊灏忕▼搴忋�佸瓧鑺傝烦鍔ㄥ皬绋嬪簭 2.31.0+ */
+    enableCache?: boolean;
+    /** @desc 寮�鍚� httpDNS;寰俊灏忕▼搴� */
+    enableHttpDNS?: boolean;
+    /** @desc httpDNS 鏈嶅姟鍟嗭紱寰俊灏忕▼搴� */
+    httpDNSServiceId?: string;
+    /** @desc 寮�鍚� transfer-encoding chunked;寰俊灏忕▼搴� */
+    enableChunked?: boolean;
+    /** @desc wifi涓嬩娇鐢ㄧЩ鍔ㄧ綉缁滃彂閫佽姹�;寰俊灏忕▼搴� */
+    forceCellularNetwork?: boolean;
+    /** @desc 寮�鍚悗鍙湪headers涓紪杈慶ookie;鏀粯瀹濆皬绋嬪簭 10.2.33+ */
+    enableCookie?: boolean;
+    /** @desc 鏄惁寮�鍚簯鍔犻��;鐧惧害灏忕▼搴� 3.310.11+ */
+    cloudCache?: boolean | object;
+    /** @desc 鎺у埗褰撳墠璇锋眰鏄惁寤舵椂鑷抽灞忓唴瀹规覆鏌撳悗鍙戦�侊紱鐧惧害灏忕▼搴� 3.310.11+ */
+    defer?: boolean;
+
+    /** @desc 鑷畾涔夊弬鏁� */
+    custom?: HttpCustom;
+
+    /** @desc 杩斿洖褰撳墠璇锋眰鐨� task 鍜� options锛屼笉瑕佸湪杩欓噷淇敼 options */
+    getTask?: (task: T, options: HttpRequestConfig<T>) => void;
+
+    /** @desc 闇�瑕佷笂浼犵殑鏂囦欢鍒楄〃锛屼娇鐢� files 鏃讹紝filePath 鍜� name 涓嶇敓鏁堬紝浠呮敮鎸� App銆丠5 (2.6.15+) */
+    files?: { name?: string; file?: File; uri: string; }[];
+    /** @desc 鏂囦欢绫诲瀷锛屼粎鏀粯瀹濆皬绋嬪簭鏀寔涓斾负蹇呭~椤� */
+    fileType?: HttpFileType;
+    /** @desc 瑕佷笂浼犵殑鏂囦欢瀵硅薄锛屼粎 H5 (2.6.15+) 鏀寔 */
+    file?: File;
+    /** @desc 瑕佷笂浼犳枃浠惰祫婧愮殑璺緞锛屼娇鐢� files 鏃讹紝filePath 鍜� name 涓嶇敓鏁� */
+    filePath?: string;
+    /** @desc 鏂囦欢瀵瑰簲鐨� key锛屽紑鍙戣�呭湪鏈嶅姟鍣ㄧ閫氳繃杩欎釜 key 鍙互鑾峰彇鍒版枃浠朵簩杩涘埗鍐呭锛屼娇鐢� files 鏃讹紝filePath 鍜� name 涓嶇敓鏁� */
+    name?: string;
+    /** @desc 璇锋眰涓叾浠栭澶栫殑 form data */
+    formData?: HttpFormData;
+}
+
+export interface HttpResponse<T = any, D = HttpTask> {
+    data: T;
+    statusCode: number;
+    header: HttpResponseHeader;
+    config: HttpRequestConfig<D>;
+    cookies: string[];
+    errMsg: string;
+    rawData: any;
+}
+
+export interface HttpUploadResponse<T = any, D = HttpTask> {
+    data: T;
+    statusCode: number;
+    config: HttpRequestConfig<D>;
+    errMsg: string;
+    rawData: any;
+}
+
+export interface HttpDownloadResponse extends HttpResponse {
+    tempFilePath: string;
+    apFilePath?: string;
+    filePath?: string;
+    fileContent?: string;
+}
+
+export interface HttpError<T = any, D = HttpTask> {
+    data?: T;
+    statusCode?: number;
+    header?: HttpResponseHeader;
+    config: HttpRequestConfig<D>;
+    cookies?: string[];
+    errMsg: string;
+}
+
+export interface HttpPromise<T = any> extends Promise<HttpResponse<T>> {
+}
+
+export interface HttpInterceptorManager<V, E = V> {
+    use(onFulfilled?: (value: V) => V | Promise<V>, onRejected?: (error: E) => T | Promise<E>): void;
+
+    eject(id: number): void;
+}
+
+export abstract class HttpRequestAbstract {
+    constructor(config?: HttpRequestConfig);
+
+    interceptors: {
+        request: HttpInterceptorManager<HttpRequestConfig>;
+        response: HttpInterceptorManager<HttpResponse, HttpError>;
+    }
+
+    request<T = any, R = HttpResponse<T>, D = HttpRequestTask>(config: HttpRequestConfig<D>): Promise<R>;
+
+    get<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
+
+    delete<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    head<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    options<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    post<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    put<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    config: HttpRequestConfig;
+
+    setConfig<D = HttpTask>(onSend: (config: HttpRequestConfig<D>) => HttpRequestConfig<D>): void;
+
+    connect<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    trace<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    upload<T = any, R = HttpUploadResponse<T>, D = HttpUploadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
+
+    download<T = any, R = HttpDownloadResponse<T>, D = HttpDownloadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
+
+    middleware<T = any, R = HttpResponse<T>, D = HttpTask>(config: HttpRequestConfig<D>): Promise<R>;
+}
+
+declare class HttpRequest extends HttpRequestAbstract {
+}
+
+export default HttpRequest;
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/index.js b/uni_modules/uv-ui-tools/libs/luch-request/index.js
new file mode 100644
index 0000000..d8fe348
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/index.js
@@ -0,0 +1,2 @@
+import Request from './core/Request'
+export default Request
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/utils.js b/uni_modules/uv-ui-tools/libs/luch-request/utils.js
new file mode 100644
index 0000000..0b5bf21
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/utils.js
@@ -0,0 +1,135 @@
+'use strict'
+
+// utils is a library of generic helper functions non-specific to axios
+
+var toString = Object.prototype.toString
+
+/**
+ * Determine if a value is an Array
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is an Array, otherwise false
+ */
+export function isArray (val) {
+  return toString.call(val) === '[object Array]'
+}
+
+
+/**
+ * Determine if a value is an Object
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is an Object, otherwise false
+ */
+export function isObject (val) {
+  return val !== null && typeof val === 'object'
+}
+
+/**
+ * Determine if a value is a Date
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is a Date, otherwise false
+ */
+export function isDate (val) {
+  return toString.call(val) === '[object Date]'
+}
+
+/**
+ * Determine if a value is a URLSearchParams object
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is a URLSearchParams object, otherwise false
+ */
+export function isURLSearchParams (val) {
+  return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
+}
+
+
+/**
+ * Iterate over an Array or an Object invoking a function for each item.
+ *
+ * If `obj` is an Array callback will be called passing
+ * the value, index, and complete array for each item.
+ *
+ * If 'obj' is an Object callback will be called passing
+ * the value, key, and complete object for each property.
+ *
+ * @param {Object|Array} obj The object to iterate
+ * @param {Function} fn The callback to invoke for each item
+ */
+export function forEach (obj, fn) {
+  // Don't bother if no value provided
+  if (obj === null || typeof obj === 'undefined') {
+    return
+  }
+
+  // Force an array if not already something iterable
+  if (typeof obj !== 'object') {
+    /*eslint no-param-reassign:0*/
+    obj = [obj]
+  }
+
+  if (isArray(obj)) {
+    // Iterate over array values
+    for (var i = 0, l = obj.length; i < l; i++) {
+      fn.call(null, obj[i], i, obj)
+    }
+  } else {
+    // Iterate over object keys
+    for (var key in obj) {
+      if (Object.prototype.hasOwnProperty.call(obj, key)) {
+        fn.call(null, obj[key], key, obj)
+      }
+    }
+  }
+}
+
+/**
+ * 鏄惁涓篵oolean 鍊�
+ * @param val
+ * @returns {boolean}
+ */
+export function isBoolean(val) {
+  return typeof val === 'boolean'
+}
+
+/**
+ * 鏄惁涓虹湡姝g殑瀵硅薄{} new Object
+ * @param {any} obj - 妫�娴嬬殑瀵硅薄
+ * @returns {boolean}
+ */
+export function isPlainObject(obj) {
+  return Object.prototype.toString.call(obj) === '[object Object]'
+}
+
+
+
+/**
+ * Function equal to merge with the difference being that no reference
+ * to original objects is kept.
+ *
+ * @see merge
+ * @param {Object} obj1 Object to merge
+ * @returns {Object} Result of all merge properties
+ */
+export function deepMerge(/* obj1, obj2, obj3, ... */) {
+  let result = {}
+  function assignValue(val, key) {
+    if (typeof result[key] === 'object' && typeof val === 'object') {
+      result[key] = deepMerge(result[key], val)
+    } else if (typeof val === 'object') {
+      result[key] = deepMerge({}, val)
+    } else {
+      result[key] = val
+    }
+  }
+  for (let i = 0, l = arguments.length; i < l; i++) {
+    forEach(arguments[i], assignValue)
+  }
+  return result
+}
+
+export function isUndefined (val) {
+  return typeof val === 'undefined'
+}
diff --git a/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js b/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js
new file mode 100644
index 0000000..2fee704
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js
@@ -0,0 +1,264 @@
+/* eslint-disable */
+var clone = (function() {
+  'use strict';
+
+  function _instanceof(obj, type) {
+    return type != null && obj instanceof type;
+  }
+
+  var nativeMap;
+  try {
+    nativeMap = Map;
+  } catch(_) {
+    // maybe a reference error because no `Map`. Give it a dummy value that no
+    // value will ever be an instanceof.
+    nativeMap = function() {};
+  }
+
+  var nativeSet;
+  try {
+    nativeSet = Set;
+  } catch(_) {
+    nativeSet = function() {};
+  }
+
+  var nativePromise;
+  try {
+    nativePromise = Promise;
+  } catch(_) {
+    nativePromise = function() {};
+  }
+
+  /**
+   * Clones (copies) an Object using deep copying.
+   *
+   * This function supports circular references by default, but if you are certain
+   * there are no circular references in your object, you can save some CPU time
+   * by calling clone(obj, false).
+   *
+   * Caution: if `circular` is false and `parent` contains circular references,
+   * your program may enter an infinite loop and crash.
+   *
+   * @param `parent` - the object to be cloned
+   * @param `circular` - set to true if the object to be cloned may contain
+   *    circular references. (optional - true by default)
+   * @param `depth` - set to a number if the object is only to be cloned to
+   *    a particular depth. (optional - defaults to Infinity)
+   * @param `prototype` - sets the prototype to be used when cloning an object.
+   *    (optional - defaults to parent prototype).
+   * @param `includeNonEnumerable` - set to true if the non-enumerable properties
+   *    should be cloned as well. Non-enumerable properties on the prototype
+   *    chain will be ignored. (optional - false by default)
+   */
+  function clone(parent, circular, depth, prototype, includeNonEnumerable) {
+    if (typeof circular === 'object') {
+      depth = circular.depth;
+      prototype = circular.prototype;
+      includeNonEnumerable = circular.includeNonEnumerable;
+      circular = circular.circular;
+    }
+    // maintain two arrays for circular references, where corresponding parents
+    // and children have the same index
+    var allParents = [];
+    var allChildren = [];
+
+    var useBuffer = typeof Buffer != 'undefined';
+
+    if (typeof circular == 'undefined')
+      circular = true;
+
+    if (typeof depth == 'undefined')
+      depth = Infinity;
+
+    // recurse this function so we don't reset allParents and allChildren
+    function _clone(parent, depth) {
+      // cloning null always returns null
+      if (parent === null)
+        return null;
+
+      if (depth === 0)
+        return parent;
+
+      var child;
+      var proto;
+      if (typeof parent != 'object') {
+        return parent;
+      }
+
+      if (_instanceof(parent, nativeMap)) {
+        child = new nativeMap();
+      } else if (_instanceof(parent, nativeSet)) {
+        child = new nativeSet();
+      } else if (_instanceof(parent, nativePromise)) {
+        child = new nativePromise(function (resolve, reject) {
+          parent.then(function(value) {
+            resolve(_clone(value, depth - 1));
+          }, function(err) {
+            reject(_clone(err, depth - 1));
+          });
+        });
+      } else if (clone.__isArray(parent)) {
+        child = [];
+      } else if (clone.__isRegExp(parent)) {
+        child = new RegExp(parent.source, __getRegExpFlags(parent));
+        if (parent.lastIndex) child.lastIndex = parent.lastIndex;
+      } else if (clone.__isDate(parent)) {
+        child = new Date(parent.getTime());
+      } else if (useBuffer && Buffer.isBuffer(parent)) {
+        if (Buffer.from) {
+          // Node.js >= 5.10.0
+          child = Buffer.from(parent);
+        } else {
+          // Older Node.js versions
+          child = new Buffer(parent.length);
+          parent.copy(child);
+        }
+        return child;
+      } else if (_instanceof(parent, Error)) {
+        child = Object.create(parent);
+      } else {
+        if (typeof prototype == 'undefined') {
+          proto = Object.getPrototypeOf(parent);
+          child = Object.create(proto);
+        }
+        else {
+          child = Object.create(prototype);
+          proto = prototype;
+        }
+      }
+
+      if (circular) {
+        var index = allParents.indexOf(parent);
+
+        if (index != -1) {
+          return allChildren[index];
+        }
+        allParents.push(parent);
+        allChildren.push(child);
+      }
+
+      if (_instanceof(parent, nativeMap)) {
+        parent.forEach(function(value, key) {
+          var keyChild = _clone(key, depth - 1);
+          var valueChild = _clone(value, depth - 1);
+          child.set(keyChild, valueChild);
+        });
+      }
+      if (_instanceof(parent, nativeSet)) {
+        parent.forEach(function(value) {
+          var entryChild = _clone(value, depth - 1);
+          child.add(entryChild);
+        });
+      }
+
+      for (var i in parent) {
+        var attrs = Object.getOwnPropertyDescriptor(parent, i);
+        if (attrs) {
+          child[i] = _clone(parent[i], depth - 1);
+        }
+
+        try {
+          var objProperty = Object.getOwnPropertyDescriptor(parent, i);
+          if (objProperty.set === 'undefined') {
+            // no setter defined. Skip cloning this property
+            continue;
+          }
+          child[i] = _clone(parent[i], depth - 1);
+        } catch(e){
+          if (e instanceof TypeError) {
+            // when in strict mode, TypeError will be thrown if child[i] property only has a getter
+            // we can't do anything about this, other than inform the user that this property cannot be set.
+            continue
+          } else if (e instanceof ReferenceError) {
+            //this may happen in non strict mode
+            continue
+          }
+        }
+
+      }
+
+      if (Object.getOwnPropertySymbols) {
+        var symbols = Object.getOwnPropertySymbols(parent);
+        for (var i = 0; i < symbols.length; i++) {
+          // Don't need to worry about cloning a symbol because it is a primitive,
+          // like a number or string.
+          var symbol = symbols[i];
+          var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
+          if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
+            continue;
+          }
+          child[symbol] = _clone(parent[symbol], depth - 1);
+          Object.defineProperty(child, symbol, descriptor);
+        }
+      }
+
+      if (includeNonEnumerable) {
+        var allPropertyNames = Object.getOwnPropertyNames(parent);
+        for (var i = 0; i < allPropertyNames.length; i++) {
+          var propertyName = allPropertyNames[i];
+          var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
+          if (descriptor && descriptor.enumerable) {
+            continue;
+          }
+          child[propertyName] = _clone(parent[propertyName], depth - 1);
+          Object.defineProperty(child, propertyName, descriptor);
+        }
+      }
+
+      return child;
+    }
+
+    return _clone(parent, depth);
+  }
+
+  /**
+   * Simple flat clone using prototype, accepts only objects, usefull for property
+   * override on FLAT configuration object (no nested props).
+   *
+   * USE WITH CAUTION! This may not behave as you wish if you do not know how this
+   * works.
+   */
+  clone.clonePrototype = function clonePrototype(parent) {
+    if (parent === null)
+      return null;
+
+    var c = function () {};
+    c.prototype = parent;
+    return new c();
+  };
+
+// private utility functions
+
+  function __objToStr(o) {
+    return Object.prototype.toString.call(o);
+  }
+  clone.__objToStr = __objToStr;
+
+  function __isDate(o) {
+    return typeof o === 'object' && __objToStr(o) === '[object Date]';
+  }
+  clone.__isDate = __isDate;
+
+  function __isArray(o) {
+    return typeof o === 'object' && __objToStr(o) === '[object Array]';
+  }
+  clone.__isArray = __isArray;
+
+  function __isRegExp(o) {
+    return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
+  }
+  clone.__isRegExp = __isRegExp;
+
+  function __getRegExpFlags(re) {
+    var flags = '';
+    if (re.global) flags += 'g';
+    if (re.ignoreCase) flags += 'i';
+    if (re.multiline) flags += 'm';
+    return flags;
+  }
+  clone.__getRegExpFlags = __getRegExpFlags;
+
+  return clone;
+})();
+
+export default clone
diff --git a/uni_modules/uv-ui-tools/libs/mixin/button.js b/uni_modules/uv-ui-tools/libs/mixin/button.js
new file mode 100644
index 0000000..0c019c2
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/mixin/button.js
@@ -0,0 +1,13 @@
+export default {
+    props: {
+        lang: String,
+        sessionFrom: String,
+        sendMessageTitle: String,
+        sendMessagePath: String,
+        sendMessageImg: String,
+        showMessageCard: Boolean,
+        appParameter: String,
+        formType: String,
+        openType: String
+    }
+}
diff --git a/uni_modules/uv-ui-tools/libs/mixin/mixin.js b/uni_modules/uv-ui-tools/libs/mixin/mixin.js
new file mode 100644
index 0000000..0dd3b03
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/mixin/mixin.js
@@ -0,0 +1,172 @@
+import * as index from '../function/index.js';
+import * as test from '../function/test.js';
+import route from '../util/route.js';
+import debounce from '../function/debounce.js';
+import throttle from '../function/throttle.js';
+export default {
+	// 瀹氫箟姣忎釜缁勪欢閮藉彲鑳介渶瑕佺敤鍒扮殑澶栭儴鏍峰紡浠ュ強绫诲悕
+	props: {
+		// 姣忎釜缁勪欢閮芥湁鐨勭埗缁勪欢浼犻�掔殑鏍峰紡锛屽彲浠ヤ负瀛楃涓叉垨鑰呭璞″舰寮�
+		customStyle: {
+			type: [Object, String],
+			default: () => ({})
+		},
+		customClass: {
+			type: String,
+			default: ''
+		},
+		// 璺宠浆鐨勯〉闈㈣矾寰�
+		url: {
+			type: String,
+			default: ''
+		},
+		// 椤甸潰璺宠浆鐨勭被鍨�
+		linkType: {
+			type: String,
+			default: 'navigateTo'
+		}
+	},
+	data() {
+		return {}
+	},
+	onLoad() {
+		// getRect鎸傝浇鍒�$uv涓婏紝鍥犱负杩欐柟娉曢渶瑕佷娇鐢╥n(this)锛屾墍浠ユ棤娉曟妸瀹冪嫭绔嬫垚涓�涓崟鐙殑鏂囦欢瀵煎嚭
+		this.$uv.getRect = this.$uvGetRect
+	},
+	created() {
+		// 缁勪欢褰撲腑锛屽彧鏈塩reated澹版槑鍛ㄦ湡锛屼负浜嗚兘鍦ㄧ粍浠朵娇鐢紝鏁呬篃鍦╟reated涓皢鏂规硶鎸傝浇鍒�$uv
+		this.$uv.getRect = this.$uvGetRect
+	},
+	computed: {
+		$uv() {
+			return {
+				...index,
+				test,
+				route,
+				debounce,
+				throttle,
+				unit: uni?.$uv?.config?.unit
+			}
+		},
+		/**
+		 * 鐢熸垚bem瑙勫垯绫诲悕
+		 * 鐢变簬寰俊灏忕▼搴忥紝H5锛宯vue涔嬮棿缁戝畾class鐨勫樊寮傦紝鏃犳硶閫氳繃:class="[bem()]"鐨勫舰寮忚繘琛屽悓鐢�
+		 * 鏁呴噰鐢ㄥ涓嬫姌涓仛娉曪紝鏈�鍚庤繑鍥炵殑鏄暟缁勶紙涓�鑸钩鍙帮級鎴栧瓧绗︿覆锛堟敮浠樺疂鍜屽瓧鑺傝烦鍔ㄥ钩鍙帮級锛岀被浼糩'a', 'b', 'c']鎴�'a b c'鐨勫舰寮�
+		 * @param {String} name 缁勪欢鍚嶇О
+		 * @param {Array} fixed 涓�鐩翠細瀛樺湪鐨勭被鍚�
+		 * @param {Array} change 浼氭牴鎹彉閲忓�间负true鎴栬�協alse鑰屽嚭鐜版垨鑰呴殣钘忕殑绫诲悕
+		 * @returns {Array|string}
+		 */
+		bem() {
+			return function(name, fixed, change) {
+				// 绫诲悕鍓嶇紑
+				const prefix = `uv-${name}--`
+				const classes = {}
+				if (fixed) {
+					fixed.map((item) => {
+						// 杩欓噷鐨勭被鍚嶏紝浼氫竴鐩村瓨鍦�
+						classes[prefix + this[item]] = true
+					})
+				}
+				if (change) {
+					change.map((item) => {
+						// 杩欓噷鐨勭被鍚嶏紝浼氭牴鎹畉his[item]鐨勫�间负true鎴栬�協alse锛岃�岃繘琛屾坊鍔犳垨鑰呯Щ闄ゆ煇涓�涓被
+						this[item] ? (classes[prefix + item] = this[item]) : (delete classes[prefix + item])
+					})
+				}
+				return Object.keys(classes)
+					// 鏀粯瀹濓紝澶存潯灏忕▼搴忔棤娉曞姩鎬佺粦瀹氫竴涓暟缁勭被鍚嶏紝鍚﹀垯瑙f瀽鍑烘潵鐨勭粨鏋滀細甯︽湁","锛岃�屽鑷村け鏁�
+					// #ifdef MP-ALIPAY || MP-TOUTIAO || MP-LARK || MP-BAIDU
+					.join(' ')
+				// #endif
+			}
+		}
+	},
+	methods: {
+		// 璺宠浆鏌愪竴涓〉闈�
+		openPage(urlKey = 'url') {
+			const url = this[urlKey]
+			if (url) {
+				// 鎵ц绫讳技uni.navigateTo鐨勬柟娉�
+				uni[this.linkType]({
+					url
+				})
+			}
+		},
+		// 鏌ヨ鑺傜偣淇℃伅
+		// 鐩墠姝ゆ柟娉曞湪鏀粯瀹濆皬绋嬪簭涓棤娉曡幏鍙栫粍浠惰窡鎺ョ偣鐨勫昂瀵革紝涓烘敮浠樺疂鐨刡ug(2020-07-21)
+		// 瑙e喅鍔炴硶涓哄湪缁勪欢鏍归儴鍐嶅涓�涓病鏈変换浣曚綔鐢ㄧ殑view鍏冪礌
+		$uvGetRect(selector, all) {
+			return new Promise((resolve) => {
+				uni.createSelectorQuery()
+					.in(this)[all ? 'selectAll' : 'select'](selector)
+					.boundingClientRect((rect) => {
+						if (all && Array.isArray(rect) && rect.length) {
+							resolve(rect)
+						}
+						if (!all && rect) {
+							resolve(rect)
+						}
+					})
+					.exec()
+			})
+		},
+		getParentData(parentName = '') {
+			// 閬垮厤鍦╟reated涓幓瀹氫箟parent鍙橀噺
+			if (!this.parent) this.parent = {}
+			// 杩欓噷鐨勬湰璐ㄥ師鐞嗘槸锛岄�氳繃鑾峰彇鐖剁粍浠跺疄渚�(涔熷嵆绫讳技uv-radio鐨勭埗缁勪欢uv-radio-group鐨則his)
+			// 灏嗙埗缁勪欢this涓搴旂殑鍙傛暟锛岃祴鍊肩粰鏈粍浠�(uv-radio鐨則his)鐨刾arentData瀵硅薄涓搴旂殑灞炴��
+			// 涔嬫墍浠ラ渶瑕佽繖涔堝仛锛屾槸鍥犱负鎵�鏈夌涓紝澶存潯灏忕▼搴忎笉鏀寔閫氳繃this.parent.xxx鍘荤洃鍚埗缁勪欢鍙傛暟鐨勫彉鍖�
+			// 姝ゅ骞朵笉浼氳嚜鍔ㄦ洿鏂板瓙缁勪欢鐨勬暟鎹紝鑰屾槸渚濊禆鐖剁粍浠秛v-radio-group鍘荤洃鍚琩ata鐨勫彉鍖栵紝鎵嬪姩璋冪敤鏇存柊瀛愮粍浠剁殑鏂规硶鍘婚噸鏂拌幏鍙�
+			this.parent = this.$uv.$parent.call(this, parentName)
+			if (this.parent.children) {
+				// 濡傛灉鐖剁粍浠剁殑children涓嶅瓨鍦ㄦ湰缁勪欢鐨勫疄渚嬶紝鎵嶅皢鏈疄渚嬫坊鍔犲埌鐖剁粍浠剁殑children涓�
+				this.parent.children.indexOf(this) === -1 && this.parent.children.push(this)
+			}
+			if (this.parent && this.parentData) {
+				// 鍘嗛亶parentData涓殑灞炴�э紝灏唒arent涓殑鍚屽悕灞炴�ц祴鍊肩粰parentData
+				Object.keys(this.parentData).map((key) => {
+					this.parentData[key] = this.parent[key]
+				})
+			}
+		},
+		// 闃绘浜嬩欢鍐掓场
+		preventEvent(e) {
+			e && typeof(e.stopPropagation) === 'function' && e.stopPropagation()
+		},
+		// 绌烘搷浣�
+		noop(e) {
+			this.preventEvent(e)
+		}
+	},
+	onReachBottom() {
+		uni.$emit('uvOnReachBottom')
+	},
+	beforeDestroy() {
+		// 鍒ゆ柇褰撳墠椤甸潰鏄惁瀛樺湪parent鍜宑hldren锛屼竴鑸湪checkbox鍜宑heckbox-group鐖跺瓙鑱斿姩鐨勫満鏅細鏈夋鎯呭喌
+		// 缁勪欢閿�姣佹椂锛岀Щ闄ゅ瓙缁勪欢鍦ㄧ埗缁勪欢children鏁扮粍涓殑瀹炰緥锛岄噴鏀捐祫婧愶紝閬垮厤鏁版嵁娣蜂贡
+		if (this.parent && test.array(this.parent.children)) {
+			// 缁勪欢閿�姣佹椂锛岀Щ闄ょ埗缁勪欢涓殑children鏁扮粍涓搴旂殑瀹炰緥
+			const childrenList = this.parent.children
+			childrenList.map((child, index) => {
+				// 濡傛灉鐩哥瓑锛屽垯绉婚櫎
+				if (child === this) {
+					childrenList.splice(index, 1)
+				}
+			})
+		}
+	},
+	// 鍏煎vue3
+	unmounted() {
+		if (this.parent && test.array(this.parent.children)) {
+			// 缁勪欢閿�姣佹椂锛岀Щ闄ょ埗缁勪欢涓殑children鏁扮粍涓搴旂殑瀹炰緥
+			const childrenList = this.parent.children
+			childrenList.map((child, index) => {
+				// 濡傛灉鐩哥瓑锛屽垯绉婚櫎
+				if (child === this) {
+					childrenList.splice(index, 1)
+				}
+			})
+		}
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js b/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js
new file mode 100644
index 0000000..90b6903
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js
@@ -0,0 +1,8 @@
+export default {
+    // #ifdef MP-WEIXIN
+    // 灏嗚嚜瀹氫箟鑺傜偣璁剧疆鎴愯櫄鎷熺殑锛堝幓鎺夎嚜瀹氫箟缁勪欢鍖呰9灞傦級锛屾洿鍔犳帴杩慥ue缁勪欢鐨勮〃鐜帮紝鑳芥洿濂界殑浣跨敤flex灞炴��
+    options: {
+        virtualHost: true
+    }
+    // #endif
+}
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/libs/mixin/mpShare.js b/uni_modules/uv-ui-tools/libs/mixin/mpShare.js
new file mode 100644
index 0000000..c9695a0
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/mixin/mpShare.js
@@ -0,0 +1,13 @@
+export default {
+	onLoad() {
+	    // 璁剧疆榛樿鐨勮浆鍙戝弬鏁�
+	    uni.$uv.mpShare = {
+	        title: '', // 榛樿涓哄皬绋嬪簭鍚嶇О
+	        path: '', // 榛樿涓哄綋鍓嶉〉闈㈣矾寰�
+	        imageUrl: '' // 榛樿涓哄綋鍓嶉〉闈㈢殑鎴浘
+	    }
+	},
+	onShareAppMessage() {
+	    return uni.$uv.mpShare
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/libs/mixin/openType.js b/uni_modules/uv-ui-tools/libs/mixin/openType.js
new file mode 100644
index 0000000..1b94b7e
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/mixin/openType.js
@@ -0,0 +1,47 @@
+export default {
+    props: {
+        openType: String
+    },
+		emits: ['getphonenumber','getuserinfo','error','opensetting','launchapp','contact','chooseavatar','addgroupapp','chooseaddress','subscribe','login','im'],
+    methods: {
+        onGetPhoneNumber(event) {
+            this.$emit('getphonenumber', event.detail)
+        },
+        onGetUserInfo(event) {
+            this.$emit('getuserinfo', event.detail)
+        },
+        onError(event) {
+            this.$emit('error', event.detail)
+        },
+        onOpenSetting(event) {
+            this.$emit('opensetting', event.detail)
+        },
+        onLaunchApp(event) {
+            this.$emit('launchapp', event.detail)
+        },
+        onContact(event) {
+            this.$emit('contact', event.detail)
+        },
+        onChooseavatar(event) {
+            this.$emit('chooseavatar', event.detail)
+        },
+        onAgreeprivacyauthorization(event) {
+            this.$emit('agreeprivacyauthorization', event.detail)
+        },
+        onAddgroupapp(event) {
+            this.$emit('addgroupapp', event.detail)
+        },
+        onChooseaddress(event) {
+            this.$emit('chooseaddress', event.detail)
+        },
+        onSubscribe(event) {
+            this.$emit('subscribe', event.detail)
+        },
+        onLogin(event) {
+            this.$emit('login', event.detail)
+        },
+        onIm(event) {
+            this.$emit('im', event.detail)
+        }
+    }
+}
diff --git a/uni_modules/uv-ui-tools/libs/mixin/touch.js b/uni_modules/uv-ui-tools/libs/mixin/touch.js
new file mode 100644
index 0000000..0ecbd88
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/mixin/touch.js
@@ -0,0 +1,59 @@
+const MIN_DISTANCE = 10
+
+function getDirection(x, y) {
+    if (x > y && x > MIN_DISTANCE) {
+        return 'horizontal'
+    }
+    if (y > x && y > MIN_DISTANCE) {
+        return 'vertical'
+    }
+    return ''
+}
+
+export default {
+    methods: {
+        getTouchPoint(e) {
+            if (!e) {
+                return {
+                    x: 0,
+                    y: 0
+                }
+            } if (e.touches && e.touches[0]) {
+                return {
+                    x: e.touches[0].pageX,
+                    y: e.touches[0].pageY
+                }
+            } if (e.changedTouches && e.changedTouches[0]) {
+                return {
+                    x: e.changedTouches[0].pageX,
+                    y: e.changedTouches[0].pageY
+                }
+            }
+            return {
+                x: e.clientX || 0,
+                y: e.clientY || 0
+            }
+        },
+        resetTouchStatus() {
+            this.direction = ''
+            this.deltaX = 0
+            this.deltaY = 0
+            this.offsetX = 0
+            this.offsetY = 0
+        },
+        touchStart(event) {
+            this.resetTouchStatus()
+            const touch = this.getTouchPoint(event)
+            this.startX = touch.x
+            this.startY = touch.y
+        },
+        touchMove(event) {
+            const touch = this.getTouchPoint(event)
+            this.deltaX = touch.x - this.startX
+            this.deltaY = touch.y - this.startY
+            this.offsetX = Math.abs(this.deltaX)
+            this.offsetY = Math.abs(this.deltaY)
+            this.direction =				this.direction || getDirection(this.offsetX, this.offsetY)
+        }
+    }
+}
diff --git a/uni_modules/uv-ui-tools/libs/util/dayjs.js b/uni_modules/uv-ui-tools/libs/util/dayjs.js
new file mode 100644
index 0000000..c84ab68
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/util/dayjs.js
@@ -0,0 +1,216 @@
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __commonJS = (cb, mod) => function __require() {
+  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+};
+
+var require_dayjs_min = __commonJS({
+  "uvuidayjs"(exports, module) {
+    !function(t, e) {
+      "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e();
+    }(exports, function() {
+      "use strict";
+      var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", f = "month", h = "quarter", c = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) {
+        var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100;
+        return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]";
+      } }, m = function(t2, e2, n2) {
+        var r2 = String(t2);
+        return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2;
+      }, v = { s: m, z: function(t2) {
+        var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60;
+        return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0");
+      }, m: function t2(e2, n2) {
+        if (e2.date() < n2.date())
+          return -t2(n2, e2);
+        var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, f), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), f);
+        return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0);
+      }, a: function(t2) {
+        return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2);
+      }, p: function(t2) {
+        return { M: f, y: c, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: h }[t2] || String(t2 || "").toLowerCase().replace(/s$/, "");
+      }, u: function(t2) {
+        return void 0 === t2;
+      } }, g = "en", D = {};
+      D[g] = M;
+      var p = function(t2) {
+        return t2 instanceof _;
+      }, S = function t2(e2, n2, r2) {
+        var i2;
+        if (!e2)
+          return g;
+        if ("string" == typeof e2) {
+          var s2 = e2.toLowerCase();
+          D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2);
+          var u2 = e2.split("-");
+          if (!i2 && u2.length > 1)
+            return t2(u2[0]);
+        } else {
+          var a2 = e2.name;
+          D[a2] = e2, i2 = a2;
+        }
+        return !r2 && i2 && (g = i2), i2 || !r2 && g;
+      }, w = function(t2, e2) {
+        if (p(t2))
+          return t2.clone();
+        var n2 = "object" == typeof e2 ? e2 : {};
+        return n2.date = t2, n2.args = arguments, new _(n2);
+      }, O = v;
+      O.l = S, O.i = p, O.w = function(t2, e2) {
+        return w(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset });
+      };
+      var _ = function() {
+        function M2(t2) {
+          this.$L = S(t2.locale, null, true), this.parse(t2);
+        }
+        var m2 = M2.prototype;
+        return m2.parse = function(t2) {
+          this.$d = function(t3) {
+            var e2 = t3.date, n2 = t3.utc;
+            if (null === e2)
+              return new Date(NaN);
+            if (O.u(e2))
+              return new Date();
+            if (e2 instanceof Date)
+              return new Date(e2);
+            if ("string" == typeof e2 && !/Z$/i.test(e2)) {
+              var r2 = e2.match($);
+              if (r2) {
+                var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3);
+                return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2);
+              }
+            }
+            return new Date(e2);
+          }(t2), this.$x = t2.x || {}, this.init();
+        }, m2.init = function() {
+          var t2 = this.$d;
+          this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds();
+        }, m2.$utils = function() {
+          return O;
+        }, m2.isValid = function() {
+          return !(this.$d.toString() === l);
+        }, m2.isSame = function(t2, e2) {
+          var n2 = w(t2);
+          return this.startOf(e2) <= n2 && n2 <= this.endOf(e2);
+        }, m2.isAfter = function(t2, e2) {
+          return w(t2) < this.startOf(e2);
+        }, m2.isBefore = function(t2, e2) {
+          return this.endOf(e2) < w(t2);
+        }, m2.$g = function(t2, e2, n2) {
+          return O.u(t2) ? this[e2] : this.set(n2, t2);
+        }, m2.unix = function() {
+          return Math.floor(this.valueOf() / 1e3);
+        }, m2.valueOf = function() {
+          return this.$d.getTime();
+        }, m2.startOf = function(t2, e2) {
+          var n2 = this, r2 = !!O.u(e2) || e2, h2 = O.p(t2), l2 = function(t3, e3) {
+            var i2 = O.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2);
+            return r2 ? i2 : i2.endOf(a);
+          }, $2 = function(t3, e3) {
+            return O.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2);
+          }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : "");
+          switch (h2) {
+            case c:
+              return r2 ? l2(1, 0) : l2(31, 11);
+            case f:
+              return r2 ? l2(1, M3) : l2(0, M3 + 1);
+            case o:
+              var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2;
+              return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3);
+            case a:
+            case d:
+              return $2(v2 + "Hours", 0);
+            case u:
+              return $2(v2 + "Minutes", 1);
+            case s:
+              return $2(v2 + "Seconds", 2);
+            case i:
+              return $2(v2 + "Milliseconds", 3);
+            default:
+              return this.clone();
+          }
+        }, m2.endOf = function(t2) {
+          return this.startOf(t2, false);
+        }, m2.$set = function(t2, e2) {
+          var n2, o2 = O.p(t2), h2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = h2 + "Date", n2[d] = h2 + "Date", n2[f] = h2 + "Month", n2[c] = h2 + "FullYear", n2[u] = h2 + "Hours", n2[s] = h2 + "Minutes", n2[i] = h2 + "Seconds", n2[r] = h2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2;
+          if (o2 === f || o2 === c) {
+            var y2 = this.clone().set(d, 1);
+            y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d;
+          } else
+            l2 && this.$d[l2]($2);
+          return this.init(), this;
+        }, m2.set = function(t2, e2) {
+          return this.clone().$set(t2, e2);
+        }, m2.get = function(t2) {
+          return this[O.p(t2)]();
+        }, m2.add = function(r2, h2) {
+          var d2, l2 = this;
+          r2 = Number(r2);
+          var $2 = O.p(h2), y2 = function(t2) {
+            var e2 = w(l2);
+            return O.w(e2.date(e2.date() + Math.round(t2 * r2)), l2);
+          };
+          if ($2 === f)
+            return this.set(f, this.$M + r2);
+          if ($2 === c)
+            return this.set(c, this.$y + r2);
+          if ($2 === a)
+            return y2(1);
+          if ($2 === o)
+            return y2(7);
+          var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3;
+          return O.w(m3, this);
+        }, m2.subtract = function(t2, e2) {
+          return this.add(-1 * t2, e2);
+        }, m2.format = function(t2) {
+          var e2 = this, n2 = this.$locale();
+          if (!this.isValid())
+            return n2.invalidDate || l;
+          var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = O.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, f2 = n2.months, h2 = function(t3, n3, i3, s3) {
+            return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3);
+          }, c2 = function(t3) {
+            return O.s(s2 % 12 || 12, t3, "0");
+          }, d2 = n2.meridiem || function(t3, e3, n3) {
+            var r3 = t3 < 12 ? "AM" : "PM";
+            return n3 ? r3.toLowerCase() : r3;
+          }, $2 = { YY: String(this.$y).slice(-2), YYYY: this.$y, M: a2 + 1, MM: O.s(a2 + 1, 2, "0"), MMM: h2(n2.monthsShort, a2, f2, 3), MMMM: h2(f2, a2), D: this.$D, DD: O.s(this.$D, 2, "0"), d: String(this.$W), dd: h2(n2.weekdaysMin, this.$W, o2, 2), ddd: h2(n2.weekdaysShort, this.$W, o2, 3), dddd: o2[this.$W], H: String(s2), HH: O.s(s2, 2, "0"), h: c2(1), hh: c2(2), a: d2(s2, u2, true), A: d2(s2, u2, false), m: String(u2), mm: O.s(u2, 2, "0"), s: String(this.$s), ss: O.s(this.$s, 2, "0"), SSS: O.s(this.$ms, 3, "0"), Z: i2 };
+          return r2.replace(y, function(t3, e3) {
+            return e3 || $2[t3] || i2.replace(":", "");
+          });
+        }, m2.utcOffset = function() {
+          return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
+        }, m2.diff = function(r2, d2, l2) {
+          var $2, y2 = O.p(d2), M3 = w(r2), m3 = (M3.utcOffset() - this.utcOffset()) * e, v2 = this - M3, g2 = O.m(this, M3);
+          return g2 = ($2 = {}, $2[c] = g2 / 12, $2[f] = g2, $2[h] = g2 / 3, $2[o] = (v2 - m3) / 6048e5, $2[a] = (v2 - m3) / 864e5, $2[u] = v2 / n, $2[s] = v2 / e, $2[i] = v2 / t, $2)[y2] || v2, l2 ? g2 : O.a(g2);
+        }, m2.daysInMonth = function() {
+          return this.endOf(f).$D;
+        }, m2.$locale = function() {
+          return D[this.$L];
+        }, m2.locale = function(t2, e2) {
+          if (!t2)
+            return this.$L;
+          var n2 = this.clone(), r2 = S(t2, e2, true);
+          return r2 && (n2.$L = r2), n2;
+        }, m2.clone = function() {
+          return O.w(this.$d, this);
+        }, m2.toDate = function() {
+          return new Date(this.valueOf());
+        }, m2.toJSON = function() {
+          return this.isValid() ? this.toISOString() : null;
+        }, m2.toISOString = function() {
+          return this.$d.toISOString();
+        }, m2.toString = function() {
+          return this.$d.toUTCString();
+        }, M2;
+      }(), T = _.prototype;
+      return w.prototype = T, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", f], ["$y", c], ["$D", d]].forEach(function(t2) {
+        T[t2[1]] = function(e2) {
+          return this.$g(e2, t2[0], t2[1]);
+        };
+      }), w.extend = function(t2, e2) {
+        return t2.$i || (t2(e2, _, w), t2.$i = true), w;
+      }, w.locale = S, w.isDayjs = p, w.unix = function(t2) {
+        return w(1e3 * t2);
+      }, w.en = D[g], w.Ls = D, w.p = {}, w;
+    });
+  }
+});
+export default require_dayjs_min();
diff --git a/uni_modules/uv-ui-tools/libs/util/route.js b/uni_modules/uv-ui-tools/libs/util/route.js
new file mode 100644
index 0000000..80c0afd
--- /dev/null
+++ b/uni_modules/uv-ui-tools/libs/util/route.js
@@ -0,0 +1,126 @@
+/**
+ * 璺敱璺宠浆鏂规硶锛岃鏂规硶鐩稿浜庣洿鎺ヤ娇鐢╱ni.xxx鐨勫ソ澶勬槸浣跨敤鏇村姞绠�鍗曞揩鎹�
+ * 骞朵笖甯︽湁璺敱鎷︽埅鍔熻兘
+ */
+import { queryParams, deepMerge, page } from '@/uni_modules/uv-ui-tools/libs/function/index.js'
+class Router {
+	constructor() {
+		// 鍘熷灞炴�у畾涔�
+		this.config = {
+			type: 'navigateTo',
+			url: '',
+			delta: 1, // navigateBack椤甸潰鍚庨��鏃�,鍥為��鐨勫眰鏁�
+			params: {}, // 浼犻�掔殑鍙傛暟
+			animationType: 'pop-in', // 绐楀彛鍔ㄧ敾,鍙湪APP鏈夋晥
+			animationDuration: 300, // 绐楀彛鍔ㄧ敾鎸佺画鏃堕棿,鍗曚綅姣,鍙湪APP鏈夋晥
+			intercept: false ,// 鏄惁闇�瑕佹嫤鎴�
+			events: {} // 椤甸潰闂撮�氫俊鎺ュ彛锛岀敤浜庣洃鍚鎵撳紑椤甸潰鍙戦�佸埌褰撳墠椤甸潰鐨勬暟鎹�俬builderx 2.8.9+ 寮�濮嬫敮鎸併��
+		}
+		// 鍥犱负route鏂规硶鏄渶瑕佸澶栬祴鍊肩粰鍙﹀鐨勫璞′娇鐢紝鍚屾椂route鍐呴儴鏈変娇鐢╰his锛屼細瀵艰嚧route澶卞幓涓婁笅鏂�
+		// 杩欓噷鍦ㄦ瀯閫犲嚱鏁颁腑杩涜this缁戝畾
+		this.route = this.route.bind(this)
+	}
+
+	// 鍒ゆ柇url鍓嶉潰鏄惁鏈�"/"锛屽鏋滄病鏈夊垯鍔犱笂锛屽惁鍒欐棤娉曡烦杞�
+	addRootPath(url) {
+		return url[0] === '/' ? url : `/${url}`
+	}
+
+	// 鏁村悎璺敱鍙傛暟
+	mixinParam(url, params) {
+		url = url && this.addRootPath(url)
+
+		// 浣跨敤姝e垯鍖归厤锛屼富瑕佷緷鎹槸鍒ゆ柇鏄惁鏈�"/","?","="绛夛紝濡傗��/page/index/index?name=mary"
+		// 濡傛灉鏈塽rl涓湁get鍙傛暟锛岃浆鎹㈠悗鏃犻渶甯︿笂"?"
+		let query = ''
+		if (/.*\/.*\?.*=.*/.test(url)) {
+			// object瀵硅薄杞负get绫诲瀷鐨勫弬鏁�
+			query = queryParams(params, false)
+			// 鍥犱负宸叉湁get鍙傛暟,鎵�浠ュ悗闈㈡嫾鎺ョ殑鍙傛暟闇�瑕佸甫涓�"&"闅斿紑
+			return url += `&${query}`
+		}
+		// 鐩存帴鎷兼帴鍙傛暟锛屽洜涓烘澶剈rl涓病鏈夊悗闈㈢殑query鍙傛暟锛屼篃灏辨病鏈�"?/&"涔嬬被鐨勭鍙�
+		query = queryParams(params)
+		return url += query
+	}
+
+	// 瀵瑰鐨勬柟娉曞悕绉�
+	async route(options = {}, params = {}) {
+		// 鍚堝苟鐢ㄦ埛鐨勯厤缃拰鍐呴儴鐨勯粯璁ら厤缃�
+		let mergeConfig = {}
+
+		if (typeof options === 'string') {
+			// 濡傛灉options涓哄瓧绗︿覆锛屽垯涓簉oute(url, params)鐨勫舰寮�
+			mergeConfig.url = this.mixinParam(options, params)
+			mergeConfig.type = 'navigateTo'
+		} else {
+			mergeConfig = deepMerge(this.config, options)
+			// 鍚﹀垯姝e父浣跨敤mergeConfig涓殑url鍜宲arams杩涜鎷兼帴
+			mergeConfig.url = this.mixinParam(options.url, options.params)
+		}
+		// 濡傛灉鏈璺宠浆鐨勮矾寰勫拰鏈〉闈㈣矾寰勪竴鑷达紝涓嶆墽琛岃烦杞紝闃叉鐢ㄦ埛蹇�熺偣鍑昏烦杞寜閽紝閫犳垚澶氭璺宠浆鍚屼竴涓〉闈㈢殑闂
+		if (mergeConfig.url === page()) return
+
+		if (params.intercept) {
+			mergeConfig.intercept = params.intercept
+		}
+		// params鍙傛暟涔熷甫缁欐嫤鎴櫒
+		mergeConfig.params = params
+		// 鍚堝苟鍐呭閮ㄥ弬鏁�
+		mergeConfig = deepMerge(this.config, mergeConfig)
+		// 鍒ゆ柇鐢ㄦ埛鏄惁瀹氫箟浜嗘嫤鎴櫒
+		if (typeof mergeConfig.intercept === 'function') {
+			// 瀹氫竴涓猵romise锛屾牴鎹敤鎴锋墽琛宺esolve(true)鎴栬�卹esolve(false)鏉ュ喅瀹氭槸鍚﹁繘琛岃矾鐢辫烦杞�
+			const isNext = await new Promise((resolve, reject) => {
+				mergeConfig.intercept(mergeConfig, resolve)
+			})
+			// 濡傛灉isNext涓簍rue锛屽垯鎵ц璺敱璺宠浆
+			isNext && this.openPage(mergeConfig)
+		} else {
+			this.openPage(mergeConfig)
+		}
+	}
+
+	// 鎵ц璺敱璺宠浆
+	openPage(config) {
+		// 瑙f瀯鍙傛暟
+		const {
+			url,
+			type,
+			delta,
+			animationType,
+			animationDuration,
+			events
+		} = config
+		if (config.type == 'navigateTo' || config.type == 'to') {
+			uni.navigateTo({
+				url,
+				animationType,
+				animationDuration,
+				events
+			})
+		}
+		if (config.type == 'redirectTo' || config.type == 'redirect') {
+			uni.redirectTo({
+				url
+			})
+		}
+		if (config.type == 'switchTab' || config.type == 'tab') {
+			uni.switchTab({
+				url
+			})
+		}
+		if (config.type == 'reLaunch' || config.type == 'launch') {
+			uni.reLaunch({
+				url
+			})
+		}
+		if (config.type == 'navigateBack' || config.type == 'back') {
+			uni.navigateBack({
+				delta
+			})
+		}
+	}
+}
+
+export default (new Router()).route
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/package.json b/uni_modules/uv-ui-tools/package.json
new file mode 100644
index 0000000..2d940f6
--- /dev/null
+++ b/uni_modules/uv-ui-tools/package.json
@@ -0,0 +1,81 @@
+{
+  "id": "uv-ui-tools",
+  "displayName": "uv-ui-tools 宸ュ叿闆� 鍏ㄩ潰鍏煎vue3+2銆乤pp銆乭5銆佸皬绋嬪簭绛夊绔�",
+  "version": "1.1.25",
+  "description": "uv-ui-tools锛岄泦鎴愬伐鍏峰簱锛屽己澶х殑Http璇锋眰灏佽锛屾竻鏅扮殑鏂囨。璇存槑锛屽紑绠卞嵆鐢ㄣ�傛柟渚夸娇鐢紝鍙互鍏ㄥ眬浣跨敤",
+  "keywords": [
+    "uv-ui-tools,uv-ui缁勪欢搴�,宸ュ叿闆�,uvui,uView2.x"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "type": "component-vue",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "鏃�",
+      "data": "鎻掍欢涓嶉噰闆嗕换浣曟暟鎹�",
+      "permissions": "鏃�"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "寰俊娴忚鍣�(Android)": "y",
+          "QQ娴忚鍣�(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "灏忕▼搴�": {
+          "寰俊": "y",
+          "闃块噷": "y",
+          "鐧惧害": "y",
+          "瀛楄妭璺冲姩": "y",
+          "QQ": "y",
+          "閽夐拤": "y",
+          "蹇墜": "y",
+          "椋炰功": "y",
+          "浜笢": "y"
+        },
+        "蹇簲鐢�": {
+          "鍗庝负": "y",
+          "鑱旂洘": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/readme.md b/uni_modules/uv-ui-tools/readme.md
new file mode 100644
index 0000000..79a7df5
--- /dev/null
+++ b/uni_modules/uv-ui-tools/readme.md
@@ -0,0 +1,23 @@
+## uv-ui-tools 宸ュ叿闆�
+
+> **缁勪欢鍚嶏細uv-ui-tools**
+
+uv-ui宸ュ叿闆嗘垚锛屽寘鎷綉缁淗ttp璇锋眰銆佷究鎹峰伐鍏枫�佽妭娴侀槻鎶栥�佸璞℃搷浣溿�佹椂闂存牸寮忓寲銆佽矾鐢辫烦杞�佸叏灞�鍞竴鏍囪瘑绗︺�佽鍒欐牎楠岀瓑绛夈��
+
+璇ョ粍浠舵帹鑽愰厤鍚圼uv-ui缁勪欢搴揮(https://www.uvui.cn/components/intro.html)浣跨敤锛屽崟鐙笅杞戒篃鍙互鍦ㄨ嚜宸遍」鐩腑浣跨敤锛岄渶瑕佸仛鐩稿簲鐨勯厤缃紝鍙煡鐪嬫枃妗c�傚己鐑堟帹鑽愪娇鐢╗uv-ui缁勪欢搴揮(https://www.uvui.cn/components/intro.html)锛屽鍏ョ粍浠堕兘浼氳嚜鍔ㄥ鍏uv-ui-tools`銆傞渶瑕佸湪鑷繁鐨勯」鐩腑浣跨敤璇峰弬鑰僛鎵╁睍閰嶇疆](https://www.uvui.cn/components/setting.html)銆�
+
+uv-ui鐮撮嚋娌夎垷涔嬪吋瀹箆ue3+2銆乤pp銆乭5銆佸绔皬绋嬪簭鐨剈ni-app鐢熸�佹鏋讹紝澶ч儴鍒嗙粍浠跺熀浜巙View2.x锛屽湪缁忚繃鏀硅繘鍚庡叏闈㈡敮鎸乿ue3锛岄儴鍒嗙粍浠跺仛浜嗚繘涓�姝ョ殑浼樺寲锛屼慨澶嶅ぇ閲廈UG锛屾敮鎸佸崟鐙鍏ワ紝鏂逛究寮�鍙戣�呴�夋嫨瀵煎叆闇�瑕佺殑缁勪欢銆傚紑绠卞嵆鐢紝鐏垫椿閰嶇疆銆�
+
+# <a href="https://www.uvui.cn/js/intro.html" target="_blank">鏌ョ湅鏂囨。</a>
+
+## [涓嬭浇瀹屾暣绀轰緥椤圭洰](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>锛堣涓嶈 涓嬭浇鎻掍欢ZIP锛�</small>
+
+### [鏇村鎻掍欢锛岃鍏虫敞uv-ui缁勪欢搴揮(https://ext.dcloud.net.cn/plugin?name=uv-ui)
+
+<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
+
+![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png)
+
+</a>
+
+#### 濡備娇鐢ㄨ繃绋嬩腑鏈変换浣曢棶棰樺弽棣堬紝鎴栬�呮偍瀵箄v-ui鏈変竴浜涘ソ鐨勫缓璁紝娆㈣繋鍔犲叆uv-ui瀹樻柟浜ゆ祦缇わ細<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">瀹樻柟QQ缇�</a>
\ No newline at end of file
diff --git a/uni_modules/uv-ui-tools/theme.scss b/uni_modules/uv-ui-tools/theme.scss
new file mode 100644
index 0000000..cfaae92
--- /dev/null
+++ b/uni_modules/uv-ui-tools/theme.scss
@@ -0,0 +1,43 @@
+// 姝ゆ枃浠朵负uvUI鐨勪富棰樺彉閲忥紝杩欎簺鍙橀噺鐩墠鍙兘閫氳繃uni.scss寮曞叆鎵嶆湁鏁堬紝鍙﹀鐢变簬
+// uni.scss涓紩鍏ョ殑鏍峰紡浼氬悓鏃舵贩鍏ュ埌鍏ㄥ眬鏍峰紡鏂囦欢鍜屽崟鐙瘡涓�涓〉闈㈢殑鏍峰紡涓紝閫犳垚寰俊绋嬪簭鍖呭お澶э紝
+// 鏁卽ni.scss鍙缓璁斁scss鍙橀噺鍚嶇浉鍏虫牱寮忥紝鍏朵粬鐨勬牱寮忓彲浠ラ�氳繃main.js鎴栬�匒pp.vue寮曞叆
+
+$uv-main-color: #303133;
+$uv-content-color: #606266;
+$uv-tips-color: #909193;
+$uv-light-color: #c0c4cc;
+$uv-border-color: #dadbde;
+$uv-bg-color: #f3f4f6;
+$uv-disabled-color: #c8c9cc;
+
+$uv-primary: #3c9cff;
+$uv-primary-dark: #398ade;
+$uv-primary-disabled: #9acafc;
+$uv-primary-light: #ecf5ff;
+
+$uv-warning: #f9ae3d;
+$uv-warning-dark: #f1a532;
+$uv-warning-disabled: #f9d39b;
+$uv-warning-light: #fdf6ec;
+
+$uv-success: #5ac725;
+$uv-success-dark: #53c21d;
+$uv-success-disabled: #a9e08f;
+$uv-success-light: #f5fff0;
+
+$uv-error: #f56c6c;
+$uv-error-dark: #e45656;
+$uv-error-disabled: #f7b2b2;
+$uv-error-light: #fef0f0;
+
+$uv-info: #909399;
+$uv-info-dark: #767a82;
+$uv-info-disabled: #c4c6c9;
+$uv-info-light: #f4f4f5;
+
+@mixin flex($direction: row) {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: $direction;
+}
\ No newline at end of file

--
Gitblit v1.9.3