diff --git a/.gitignore b/.gitignore
index 8ff30f3a..221095f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,5 @@ unpackage/
 .DS_Store
 wxcomponents/**/*.vue
 wxcomponents/**/*.css
-.hbuilderx/
\ No newline at end of file
+.hbuilderx/
+__image_snapshots__
\ No newline at end of file
diff --git a/App.vue b/App.vue
index 9ead80fe..ce99d18d 100644
--- a/App.vue
+++ b/App.vue
@@ -5,7 +5,9 @@
 	import {
 		version
 	} from './package.json'
+	// #ifdef APP
 	import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update';
+	// #endif
 
 	export default {
 		onLaunch: function() {
@@ -17,7 +19,7 @@
 			)
 			// #endif
 			// 线上示例使用
-			// console.log('%c uni-app官方团队诚邀优秀前端工程师加盟，一起打造更卓越的uni-app & uniCloud，欢迎投递简历到 hr2013@dcloud.io', 'color: red');
+			// console.log('%c uni-app官方团队诚邀优秀前 端工程师加盟，一起打造更卓越的uni-app & uniCloud，欢迎投递简历到 hr2013@dcloud.io', 'color: red');
 			console.log('App Launch');
 			// #ifdef APP-PLUS
 			// App平台检测升级，服务端代码是通过uniCloud的云函数实现的，详情可参考：https://ext.dcloud.net.cn/plugin?id=4542
diff --git a/README.md b/README.md
index 36c44dff..17bb22bc 100644
--- a/README.md
+++ b/README.md
@@ -73,7 +73,7 @@ npm run dev:h5
       </a>
       <a href="https://hellouniapp.dcloud.net.cn/" target="_blank" class="clear-style barcode-view">
         <div class="barcode-img-box">
-          <img src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/bb3ef7c0-517d-11eb-bdc1-8bd33eb6adaa.png" width="160" />
+          <img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/uni-h5-hosting-qr.png" width="160" />
         </div>
         <b>H5版</b>
       </a>
diff --git a/changelog.md b/changelog.md
index 4f33931d..24de90db 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,18 @@
+## 3.4.9（2025-06-25）
+- 适配 鸿蒙元服务
+- 更新 uni-swipe-action
+- 新增 crypto 示例和测试例
+- 新增 css 变量示例和测试例
+- 新增 web-view点击位置偏移测试例
+## 3.4.8（2025-04-10）
+- 调整 renderjs示例的平台兼容性
+## 3.4.7（2025-01-08）
+- 新增 uni-calendar显示
+- 更新 uniui 组件
+- 更新uni-id至3.3.33版本
+- 替换示例中失效图片资源地址
+## 3.4.6（2023-06-30）
+- 更新 video组件引用的视频链接
 ## 3.4.4（2022-07-25）
 - 新增 同步 uni-ui@1.4.20
 	- uni-forms 【重要】组件逻辑重构，部分用法旧版本不兼容，请注意兼容问题
diff --git a/components/api-set-tabbar.nvue b/components/api-set-tabbar.nvue
index c9c91872..19529af1 100644
--- a/components/api-set-tabbar.nvue
+++ b/components/api-set-tabbar.nvue
@@ -2,9 +2,11 @@
 	<view class="uni-padding-wrap">
 		<page-head :title="title"></page-head>
 		<button class="button" @click="setTabBarBadge">{{ !hasSetTabBarBadge ? '设置tab徽标' : '移除tab徽标' }}</button>
+		<!-- #ifndef MP-HARMONY -->
 		<button class="button" @click="showTabBarRedDot">{{ !hasShownTabBarRedDot ?  '显示红点' : '移除红点'}}</button>
 		<button class="button" @click="customStyle">{{ !hasCustomedStyle ? '自定义Tab样式' : '移除自定义样式'}}</button>
 		<button class="button" @click="customItem">{{ !hasCustomedItem ? '自定义Tab信息' : '移除自定义信息' }}</button>
+		<!-- #endif -->
 		<button class="button" @click="hideTabBar">{{ !hasHiddenTabBar ? '隐藏TabBar' : '显示TabBar' }}</button>
 		<view class="btn-area">
 			<button class="button" type="primary" @click="navigateBack">返回上一级</button>
diff --git a/env.js b/env.js
new file mode 100644
index 00000000..2cc35e5e
--- /dev/null
+++ b/env.js
@@ -0,0 +1,31 @@
+module.exports = {
+    "is-custom-runtime": false,
+    "compile": true,
+    "h5": {
+        "options": {
+            "headless": true
+        },
+        "executablePath": ""
+    },
+    "mp-weixin": {
+        "port": 9420,
+        "account": "",
+        "args": "",
+        "cwd": "",
+        "launch": true,
+        "teardown": "disconnect",
+        "remote": false,
+        "executablePath": ""
+    },
+    "app-plus": {
+        "android": {
+            "id": "emulator-5554",
+            "executablePath": "/Applications/HBuilderX-Dev.app/Contents/HBuilderX/plugins/launcher/base/android_base.apk"
+        },
+        "version": "/Applications/HBuilderX-Dev.app/Contents/HBuilderX/plugins/launcher/base/version.txt",
+        "ios": {
+            "id": "88E23FD4-D59B-46C8-BF89-C15586FE1507",
+            "executablePath": "/Applications/HBuilderX-Dev.app/Contents/HBuilderX/plugins/launcher/base/Pandora_simulator.app"
+        }
+    }
+}
diff --git a/hybrid/html/issue-17581.html b/hybrid/html/issue-17581.html
new file mode 100644
index 00000000..b235ffc4
--- /dev/null
+++ b/hybrid/html/issue-17581.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+	<head>
+		<meta charset="UTF-8">
+		<meta name="viewport"
+			content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<title>点击显示小点</title>
+		<style>
+			html,
+			body {
+				margin: 0;
+				padding: 0;
+				height: 100%;
+				background-color: aqua;
+				cursor: pointer;
+			}
+
+			.dot {
+				position: absolute;
+				width: 8px;
+				height: 8px;
+				background-color: red;
+				border-radius: 50%;
+				pointer-events: none;
+			}
+		</style>
+	</head>
+	<body>
+
+	</body>
+	<script type="text/javascript" src="https://doc.dcloud.net.cn/uni.webview.1.5.6.js"></script>
+	<script>
+		document.addEventListener('click', function(e) {
+			const {
+				clientX,
+				clientY
+			} = e
+			uni.postMessage({
+				data: {
+					action: 'click',
+					clientX,
+					clientY
+				}
+			});
+			const dot = document.createElement('div');
+			dot.className = 'dot';
+			dot.style.left = `${clientX - 4}px`;
+			dot.style.top = `${clientY - 4}px`;
+			document.body.appendChild(dot);
+			setTimeout(() => {
+				dot.remove();
+			}, 500); // 显示 500 毫秒后消失
+		});
+	</script>
+</html>
diff --git a/index.html b/index.html
index c1ee9124..2a448cb1 100644
--- a/index.html
+++ b/index.html
@@ -10,8 +10,8 @@
         (coverSupport ? ', viewport-fit=cover' : '') + '" />')
     </script>
     <title></title>
-	<script src="/static/image-resize-3.0.1.min.js"></script>
-	<script src="/static/quill-1.3.7.min.js"></script>
+	<script src="/static/web/image-resize-3.0.1.min.js"></script>
+	<script src="/static/web/quill-1.3.7.min.js"></script>
     <!--preload-links-->
     <!--app-context-->
   </head>
diff --git a/jest-setup.js b/jest-setup.js
new file mode 100644
index 00000000..32595829
--- /dev/null
+++ b/jest-setup.js
@@ -0,0 +1,191 @@
+const path = require("path");
+const fs = require("fs");
+const {
+    configureToMatchImageSnapshot
+} = require('jest-image-snapshot');
+let saveImageSnapshotDir = process.env.saveImageSnapshotDir || path.join(__dirname, '__snapshot__');
+
+expect.extend({
+    toMatchImageSnapshot: configureToMatchImageSnapshot({
+        customSnapshotIdentifier(args) {
+            return args.currentTestName.replace(/\//g, "-").replace(" ", "-");
+        },
+        customSnapshotsDir: process.env.saveImageSnapshotDir,
+        customDiffDir: path.join(saveImageSnapshotDir, "diff"),
+    }),
+    toSaveSnapshot,
+    toSaveImageSnapshot,
+});
+
+const testCaseToSnapshotFilePath =
+    process.env.testCaseToSnapshotFilePath || "./testCaseToSnapshotFilePath.json";
+
+if (!fs.existsSync(testCaseToSnapshotFilePath)) {
+    fs.writeFileSync(testCaseToSnapshotFilePath, "{}");
+}
+
+function writeTestCaseToSnapshotFile(testCaseName, snapshotFilePath) {
+    const data = JSON.parse(fs.readFileSync(testCaseToSnapshotFilePath));
+
+    if (testCaseName.includes(__dirname)) {
+        testCaseName = testCaseName.substring(`${__dirname}`.length);
+        if (testCaseName[0] == '/'  || testCaseName[0] == '\\') {
+            testCaseName = testCaseName.substring(1);
+        };
+    };
+
+    if (!data[testCaseName]) {
+        data[testCaseName] = [snapshotFilePath];
+    } else {
+        data[testCaseName].push(snapshotFilePath);
+    }
+    fs.writeFileSync(testCaseToSnapshotFilePath, JSON.stringify(data, null, 2));
+}
+
+function toSaveSnapshot(received, {
+    customSnapshotsDir,
+    fileName
+} = {}) {
+    const {
+        snapshotState: {
+            _rootDir
+        },
+        testPath,
+        currentTestName,
+    } = this;
+    const SNAPSHOTS_DIR = "__file_snapshots__";
+    const snapshotDir =
+        process.env.saveSnapshotDir ||
+        createSnapshotDir({
+            customSnapshotsDir,
+            testPath,
+            SNAPSHOTS_DIR,
+        });
+    const _fileName = createFileName({
+        fileName,
+        testPath,
+        currentTestName,
+    });
+    const filePath = path.join(snapshotDir, _fileName);
+    let message = () => `${currentTestName} toSaveSnapshot success`;
+    let pass = true;
+
+    try {
+        checkSnapshotDir(path.dirname(filePath));
+        fs.writeFileSync(filePath, received);
+        writeTestCaseToSnapshotFile(testPath.replace(`${_rootDir}/`, ""), filePath);
+    } catch (e) {
+        console.log("toSaveSnapshot fail", e);
+        message = () => e.message;
+        pass = false;
+    }
+
+    return {
+        message,
+        pass,
+    };
+}
+
+function toSaveImageSnapshot(
+    received, {
+        customSnapshotsDir,
+        customSnapshotIdentifier
+    } = {}
+) {
+    const {
+        snapshotState: {
+            _rootDir
+        },
+        testPath,
+        currentTestName,
+    } = this;
+    const SNAPSHOTS_DIR = "__image_snapshots__";
+    const snapshotDir =
+        process.env.saveImageSnapshotDir ||
+        createSnapshotDir({
+            customSnapshotsDir,
+            testPath,
+            SNAPSHOTS_DIR,
+        });
+    const _fileName = createFileName({
+        fileName: customSnapshotIdentifier ? `${customSnapshotIdentifier()}.png` : "",
+        testPath,
+        currentTestName,
+        fileType: "png",
+    });
+    const filePath = path.join(snapshotDir, _fileName);
+    let message = () => `${currentTestName} toSaveImageSnapshot success`;
+    let pass = true;
+
+    try {
+        checkSnapshotDir(path.dirname(filePath));
+        fs.writeFileSync(filePath, Buffer.from(received, "base64"));
+        writeTestCaseToSnapshotFile(testPath.replace(`${_rootDir}/`, ""), filePath);
+    } catch (e) {
+        console.log("toSaveImageSnapshot fail", e);
+        message = () => e.message;
+        pass = false;
+    }
+
+    return {
+        message,
+        pass,
+    };
+}
+
+function createSnapshotDir({
+    customSnapshotsDir,
+    testPath,
+    SNAPSHOTS_DIR
+}) {
+    return customSnapshotsDir || path.join(path.dirname(testPath), SNAPSHOTS_DIR);
+}
+
+function createFileName({
+    fileName,
+    testPath,
+    currentTestName,
+    fileType
+}) {
+    return (
+        fileName ||
+        createSnapshotIdentifier({
+            testPath,
+            currentTestName,
+            fileType,
+        })
+    );
+}
+
+function createSnapshotIdentifier({
+    testPath,
+    currentTestName,
+    fileType = "txt",
+}) {
+    const snapshotIdentifier = kebabCase(
+        `${path.basename(testPath)}-${currentTestName}`
+    );
+    const counter = timesCalled.get(`${snapshotIdentifier}-${fileType}`) || 1;
+    timesCalled.set(`${snapshotIdentifier}-${fileType}`, counter + 1);
+    return `${snapshotIdentifier}-${counter}.${fileType}`;
+}
+
+function kebabCase(str) {
+    return str
+        .replaceAll(/([a-z])([A-Z])/g, "$1-$2")
+        .replaceAll(/\s+/g, "-")
+        .replaceAll(/_+/g, "-")
+        .replaceAll(/\/+/g, "-")
+        .replaceAll(/\.+/g, "-")
+        .toLowerCase();
+}
+
+function checkSnapshotDir(snapshotDir) {
+    if (!fs.existsSync(snapshotDir)) {
+        fs.mkdirSync(snapshotDir, {
+            recursive: true,
+        });
+    }
+}
+
+const timesCalled = new Map();
diff --git a/jest.config.js b/jest.config.js
index 96c1fcee..954fc12a 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,11 +1,12 @@
 module.exports = {
-    testTimeout: 20000,
-    reporters: [
-        'default'
-    ],
-    watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'],
-    moduleFileExtensions: ['js', 'json'],
-    rootDir: __dirname,
-    testMatch: ["<rootDir>/pages/**/*test.[jt]s?(x)"],
-    testPathIgnorePatterns: ['/node_modules/']
-}
+  testTimeout: 20000,
+  reporters: [
+    'default'
+  ],
+  watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'],
+  moduleFileExtensions: ['js', 'json'],
+  rootDir: __dirname,
+  testMatch: ["<rootDir>/pages/**/*test.[jt]s?(x)"],
+  testPathIgnorePatterns: ['/node_modules/'],
+  setupFilesAfterEnv: ['<rootDir>/jest-setup.js'],
+}
diff --git a/main.js b/main.js
index a72be26e..ff49fdee 100644
--- a/main.js
+++ b/main.js
@@ -22,10 +22,13 @@ app.$mount()
 // #ifdef VUE3
 import {
 	createSSRApp
-} from 'vue'
+} from 'vue'
+import * as Pinia from 'pinia';
+import Vuex from "vuex";
 export function createApp() {
 	const app = createSSRApp(App)
-	app.use(store)
+	app.use(store)
+	app.use(Pinia.createPinia());
 	app.config.globalProperties.$adpid = "1111111111"
 	app.config.globalProperties.$backgroundAudioData = {
 		playing: false,
@@ -33,7 +36,9 @@ export function createApp() {
 		formatedPlayTime: '00:00:00'
 	}
 	return {
-		app
+		app,
+		Vuex, // 如果 nvue 使用 vuex 的各种map工具方法时，必须 return Vuex
+		Pinia // 此处必须将 Pinia 返回
 	}
 }
 // #endif
diff --git a/manifest.json b/manifest.json
index 79189a62..ee4b3918 100644
--- a/manifest.json
+++ b/manifest.json
@@ -114,7 +114,8 @@
         },
         "uniStatistics" : {
             "enable" : true
-        }
+        },
+        "libVersion" : "latest"
     },
     "mp-alipay" : {
         "usingComponents" : true,
diff --git a/package.json b/package.json
index 7294780c..d1e3f290 100644
--- a/package.json
+++ b/package.json
@@ -1,118 +1,133 @@
-{
-	"id": "hello-uniapp",
-	"name": "hello-uniapp",
-	"displayName": "hello-uniapp 示例工程",
-	"version": "3.4.4",
-	"description": "uni-app 框架示例，一套代码，同时发行到iOS、Android、H5、小程序等多个平台，请使用手机扫码快速体验 uni-app 的强大功能",
-	"scripts": {
-		"test": "echo \"Error: no test specified\" && exit 1"
-	},
-	"repository": "https://github.com/dcloudio/hello-uniapp.git",
-	"keywords": [
-        "hello-uniapp",
-        "uni-app",
-        "uni-ui",
-        "示例工程"
-    ],
-	"author": "",
-	"license": "MIT",
-	"bugs": {
-		"url": "https://github.com/dcloudio/hello-uniapp/issues"
-	},
-	"homepage": "https://github.com/dcloudio/hello-uniapp#readme",
-	"dependencies": {},
-	"dcloudext": {
-		"category": [
-			"前端页面模板",
-			"uni-app前端项目模板"
-		],
-		"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": {
-				"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"
-                },
-                "Vue": {
-                    "vue2": "y",
-                    "vue3": "y"
-                }
-			}
-		}
-	},
-
-	"uni-app": {
-		"scripts": {
-			"mp-dingtalk": {
-				"title": "钉钉小程序",
-				"env": {
-					"UNI_PLATFORM": "mp-alipay"
-				},
-				"define": {
-					"MP-DINGTALK": true
-				}
-			},
-			"hello-uniapp-demo": {
-				"title": "hello-uniapp 演示网站",
-				"env": {
-					"UNI_PLATFORM": "h5"
-				},
-				"define": {
-					"H5-DEMO": true
-				}
-			}
-		}
-	}
-}
+{
+  "id": "hello-uniapp",
+  "name": "hello-uniapp",
+  "displayName": "hello-uniapp 示例工程",
+  "version": "3.4.9",
+  "description": "uni-app 框架示例，一套代码，同时发行到iOS、Android、H5、小程序等多个平台，请使用手机扫码快速体验 uni-app 的强大功能",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": "https://github.com/dcloudio/hello-uniapp.git",
+  "keywords": [
+    "hello-uniapp",
+    "uni-app",
+    "uni-ui",
+    "示例工程"
+],
+  "author": "",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/dcloudio/hello-uniapp/issues"
+  },
+  "homepage": "https://github.com/dcloudio/hello-uniapp#readme",
+  "dependencies": {},
+  "dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "",
+    "type": "uniapp-template-project",
+    "darkmode": "x",
+    "i18n": "x",
+    "widescreen": "x"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "√",
+        "aliyun": "√",
+        "alipay": "x"
+      },
+      "client": {
+        "uni-app": {
+          "vue": {
+            "vue2": "√",
+            "vue3": "√"
+          },
+          "web": {
+            "safari": "√",
+            "chrome": "√"
+          },
+          "app": {
+            "vue": "√",
+            "nvue": "√",
+            "android": "√",
+            "ios": "√",
+            "harmony": "√"
+          },
+          "mp": {
+            "weixin": "√",
+            "alipay": "√",
+            "toutiao": "√",
+            "baidu": "√",
+            "kuaishou": "√",
+            "jd": "√",
+            "harmony": "√",
+            "qq": "√",
+            "lark": "√"
+          },
+          "quickapp": {
+            "huawei": "-",
+            "union": "-"
+          }
+        },
+        "uni-app-x": {
+          "web": {
+            "safari": "-",
+            "chrome": "-"
+          },
+          "app": {
+            "android": "-",
+            "ios": "-",
+            "harmony": "-"
+          },
+          "mp": {
+            "weixin": "-"
+          }
+        }
+      }
+    }
+  },
+  "uni-app": {
+    "scripts": {
+      "mp-dingtalk": {
+        "title": "钉钉小程序",
+        "env": {
+          "UNI_PLATFORM": "mp-alipay"
+        },
+        "define": {
+          "MP-DINGTALK": true
+        }
+      },
+      "hello-uniapp-demo": {
+        "title": "hello-uniapp 演示网站",
+        "env": {
+          "UNI_PLATFORM": "h5"
+        },
+        "define": {
+          "H5-DEMO": true
+        }
+      }
+    }
+  },
+  "engines": {
+    "HBuilderX": "^3.1.0",
+    "uni-app": "^4.03",
+    "uni-app-x": ""
+  }
+}
\ No newline at end of file
diff --git a/pages.json b/pages.json
index 93f12a93..29878358 100644
--- a/pages.json
+++ b/pages.json
@@ -279,11 +279,17 @@
 			}
 		},
 		// #endif
-		// #ifdef APP-PLUS || H5
+		// #ifdef APP || H5
 		{
 			"path": "pages/component/web-view-local/web-view-local",
 			"style": {}
 		},
+		{
+			"path": "pages/component/web-view-local/issue-17581",
+			"style": {
+				"navigationBarTitleText": "issue-17581"
+			}
+		},
 		// #endif
 		{
 			"path": "platforms/app-plus/speech/speech",
@@ -1321,11 +1327,61 @@
 				},
 				// #endif
 				// #endif
+				// #ifdef APP || H5
+				{
+					"path" : "renderjs/renderjs",
+					"style" :
+					{
+						"navigationBarTitleText" : "renderjs"
+					}
+				},
+				// #endif
 				{
 					"path": "global/global",
 					"style": {
 						"navigationBarTitleText": "GlobalData和vuex"
 					}
+				},
+				// #ifdef VUE3
+				{
+					"path" : "pinia/pinia",
+					"style" :
+					{
+						"navigationBarTitleText" : "pinia"
+					}
+				},
+				// #endif
+				// #ifdef APP
+				{
+					"path" : "vuex-nvue/vuex-nvue",
+					"style" :
+					{
+						"navigationBarTitleText" : "vuex-nvue"
+					}
+				},
+				// #endif
+				// #ifdef MP-WEIXIN
+				{
+					"path" : "issue-15216/issue-15216",
+					"style" :
+					{
+						"navigationBarTitleText" : "issue-15216"
+					}
+				},
+				// #endif
+				{
+					"path" : "vuex-vue/vuex-vue",
+					"style" :
+					{
+						"navigationBarTitleText" : "vuex-vue"
+					}
+				},
+				{
+					"path" : "crypto-api/crypto-api",
+					"style" :
+					{
+						"navigationBarTitleText" : "crypto"
+					}
 				}
 			]
 		}
diff --git a/pages/API/download-file/download-file.test.js b/pages/API/download-file/download-file.test.js
index 1947f1af..2459b6c1 100644
--- a/pages/API/download-file/download-file.test.js
+++ b/pages/API/download-file/download-file.test.js
@@ -1,10 +1,18 @@
-// uni-app自动化测试教程: uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
+const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
 describe('pages/API/download-file/download-file.vue', () => {
+	/** @type {UniAutomatorPage} */
 	let page;
+	const versions = ['12.4', '13.7', '15.5', '17.4', '17.5_深色主题', '18.1'];
+	const [platform, version] = platformInfo.split(' ');
+	if (platform === 'ios_simulator' && versions.includes(version)) {
+		it('skip', async () => {
+			expect(1).toBe(1);
+		});
+		return;
+	}
 	beforeAll(async () => {
 		page = await program.reLaunch('/pages/API/download-file/download-file')
 		await page.waitFor('view')
-
 	});
 	it('check download url', async () => {
 		expect.assertions(2);
@@ -12,9 +20,18 @@ describe('pages/API/download-file/download-file.vue', () => {
 		const waitTime = process.env.uniTestPlatformInfo.includes('firefox') ? 5000:2000
 		const start = Date.now();
 		await page.waitFor(async () => {
-		  return await page.data('jest_result') === true || (Date.now() - start > waitTime)
+			return await page.data('jest_result') === true || (Date.now() - start > waitTime)
 		})
-		console.log("data",await page.data(),Date.now() - start > waitTime)
+		expect(await page.data('jest_result')).toBeTruthy();
+		expect(await page.data('imageSrc')).toBeTruthy();
+	});
+	// 下载动态 url
+	it('下载动态 url 图片', async () => {
+		await page.setData({
+			imageSrc: 'https://open.weixin.qq.com/qr/code?username=dcloudio',
+		});
+		await page.callMethod('downloadImage');
+		await page.waitFor(2000);
 		expect(await page.data('jest_result')).toBeTruthy();
 		expect(await page.data('imageSrc')).toBeTruthy();
 	});
diff --git a/pages/API/download-file/download-file.vue b/pages/API/download-file/download-file.vue
index 7e3b8989..2e14e6a4 100644
--- a/pages/API/download-file/download-file.vue
+++ b/pages/API/download-file/download-file.vue
@@ -21,9 +21,10 @@
 		data() {
 			return {
 				title: 'downloadFile',
-				imageSrc: '',
-				//自动化测试例专用
-				jest_result: false
+				imageSrc: '',
+				//自动化测试例专用
+				jest_result: false,
+				baseImg:"https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png"
 			}
 		},
 		onUnload() {
@@ -36,15 +37,15 @@
 				})
 				var self = this
 				uni.downloadFile({
-					url: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png",
-					success: (res) => {
+					url: this.baseImg,
+					success: (res) => {
 						this.jest_result = true
 						console.log('downloadFile success, res is', res)
 						self.imageSrc = res.tempFilePath;
-						uni.hideLoading();
+						uni.hideLoading();
 					},
 					fail: (err) => {
-						console.log('downloadFile fail, err is:', err)
+						console.log('downloadFile fail, err is:', err)
 						this.jest_result = false
 					}
 				})
diff --git a/pages/API/get-location/get-location.vue b/pages/API/get-location/get-location.vue
index 82b508d6..a1527707 100644
--- a/pages/API/get-location/get-location.vue
+++ b/pages/API/get-location/get-location.vue
@@ -70,8 +70,22 @@
                     return;
                 }
                 // #endif
-
-                this.doGetLocation();
+				// #ifdef MP-HARMONY
+				uni.authorize({
+					scope: "scope.userLocation",
+					success: () => {
+						this.doGetLocation();
+					},
+					fail: () => {
+						uni.showToast({
+							title: "未授权获取地理位置权限"
+						})
+					}
+				})
+				// #endif
+				// #ifndef MP-HARMONY
+				this.doGetLocation();
+				// #endif
             },
             doGetLocation() {
                 uni.getLocation({
diff --git a/pages/API/get-network-type/get-network-type.vue b/pages/API/get-network-type/get-network-type.vue
index 3e9cf725..ae3c1f42 100644
--- a/pages/API/get-network-type/get-network-type.vue
+++ b/pages/API/get-network-type/get-network-type.vue
@@ -10,13 +10,15 @@
 				</block>
 				<block v-if="hasNetworkType === true">
 					<view class="uni-h2 uni-center uni-common-mt">{{networkType}}</view>
-				</block>
+				</block>
+				<!-- #ifndef MP-HARMONY -->
 				<view v-if="hasNetworkType === true && networkType === 'wifi'" class="uni-textarea uni-common-mt">
 					<textarea :value="connectedWifi"></textarea>
-				</view>
+				</view>
+				<!-- #endif -->
 			</view>
 			<view class="uni-btn-v uni-common-mt">
-				<button type="primary"  @tap="getNetworkType">获取设备网络状态</button>
+				<button type="primary" @tap="getNetworkType">获取设备网络状态</button>
 				<!-- #ifdef MP-WEIXIN  || MP-JD-->
 				<button v-if="hasNetworkType === true && networkType === 'wifi'" class="uni-common-mt" type="primary" @tap="getConnectedWifi">获取 wifi 信息</button>
 				<!-- #endif -->
diff --git a/pages/API/get-node-info/get-node-info.test.js b/pages/API/get-node-info/get-node-info.test.js
new file mode 100644
index 00000000..509dff06
--- /dev/null
+++ b/pages/API/get-node-info/get-node-info.test.js
@@ -0,0 +1,32 @@
+describe('测试 css 变量', () => {
+	let page
+	const isApp = process.env.UNI_PLATFORM.includes('app');
+	beforeAll(async () => {
+		// 重新reLaunch至首页，并获取首页page对象（其中 program 是uni-automator自动注入的全局对象）
+		page = await program.reLaunch('/pages/API/get-node-info/get-node-info')
+		await page.waitFor(1000)
+	})
+
+	it('css var', async () => {
+
+		if (isApp) {
+			const element1 = await page.$('.box1')
+			const size = await element1.size()
+			expect(size.height > 0).toBe(true)
+
+			const element2 = await page.$('.box2')
+			const size2 = await element2.size()
+			expect(size2.height === 0).toBe(true)
+
+			const element3 = await page.$('.box3')
+			const size3 = await element3.size()
+			expect(size3.height === 0).toBe(true)
+
+			const element4 = await page.$('.box4')
+			const size4 = await element4.size()
+			expect(size4.height > size.height).toBe(true)
+		} else {
+			expect(1).toBe(1)
+		}
+	})
+});
diff --git a/pages/API/get-node-info/get-node-info.vue b/pages/API/get-node-info/get-node-info.vue
index 870ab167..0b41e305 100644
--- a/pages/API/get-node-info/get-node-info.vue
+++ b/pages/API/get-node-info/get-node-info.vue
@@ -20,6 +20,14 @@
 					</view>
 				</view>
 			</view>
+			<!-- #ifdef APP -->
+			<view>
+				<view class="box box1"></view>
+				<view class="box box2"></view>
+				<view class="box box3"></view>
+				<view class="box box4"></view>
+			</view>
+			<!-- #endif -->
 		</view>
 	</view>
 </template>
@@ -114,4 +122,20 @@
 		width: 100rpx;
 		display: inline-block;
 	}
+
+	.box {
+		width: 50px;
+	}
+	.box1 {
+		height: var(--status-bar-height);
+	}
+	.box2 {
+		height: var(--window-bottom);
+	}
+	.box3 {
+		height: var(--window-top);
+	}
+	.box4 {
+		height: calc(var(--status-bar-height) + 2px);
+	}
 </style>
diff --git a/pages/API/login/login.vue b/pages/API/login/login.vue
index 5cd7d0bf..e6361475 100644
--- a/pages/API/login/login.vue
+++ b/pages/API/login/login.vue
@@ -91,6 +91,9 @@
 								break;
 							case 'univerify':
 								providerName = '一键登录'
+								break;
+							case 'huawei':
+								providerName = '华为登录'
 								break;
 						}
 						return {
@@ -259,7 +262,7 @@
 					provider
 				});
 				// #endif
-				
+
 				// #ifdef VUE3
 				try {
 					result = await uni.getUserInfo({
@@ -269,7 +272,7 @@
 					getUserInfoErr = e
 				}
 				// #endif
-				
+
 				if (getUserInfoErr) {
 					let content = getUserInfoErr.errMsg;
 					if (~content.indexOf('uni.login')) {
diff --git a/pages/API/request-payment/request-payment.vue b/pages/API/request-payment/request-payment.vue
index 395295b8..41e2d8a7 100644
--- a/pages/API/request-payment/request-payment.vue
+++ b/pages/API/request-payment/request-payment.vue
@@ -54,6 +54,13 @@
 									id: value,
 									loading: false
 								});
+								break;
+							case 'huawei':
+								providerList.push({
+									name: '华为',
+									id: value,
+									loading: false
+								});
 								break;
 							default:
 								break;
diff --git a/pages/API/set-navigation-bar-title/set-navigation-bar-title.test.js b/pages/API/set-navigation-bar-title/set-navigation-bar-title.test.js
index 249cff6d..93b017c9 100644
--- a/pages/API/set-navigation-bar-title/set-navigation-bar-title.test.js
+++ b/pages/API/set-navigation-bar-title/set-navigation-bar-title.test.js
@@ -1,14 +1,10 @@
-
 describe('pages/API/set-navigation-bar-title/set-navigation-bar-title.vue', () => {
     let page
     beforeAll(async () => {
         // 重新reLaunch至首页，并获取首页page对象（其中 program 是uni-automator自动注入的全局对象）
        page = await program.reLaunch('/pages/API/set-navigation-bar-title/set-navigation-bar-title')
-       if (process.env.UNI_PLATFORM === "mp-weixin") {
-       	await page.waitFor(10000)
-       } else {
-       	await page.waitFor(5000)
-       }
+	   const waitTime = process.env.UNI_PLATFORM === "mp-weixin" ? 10000 : 5000
+	   await page.waitFor(waitTime)
        page = await program.currentPage()
     })
     it('set-navigation-bar-title 组件标题', async () => {
diff --git a/pages/API/share/share.vue b/pages/API/share/share.vue
index 1f484198..90e8701a 100644
--- a/pages/API/share/share.vue
+++ b/pages/API/share/share.vue
@@ -135,7 +135,7 @@
 		methods: {
 			async share(e) {
 				console.log('分享通道:'+ e.id +'； 分享类型:' + this.shareType);
-				
+
 				if(!this.shareText && (this.shareType === 1 || this.shareType === 0)){
 					uni.showModal({
 						content:'分享内容不能为空',
@@ -143,7 +143,7 @@
 					})
 					return;
 				}
-				
+
 				if(!this.image && (this.shareType === 2 || this.shareType === 0)){
 					uni.showModal({
 						content:'分享图片不能为空',
@@ -151,10 +151,10 @@
 					})
 					return;
 				}
-				
+
 				let shareOPtions = {
 					provider: e.id,
-					scene: e.type && e.type === 'WXSceneTimeline' ? 'WXSceneTimeline' : 'WXSceneSession', //WXSceneSession”分享到聊天界面，“WXSceneTimeline”分享到朋友圈，“WXSceneFavorite”分享到微信收藏     
+					scene: e.type && e.type === 'WXSceneTimeline' ? 'WXSceneTimeline' : 'WXSceneSession', //WXSceneSession”分享到聊天界面，“WXSceneTimeline”分享到朋友圈，“WXSceneFavorite”分享到微信收藏
 					type: this.shareType,
 					success: (e) => {
 						console.log('success', e);
@@ -174,7 +174,7 @@
 						console.log('分享操作结束!')
 					}
 				}
-				
+
 				switch (this.shareType){
 					case 0:
 						shareOPtions.summary = this.shareText;
@@ -189,7 +189,7 @@
 						shareOPtions.imageUrl = this.image;
 						break;
 					case 5:
-						shareOPtions.imageUrl = this.image ? this.image : 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b6304f00-5168-11eb-bd01-97bc1429a9ff.png'
+						shareOPtions.imageUrl = this.image ? this.image : 'https://web-ext-storage.dcloud.net.cn/hello-uni-app/share.png'
 						shareOPtions.title = '欢迎体验uniapp';
 						shareOPtions.miniProgram = {
 							id:'gh_33446d7f7a26',
@@ -201,8 +201,8 @@
 					default:
 						break;
 				}
-				
-				if(shareOPtions.type === 0 && plus.os.name === 'iOS'){//如果是图文分享，且是ios平台，则压缩图片 
+
+				if(shareOPtions.type === 0 && plus.os.name === 'iOS'){//如果是图文分享，且是ios平台，则压缩图片
 					shareOPtions.imageUrl = await this.compress();
 				}
 				if(shareOPtions.type === 1 && shareOPtions.provider === 'qq'){//如果是分享文字到qq，则必须加上href和title
@@ -253,7 +253,7 @@
 					console.log('after' + localPath);
 					// 压缩size
 					plus.io.resolveLocalFileSystemURL(localPath, (entry) => {
-						entry.file((file) => {// 可通过entry对象操作图片 
+						entry.file((file) => {// 可通过entry对象操作图片
 							console.log('getFile:' + JSON.stringify(file));
 							if(file.size > 20480) {// 压缩后size 大于20Kb
 								plus.zip.compressImage({
diff --git a/pages/API/toast/toast.vue b/pages/API/toast/toast.vue
index e290bab1..2fd0ccd0 100644
--- a/pages/API/toast/toast.vue
+++ b/pages/API/toast/toast.vue
@@ -5,14 +5,19 @@
 			<view class="uni-btn-v">
 				<button type="default" @tap="toast1Tap">点击弹出默认toast</button>
 				<button type="default" @tap="toast2Tap">点击弹出设置duration的toast</button>
+				<!-- #ifndef MP-HARMONY -->
 				<button type="default" @tap="toast3Tap">点击弹出显示loading的toast</button>
-				<!-- #ifndef MP-ALIPAY -->
+				<!-- #endif -->
+
+				<!-- #ifndef MP-ALIPAY || MP-HARMONY  -->
 				<button type="default" @tap="toast4Tap">点击弹出显示自定义图片的toast</button>
 				<!-- #endif -->
 				<!-- #ifdef APP-PLUS -->
 				<button type="default" @tap="toast5Tap">点击显示无图标的居底toast</button>
-				<!-- #endif -->
-				<button type="default" @tap="hideToast">点击隐藏toast</button>
+				<!-- #endif -->
+				<!-- #ifndef MP-HARMONY -->
+				<button type="default" @tap="hideToast">点击隐藏toast</button>
+				<!-- #endif -->
 			</view>
 		</view>
 	</view>
@@ -30,18 +35,18 @@
 		},
 		// #endif
 		methods: {
-			toast1Tap: function () {
+			toast1Tap: function() {
 				uni.showToast({
 					title: "默认"
 				})
 			},
-			toast2Tap: function () {
+			toast2Tap: function() {
 				uni.showToast({
 					title: "duration 3000",
 					duration: 3000
 				})
 			},
-			toast3Tap: function () {
+			toast3Tap: function() {
 				uni.showToast({
 					title: "loading",
 					icon: "loading",
@@ -57,23 +62,23 @@
 				// #endif
 
 			},
-			toast4Tap: function () {
+			toast4Tap: function() {
 				uni.showToast({
 					title: "logo",
 					image: "../../../static/uni.png"
 				})
 			},
 			// #ifdef APP-PLUS
-			toast5Tap: function () {
+			toast5Tap: function() {
 				uni.showToast({
 					title: "显示一段轻提示",
-					position:'bottom'
+					position: 'bottom'
 				})
 			},
 			// #endif
-			hideToast: function () {
+			hideToast: function() {
 				uni.hideToast()
 			}
 		}
 	}
-</script>
+</script>
diff --git a/pages/API/vibrate/vibrate.vue b/pages/API/vibrate/vibrate.vue
index 4dedb00b..41a413a3 100644
--- a/pages/API/vibrate/vibrate.vue
+++ b/pages/API/vibrate/vibrate.vue
@@ -30,7 +30,10 @@ export default {
 			});
 		},
 		shortshock() {
-			uni.vibrateShort({
+			uni.vibrateShort({
+				// #ifdef MP-HARMONY
+				type:"medium",
+				// #endif
 				success: function() {
 					console.log('success');
 				}
diff --git a/pages/component/web-view-local/issue-17581.test.js b/pages/component/web-view-local/issue-17581.test.js
new file mode 100644
index 00000000..e9c46d4d
--- /dev/null
+++ b/pages/component/web-view-local/issue-17581.test.js
@@ -0,0 +1,29 @@
+const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
+const isHarmony = platformInfo.startsWith('harmony')
+
+describe('pages/component/web-view-local/issue-17581.vue', () => {
+	if (!isHarmony) {
+		it('skip', async () => {
+			expect(1).toBe(1)
+		})
+		return
+	}
+	let page
+	beforeAll(async () => {
+		page = await program.reLaunch('/pages/component/web-view-local/issue-17581')
+		await page.waitFor(1000)
+	})
+
+	it('click position', async () => {
+		await program.tap({
+			x: 100,
+			y: 400
+		})
+		await page.waitFor(200)
+		const {
+			clickClientY
+		} = await page.data()
+		expect(clickClientY).toBeLessThan(200)
+		expect(clickClientY).toBeGreaterThan(0)
+	})
+})
diff --git a/pages/component/web-view-local/issue-17581.vue b/pages/component/web-view-local/issue-17581.vue
new file mode 100644
index 00000000..c347105e
--- /dev/null
+++ b/pages/component/web-view-local/issue-17581.vue
@@ -0,0 +1,28 @@
+<template>
+	<view>
+		<web-view style="margin-top: 200px;" src="/hybrid/html/issue-17581.html" @message="onWebViewMessage"></web-view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				clickClientX: 0,
+				clickClientY: 0
+			}
+		},
+		onLoad() {},
+		methods: {
+			onWebViewMessage(message) {
+				const data = message.detail.data
+				const dataItem = data && data[0]
+				if(dataItem.action === 'click') {
+					this.clickClientX = dataItem.clientX
+					this.clickClientY = dataItem.clientY
+				}
+			}
+		}
+	}
+</script>
+<style>
+</style>
diff --git a/pages/component/web-view/web-view.vue b/pages/component/web-view/web-view.vue
index dce6413e..ebc19e19 100644
--- a/pages/component/web-view/web-view.vue
+++ b/pages/component/web-view/web-view.vue
@@ -8,7 +8,7 @@
 	export default {
 		data() {
 			return {
-				url: 'https://uniapp.dcloud.io/static/web-view.html'
+				url: 'https://hellouniapp.dcloud.net.cn/html/web-view.html'
 			}
 		},
 		onLoad(options) {
diff --git a/pages/extUI/collapse/collapse.vue b/pages/extUI/collapse/collapse.vue
index 4abc8a1b..fda3e02c 100644
--- a/pages/extUI/collapse/collapse.vue
+++ b/pages/extUI/collapse/collapse.vue
@@ -62,13 +62,13 @@
 		<uni-section title="配置图片" type="line">
 			<uni-collapse>
 				<uni-collapse-item title="标题文字"
-					thumb="https://web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png">
+					thumb="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png">
 					<view class="content">
 						<text class="text">折叠内容主体，可自定义内容及样式</text>
 					</view>
 				</uni-collapse-item>
 				<uni-collapse-item title="标题文字"
-					thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png">
+					thumb="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png">
 					<view class="content">
 						<text class="text">折叠内容主体，可自定义内容及样式</text>
 					</view>
@@ -96,7 +96,7 @@
 						<uni-list-item title="列表右侧显示 switch" :show-switch="true"></uni-list-item>
 						<uni-list-item :show-extra-icon="true" :extra-icon="extraIcon" title="列表左侧带扩展图标"></uni-list-item>
 						<uni-list-item title="列表左侧带略缩图" note="列表描述信息"
-							thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"
+							thumb="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png"
 							thumb-size="lg" rightText="右侧文字" showArrow></uni-list-item>
 						<uni-list-item title="开启点击反馈" clickable showArrow @click="onClick"></uni-list-item>
 					</uni-list>
diff --git a/pages/extUI/file-picker/file-picker.vue b/pages/extUI/file-picker/file-picker.vue
index c0a2d076..1a1e705a 100644
--- a/pages/extUI/file-picker/file-picker.vue
+++ b/pages/extUI/file-picker/file-picker.vue
@@ -79,11 +79,11 @@
 					extname: 'png',
 					name: 'shuijiao.png'
 				}, {
-					url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b7c7f970-517d-11eb-97b7-0dc4655d6e68.jpg',
+					url: 'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao-small.jpg',
 					extname: 'png',
 					name: 'uniapp-logo.png'
 				}, {
-					url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b7c7f970-517d-11eb-97b7-0dc4655d6e68.jpg',
+					url: 'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao-small.jpg',
 					extname: 'png',
 					name: 'shuijiao.png'
 				}]
diff --git a/pages/extUI/list/list.nvue b/pages/extUI/list/list.nvue
index 4f734782..8c812910 100644
--- a/pages/extUI/list/list.nvue
+++ b/pages/extUI/list/list.nvue
@@ -69,7 +69,7 @@
 					thumb="https://web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png"
 					thumb-size="base" rightText="默认" />
 				<uni-list-item title="列表左侧带略缩图" note="列表描述信息" showArrow
-					thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"
+					thumb="https://web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png"
 					thumb-size="lg" rightText="大图" />
 			</uni-list>
 		</uni-section>
@@ -112,7 +112,7 @@
 		data() {
 			return {
 				cover: 'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
-				avatar: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png',
+				avatar: 'https://web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
 				extraIcon: {
 					color: '#4cd964',
 					size: '22',
diff --git a/pages/extUI/swiper-dot/swiper-dot.nvue b/pages/extUI/swiper-dot/swiper-dot.nvue
index eccf59b1..7e8d34f7 100644
--- a/pages/extUI/swiper-dot/swiper-dot.nvue
+++ b/pages/extUI/swiper-dot/swiper-dot.nvue
@@ -63,12 +63,12 @@
 					},
 					{
 						colorClass: 'uni-bg-green',
-						url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/094a9dc0-50c0-11eb-b680-7980c8a877b8.jpg',
+						url: 'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
 						content: '内容 B'
 					},
 					{
 						colorClass: 'uni-bg-blue',
-						url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/094a9dc0-50c0-11eb-b680-7980c8a877b8.jpg',
+						url: 'https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
 						content: '内容 C'
 					}
 				],
@@ -155,21 +155,6 @@
 		background-color: #cee1fd;
 	}
 
-	.image {
-		width: 750rpx;
-	}
-
-	/* #ifndef APP-NVUE */
-	::v-deep .image img {
-		-webkit-user-drag: none;
-		-khtml-user-drag: none;
-		-moz-user-drag: none;
-		-o-user-drag: none;
-		user-drag: none;
-	}
-
-	/* #endif */
-
 	@media screen and (min-width: 500px) {
 		.uni-swiper-dot-box {
 			width: 400px;
diff --git a/pages/pages.test.js b/pages/pages.test.js
new file mode 100644
index 00000000..756e72e1
--- /dev/null
+++ b/pages/pages.test.js
@@ -0,0 +1,244 @@
+jest.setTimeout(10000000);
+let pageIndex = 0
+const pages = [
+	"/pages/component/view/view",
+	"/pages/component/scroll-view/scroll-view",
+	"/pages/component/movable-view/movable-view",
+	"/pages/component/text/text",
+	"/pages/component/progress/progress",
+	"/pages/component/checkbox/checkbox",
+	"/pages/component/form/form",
+	"/pages/component/label/label",
+	"/pages/component/radio/radio",
+	"/pages/component/slider/slider",
+	"/pages/component/switch/switch",
+	"/pages/component/textarea/textarea",
+	"/pages/component/editor/editor",
+	"/pages/component/navigator/navigator",
+	"/pages/component/navigator/navigate/navigate",
+	"/pages/component/navigator/redirect/redirect",
+	"/pages/component/image/image",
+	"/pages/component/web-view/web-view",
+	"/pages/API/login/login",
+	"/pages/API/get-user-info/get-user-info",
+	"/pages/API/request-payment/request-payment",
+	"/pages/API/share/share",
+	"/pages/API/set-navigation-bar-title/set-navigation-bar-title",
+	"/pages/API/show-loading/show-loading",
+	"/pages/API/navigator/navigator",
+	"/pages/API/navigator/new-page/new-vue-page-1",
+	"/pages/API/navigator/new-page/new-vue-page-2",
+	"/pages/API/pull-down-refresh/pull-down-refresh",
+	"/pages/API/animation/animation",
+	"/pages/API/get-node-info/get-node-info",
+	"/pages/API/intersection-observer/intersection-observer",
+	"/pages/API/canvas/canvas",
+	"/pages/API/action-sheet/action-sheet",
+	"/pages/API/modal/modal",
+	"/pages/API/toast/toast",
+	"/pages/API/get-network-type/get-network-type",
+	"/pages/API/get-system-info/get-system-info",
+	"/pages/API/add-phone-contact/add-phone-contact",
+	"/pages/API/on-accelerometer-change/on-accelerometer-change",
+	"/pages/API/on-compass-change/on-compass-change",
+	"/pages/API/make-phone-call/make-phone-call",
+	"/pages/API/scan-code/scan-code",
+	"/pages/API/clipboard/clipboard",
+	"/pages/API/request/request",
+	"/pages/API/upload-file/upload-file",
+	"/pages/API/download-file/download-file",
+	"/pages/API/image/image",
+	"/pages/API/voice/voice",
+	"/pages/API/background-audio/background-audio",
+	"/pages/API/video/video",
+	"/pages/API/file/file",
+	"/pages/extUI/popup/popup",
+	"/pages/extUI/segmented-control/segmented-control",
+	"/pages/extUI/collapse/collapse",
+	"/pages/extUI/pagination/pagination",
+	"/pages/extUI/steps/steps",
+	"/pages/extUI/swipe-action/swipe-action",
+	"/pages/extUI/search-bar/search-bar",
+	"/pages/extUI/fab/fab",
+	"/pages/extUI/fav/fav",
+	"/pages/extUI/section/section",
+	"/pages/extUI/transition/transition",
+	"/pages/extUI/title/title",
+	"/pages/extUI/tooltip/tooltip",
+	"/pages/extUI/link/link",
+	"/pages/extUI/combox/combox",
+	"/pages/extUI/table/table",
+	"/pages/extUI/data-checkbox/data-checkbox",
+	"/pages/extUI/easyinput/easyinput",
+	"/pages/extUI/data-select/data-select",
+	"/pages/extUI/row/row",
+	"/pages/extUI/file-picker/file-picker",
+	"/pages/extUI/button/button",
+	"/pages/template/nav-default/nav-default",
+	"/pages/template/component-communication/component-communication",
+	"/pages/template/list2detail-detail/list2detail-detail",
+	"/pages/template/tabbar/detail/detail",
+	"/pages/template/scheme/scheme",
+	"/pages/template/global/global",
+	"/pages/component/rich-text/rich-text",
+	"/pages/API/get-location/get-location",
+	"/pages/API/open-location/open-location",
+	"/pages/API/choose-location/choose-location",
+	"/pages/API/storage/storage",
+	"/pages/API/sqlite/sqlite",
+	"/pages/API/vibrate/vibrate",
+	"/pages/API/websocket-socketTask/websocket-socketTask",
+	"/pages/extUI/forms/forms",
+	"/pages/extUI/group/group",
+	"/pages/extUI/breadcrumb/breadcrumb",
+	"/pages/extUI/drawer/drawer",
+
+	...(isMatch('web') ? [
+		// 只有h5支持
+		"/pages/error/404",
+	] : [
+		// 只有h5不支持
+		"/pages/API/brightness/brightness",
+		"/pages/API/save-media/save-media",
+		"/pages/API/soter/soter",
+		"/pages/API/bluetooth/bluetooth",
+	]),
+
+	...(isMatch('android') ? [
+		// 只有app支持
+		"/pages/API/subnvue/subnvue",
+		"/pages/API/full-screen-video-ad/full-screen-video-ad",
+		"/platforms/app-plus/feedback/feedback",
+		"/platforms/app-plus/speech/speech",
+		"/platforms/app-plus/orientation/orientation",
+		"/platforms/app-plus/proximity/proximity",
+		"/platforms/app-plus/push/push",
+		"/platforms/app-plus/shake/shake",
+	] : []),
+
+	...((isMatch('android') || isMatch('mp-weixin')) ? [
+		// 只有app和微信小程序支持
+		"/pages/API/ibeacon/ibeacon",
+	] : []),
+
+	...(isMatch('mp-weixin') ? [] : [
+		// 微信小程序不支持
+		"/pages/component/web-view-local/web-view-local",
+		"/pages/template/nav-transparent/nav-transparent",
+		"/pages/template/nav-image/nav-image",
+		"/pages/template/nav-city-dropdown/nav-city-dropdown",
+		"/pages/template/nav-dot/nav-dot",
+		"/pages/template/nav-search-input/detail/detail",
+		"/pages/template/nav-button/nav-button",
+		"/pages/template/nav-search-input/nav-search-input",
+		"/pages/about/about",
+	]),
+
+	...(isMatch('safari') ? [] : [
+		// safari 在此页面会莫名卡住
+		"/pages/API/inner-audio/inner-audio",
+	]),
+
+	// 只有vue3支持
+	// "/pages/API/navigator/new-page/new-nvue-page-1",
+	// "/pages/API/navigator/new-page/new-nvue-page-2",
+
+	// 只有vue2支持
+	// "/pages/template/ucharts/ucharts",
+	// "/pages/template/vant-button/vant-button",
+
+	// 动态内容
+	// "/pages/component/ad/ad",
+	// "/pages/component/swiper/swiper",
+	// "/pages/component/canvas/canvas",
+	// "/pages/extUI/dateformat/dateformat",
+	// "/pages/extUI/datetime-picker/datetime-picker",
+	// "/pages/extUI/list/chat",
+	// "/pages/extUI/notice-bar/notice-bar",
+	// "/pages/template/list2detail-list/list2detail-list",
+	// "/pages/API/rewarded-video-ad/rewarded-video-ad",
+	// "/pages/extUI/badge/badge",
+	// "/pages/component/picker/picker",
+	// "/pages/component/picker-view/picker-view",
+	// "/pages/extUI/calendar/calendar",
+	// "/pages/component/button/button",
+
+	// nvue页面截图白屏
+	// "/pages/tabBar/component/component",
+	// "/pages/tabBar/API/API",
+	// "/pages/tabBar/template/template",
+	// "/pages/tabBar/extUI/extUI",
+	// "/pages/component/cover-view/cover-view",
+	// "/pages/component/input/input",
+	// "/pages/component/video/video",
+	// "/pages/API/map/map",
+	// "/pages/extUI/icons/icons",
+	// "/pages/extUI/load-more/load-more",
+	// "/pages/extUI/nav-bar/nav-bar",
+	// "/pages/extUI/number-box/number-box",
+	// "/pages/extUI/tag/tag",
+	// "/pages/extUI/list/list",
+	// "/pages/extUI/card/card",
+	// "/pages/extUI/swiper-dot/swiper-dot",
+	// "/pages/extUI/grid/grid",
+	// "/pages/extUI/rate/rate",
+	// "/pages/extUI/indexed-list/indexed-list",
+	// "/pages/extUI/goods-nav/goods-nav",
+	// "/pages/extUI/data-picker/data-picker",
+	// "/pages/extUI/space/space",
+	// "/pages/extUI/font/font",
+	// "/pages/extUI/color/color",
+	// "/pages/extUI/radius/radius",
+	// "/pages/template/tabbar/tabbar",
+	// "/pages/template/swiper-vertical/swiper-vertical",
+	// "/pages/template/swiper-list/swiper-list",
+	// "/pages/extUI/countdown/countdown",
+	// "/pages/template/swiper-list-nvue/swiper-list-nvue",
+	// "/pages/API/map-search/map-search",
+
+	// "/pages/API/websocket-global/websocket-global",
+	// "/pages/component/map/map",
+]
+
+function isMatch(platform) {
+	return process.env.uniTestPlatformInfo.toLocaleLowerCase().includes(platform)
+}
+// 设置position: fixed的页面不能截取完整内容
+const notFullPages = []
+
+let page;
+describe("page screenshot test", () => {
+	// HarmonyOS平台不支持截图，直接跳过
+	if (isMatch('ios') || isMatch('harmony')) {
+		it("ios platform not support", async () => {
+			expect(1).toBe(1);
+		});
+		return
+	}
+	beforeAll(async () => {
+		console.log("page screenshot test start");
+	});
+	beforeEach(async () => {
+		page = await program.reLaunch(pages[pageIndex]);
+		await page.waitFor(2000);
+	});
+	afterEach(() => {
+		pageIndex++;
+	});
+	afterAll(() => {
+		console.log("page screenshot test finish");
+	});
+	test.each(pages)("%s", async () => {
+		console.log("Taking screenshot: ", pageIndex, pages[pageIndex],
+			`${(((pageIndex + 1) / pages.length) * 100).toFixed(1)}%`);
+		let fullPage = true;
+		if (notFullPages.includes(pages[pageIndex])) {
+			fullPage = false;
+		}
+		const image = await program.screenshot({
+			fullPage: fullPage
+		});
+		expect(image).toSaveImageSnapshot();
+		await page.waitFor(500);
+	});
+});
diff --git a/pages/tabBar/API/API.nvue b/pages/tabBar/API/API.nvue
index 37bc1992..b363cbdf 100644
--- a/pages/tabBar/API/API.nvue
+++ b/pages/tabBar/API/API.nvue
@@ -47,13 +47,13 @@
                     name: '图片',
                     url: 'image'
                 },
-				// #ifndef MP-LARK
+				// #ifndef MP-LARK || MP-HARMONY
 				{
 				    name: '音频',
 				    url: 'inner-audio'
 				},
                 // #endif
-                // #ifdef APP-PLUS || MP-WEIXIN || MP-BAIDU || MP-QQ|| MP-JD
+                // #ifdef APP-PLUS || MP-WEIXIN || MP-BAIDU || MP-QQ|| MP-JD || MP-HARMONY
                 {
                     name: '录音',
                     url: 'voice'
@@ -111,10 +111,12 @@
                             name: '下拉刷新',
                             url: 'pull-down-refresh'
                         },
+						// #ifndef MP-HARMONY
                         {
                             name: '创建动画',
                             url: 'animation'
                         },
+						// #endif
 						// #ifndef QUICKAPP-WEBVIEW-UNION
                         {
                             name: '创建绘画',
@@ -127,10 +129,12 @@
                             url: 'get-node-info'
                         },
 						// #endif
+						// #ifndef MP-HARMONY
                         {
                             name: '节点布局交互状态',
                             url: 'intersection-observer'
                         },
+						// #endif
                         {
                             name: '显示操作菜单',
                             url: 'action-sheet'
@@ -189,7 +193,7 @@
                             url: 'brightness'
                         },
                         // #endif
-                        // #ifdef APP-PLUS || MP-WEIXIN || MP-QQ || MP-JD
+                        // #ifdef APP-PLUS || MP-WEIXIN || MP-QQ || MP-JD || MP-HARMONY
                         {
                             name: '蓝牙',
                             url: 'bluetooth'
@@ -207,13 +211,13 @@
                             url: 'ibeacon'
                         },
                         // #endif
-						// #ifdef APP || MP-WEIXIN
+						// #ifdef APP || MP-WEIXIN || MP-HARMONY
 						{
 							name: '监听加速度传感器',
 							url: 'on-accelerometer-change'
 						},
 						// #endif
-						// #ifdef APP || H5 ||MP-WEIXIN
+						// #ifdef APP || H5 ||MP-WEIXIN || MP-HARMONY
 						{
 							name: '监听罗盘数据',
 							url: 'on-compass-change'
@@ -347,14 +351,16 @@
                             name: '登录',
                             url: 'login'
                         },
+						// #ifndef MP-HARMONY
                         {
                             name: '获取用户信息',
                             url: 'get-user-info'
                         }
+						// #endif
                     ]
                 },
 				// #endif
-				// #ifndef H5 || QUICKAPP-WEBVIEW-UNION
+				// #ifndef H5 || QUICKAPP-WEBVIEW-UNION || MP-HARMONY
                 {
                     id: 'share',
                     name: '分享',
diff --git a/pages/tabBar/component/component.nvue b/pages/tabBar/component/component.nvue
index c7b0f181..9a58414c 100644
--- a/pages/tabBar/component/component.nvue
+++ b/pages/tabBar/component/component.nvue
@@ -20,7 +20,10 @@
 					<text class="uni-navigate-icon uni-icon">&#xe470;</text>
 				</view>
 			</view>
-		</view>
+		</view>
+		<!-- #ifdef APP-HARMONY -->
+		<privacy-dialog ref="privacyDialogRef" :tabBar="true" @agree="isAgree = true" @disagree="isAgree = false"></privacy-dialog>
+		<!-- #endif -->
 	</view>
 </template>
 <script>
@@ -42,7 +45,8 @@
 			}
 		},
 		data() {
-			return {
+			return {
+				isAgree: null,
 				list: [{
 						id: 'view',
 						name: '视图容器',
@@ -53,9 +57,11 @@
 							'swiper'
 							// #ifndef MP-TOUTIAO || MP-LARK
 							,
-							'movable-view',
+							'movable-view',
+							// #ifndef MP-HARMONY
 							'cover-view'
 							// #endif
+							// #endif
 						]
 					}, {
 						id: 'content',
@@ -118,7 +124,7 @@
 						}]
 					},
 					// #endif
-					// #ifndef APP-PLUS || H5 || MP-LARK || MP-JD
+					// #ifndef APP-PLUS || H5 || MP-LARK || MP-JD || MP-HARMONY
 					{
 						id: 'web-view',
 						name: '网页',
@@ -126,7 +132,7 @@
 						pages: ['web-view']
 					},
 					// #endif
-					// #ifndef H5 || MP-BAIDU || QUICKAPP-WEBVIEW || MP-LARK || MP-JD
+					// #ifndef H5 || MP-BAIDU || QUICKAPP-WEBVIEW || MP-LARK || MP-JD || MP-HARMONY
 					{
 						id: 'ad',
 						url: 'ad',
@@ -147,6 +153,15 @@
 			uni.navigateTo({
 				url: '/pages/about/about'
 			});
+		},
+		onReady() {
+		  // #ifdef APP-HARMONY
+		  let isAgree = this.$refs.privacyDialogRef.getIsAgree();
+		  console.log('is argree',isAgree);
+		  if (!isAgree) {
+		    this.$refs.privacyDialogRef.open();
+		  }
+		  // #endif
 		},
 		// #ifdef H5
 		watch: {
@@ -206,6 +221,9 @@
 						})
 					}
 				}
+			},
+			resetPrivacy(){
+				uni.removeStorageSync('uni-privacy-agree')
 			}
 		}
 	}
diff --git a/pages/tabBar/component/component.test.js b/pages/tabBar/component/component.test.js
index 3640f673..624f534b 100644
--- a/pages/tabBar/component/component.test.js
+++ b/pages/tabBar/component/component.test.js
@@ -1,5 +1,13 @@
 describe('pages/tabBar/component/component.nvue', () => {
-    let page
+	let page, containsVite, isApp;
+	containsVite = process.env.UNI_CLI_PATH.includes('uniapp-cli-vite')
+	isApp = process.env.UNI_PLATFORM.includes('app')
+	if (containsVite && isApp) {
+	  it('vue3', async () => {
+	    expect(1).toBe(1)
+	  })
+	  return
+	}
     beforeAll(async () => {
         // 重新reLaunch至首页，并获取首页page对象（其中 program 是uni-automator自动注入的全局对象）
         page = await program.reLaunch('/pages/tabBar/component/component')
@@ -29,7 +37,7 @@ describe('pages/tabBar/component/component.nvue', () => {
       const lists = await page.$$('.uni-panel')
 	  if(process.env.UNI_PLATFORM == 'app-plus' || process.env.UNI_PLATFORM == 'mp-weixin'){
 	  	expect(lists.length).toBe(9)
-	  }else if(process.env.UNI_PLATFORM == 'h5'){
+	  }else if(process.env.UNI_PLATFORM == 'h5' && !containsVite){
 	  	expect(lists.length).toBe(8)
 	  }
     })
diff --git a/pages/tabBar/extUI/extUI.test.js b/pages/tabBar/extUI/extUI.test.js
index b7b89ee5..8699152a 100644
--- a/pages/tabBar/extUI/extUI.test.js
+++ b/pages/tabBar/extUI/extUI.test.js
@@ -1,5 +1,13 @@
 describe('pages/tabBar/extUI/extUI.nvue', () => {
-    let page
+	let page, containsVite, isApp;
+	containsVite = process.env.UNI_CLI_PATH.includes('uniapp-cli-vite')
+	isApp = process.env.UNI_PLATFORM.includes('app')
+	if (containsVite && isApp) {
+	  it('vue3', async () => {
+	    expect(1).toBe(1)
+	  })
+	  return
+	}
     beforeAll(async () => {
         // 重新reLaunch至首页，并获取首页page对象（其中 program 是uni-automator自动注入的全局对象）
         page = await program.reLaunch('/pages/tabBar/extUI/extUI')
@@ -32,8 +40,6 @@ describe('pages/tabBar/extUI/extUI.nvue', () => {
 			const extUIEl  = await page.$('.extUI')
 			lists = await extUIEl.$$('.uni-panel')
 		}
-		console.log('lists.length:',lists.length,(await page.data('lists')).length)
-		console.log('uniTestPlatformInfo:',process.env.uniTestPlatformInfo)
 		if(process.env.UNI_PLATFORM == 'app-plus'){
 			expect(lists.length).toBe(41)
 		}else if(process.env.UNI_PLATFORM == 'h5' || process.env.UNI_PLATFORM == 'mp-weixin'){
@@ -51,7 +57,8 @@ describe('pages/tabBar/extUI/extUI.nvue', () => {
         expect(await listHead.attribute('class')).toContain('uni-panel-h')
         // 点击第一个 item，验证打开的新页面是否正确
         await listHead.tap()
-		await page.waitFor(2000)
+		const waitTime = process.env.UNI_PLATFORM == 'mp-weixin'? 5000 : 2000
+		await page.waitFor(waitTime)
         expect((await program.currentPage()).path).toBe('pages/extUI/badge/badge')
         await page.waitFor(500)
         // 执行 navigateBack 验证是否返回
diff --git a/pages/tabBar/template/template.nvue b/pages/tabBar/template/template.nvue
index 7a92387d..3945223c 100644
--- a/pages/tabBar/template/template.nvue
+++ b/pages/tabBar/template/template.nvue
@@ -116,12 +116,34 @@
 					{
 						name: 'swiper-list',
 						url: 'swiper-list-nvue'
-					},
+					},
+					// #endif
+					{
+						name: 'GlobalData和vuex',
+						url: 'global'
+					},
+					// #ifdef APP-NVUE
+					{
+						name: 'vuex-nvue',
+						url: 'vuex-nvue'
+					},
+					// #endif
+					{
+						name: 'vuex-vue',
+						url: 'vuex-vue'
+					},
+					// #ifdef VUE3
+					{
+						name: 'pinia',
+						url: 'pinia'
+					},
+					// #endif
+					// #ifdef APP || H5
+					{
+						name: 'renderjs',
+						url: 'renderjs'
+					},
 					// #endif
-					{
-						name: 'GlobalData和vuex',
-						url: 'global'
-					},
 					// #ifdef APP-PLUS
 					{
 						name: '问题反馈',
@@ -189,7 +211,7 @@
 			},
 			goDetailPage(e) {
 				let path = e.url ? e.url : e;
-				let url = ~path.indexOf('platform') ? path : '/pages/template/' + path + '/' + path;
+				let url = ~path.indexOf('platform') ? path : '/pages/template/' + path + '/' + path;
 				if (this.hasLeftWin) {
 					uni.reLaunch({
 						url: url
diff --git a/pages/template/crypto-api/crypto-api.test.js b/pages/template/crypto-api/crypto-api.test.js
new file mode 100644
index 00000000..d4c03ed9
--- /dev/null
+++ b/pages/template/crypto-api/crypto-api.test.js
@@ -0,0 +1,31 @@
+// uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
+
+describe('/pages/template/crypto-api/crypto-api.vue', () => {
+	let page
+
+	//  weixin 不提供俱全变量 crypto
+	console.log(33, process.env.UNI_PLATFORM)
+	const isWeixin = process.env.UNI_PLATFORM === "mp-weixin"
+
+	if (isWeixin) {
+		it('微信小程序不支持 crypto API', () => {
+			expect(true).toBe(true)
+		})
+		return
+	}
+
+	beforeAll(async () => {
+		// 重新reLaunch至首页，并获取首页page对象（其中 program 是uni-automator自动注入的全局对象）
+		page = await program.reLaunch('/pages/template/crypto-api/crypto-api')
+		await page.waitFor("view")
+	})
+
+	it('crypto-api', async () => {
+		const button = await page.$('#button')
+		await button.tap()
+		await page.waitFor(500)
+		const strElement = await page.$('#str')
+		const result = await strElement.text()
+		expect(result).toBe('true-true-true')
+	})
+});
diff --git a/pages/template/crypto-api/crypto-api.vue b/pages/template/crypto-api/crypto-api.vue
new file mode 100644
index 00000000..a83e62b7
--- /dev/null
+++ b/pages/template/crypto-api/crypto-api.vue
@@ -0,0 +1,35 @@
+<template>
+	<view>
+		<view id="str">{{ str.join("-") }}</view>
+		<button id="button" @click="getRandomValues">
+			crypto.getRandomValues
+		</button>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				str: [false, false, false]
+			};
+		},
+		methods: {
+			getRandomValues() {
+				try {
+					const isExists = typeof crypto === "object";
+					const hasFunction =
+						typeof crypto.getRandomValues === "function";
+					var rnds8 = new Uint8Array(16);
+					const res = crypto.getRandomValues(rnds8);
+					const isLengthSame = res.length === 16;
+					this.str = [isExists, hasFunction, isLengthSame];
+				} catch (e) {
+					console.log("crypto error:", e);
+				}
+			},
+		},
+	};
+</script>
+
+<style></style>
diff --git a/pages/template/issue-15216/issue-15216.test.js b/pages/template/issue-15216/issue-15216.test.js
new file mode 100644
index 00000000..0f4b3976
--- /dev/null
+++ b/pages/template/issue-15216/issue-15216.test.js
@@ -0,0 +1,18 @@
+describe('renderjs', () => {
+	let page;
+	if (process.env.UNI_PLATFORM !== "mp-weixin") {
+		// renderjs仅支持App和H5
+		it('not mp-weixin', async () => {
+			expect(1).toBe(1)
+		})
+		return
+	}
+	beforeAll(async () => {
+		page = await program.reLaunch('/pages/template/issue-15216/issue-15216')
+		await page.waitFor('view');
+	});
+	it('check page data', async () => {
+		const uniXxx = await page.data('uniXxx');
+		expect(uniXxx).toEqual('abc');
+	});
+});
diff --git a/pages/template/issue-15216/issue-15216.vue b/pages/template/issue-15216/issue-15216.vue
new file mode 100644
index 00000000..1fbcec0a
--- /dev/null
+++ b/pages/template/issue-15216/issue-15216.vue
@@ -0,0 +1,29 @@
+<template>
+  <view>
+    test
+  </view>
+</template>
+
+<script>
+  if (!uni.xxx) {
+    uni.xxx = 'abc'
+  }
+  const x = uni.xxx
+  console.log(x)
+  export default {
+    data() {
+      return {
+        uniXxx: uni.xxx
+      }
+    },
+    onLoad() {
+
+    },
+    methods: {
+
+    }
+  }
+</script>
+
+<style>
+</style>
diff --git a/pages/template/list2detail-detail/list2detail-detail.vue b/pages/template/list2detail-detail/list2detail-detail.vue
index 078d60dd..73e04455 100644
--- a/pages/template/list2detail-detail/list2detail-detail.vue
+++ b/pages/template/list2detail-detail/list2detail-detail.vue
@@ -10,7 +10,7 @@
 			<text class="article-time">{{banner.published_at}}</text>
 		</view>
 		<view class="article-content">
-			<rich-text :nodes="htmlNodes"></rich-text>
+			<rich-text v-if="visible" :nodes="htmlNodes"></rich-text>
 		</view>
 		<!-- #ifdef MP-WEIXIN || MP-QQ -->
 		<ad v-if="htmlNodes.length > 0" unit-id="adunit-01b7a010bf53d74e"></ad>
@@ -54,7 +54,9 @@
 			return {
 				title: '',
 				banner: {},
-				htmlNodes: []
+				htmlNodes: [],
+				visible: true,
+
 			}
 		},
 		onLoad(event) {
@@ -125,7 +127,13 @@
 					success: (data) => {
 						if (data.statusCode == 200) {
 							var htmlString = data.data.content.replace(/\\/g, "").replace(/<img/g, "<img style=\"display:none;\"");
-							this.htmlNodes = htmlParser(htmlString);
+							this.htmlNodes = htmlParser(htmlString);
+							// #ifdef MP-HARMONY
+							this.visible = false;
+							this.$nextTick(()=>{
+								this.visible = true
+							})
+							// #endif
 						}
 					},
 					fail: () => {
diff --git a/pages/template/pinia/pinia.test.js b/pages/template/pinia/pinia.test.js
new file mode 100644
index 00000000..462d7256
--- /dev/null
+++ b/pages/template/pinia/pinia.test.js
@@ -0,0 +1,50 @@
+describe('test pinia', () => {
+  let page,containsVite;
+  containsVite = process.env.UNI_CLI_PATH.includes('uniapp-cli-vite')
+  if (!containsVite) {
+	// Vue 2 项目暂不支持 Pinia
+    it('is vue2', async () => {
+      expect(1).toBe(1)
+    })
+    return
+  }
+  beforeAll(async () => {
+    page = await program.reLaunch('/pages/template/pinia/pinia')
+    await page.waitFor('view');
+  });
+  it('check page data', async () => {
+    const count = await page.$('.count');
+    expect(await count.text()).toEqual('当前计数：0');
+    const doubleCount = await page.$('.doubleCount');
+    expect(await doubleCount.text()).toEqual('计数翻倍：0');
+  });
+  it('store incrementCounter', async () => {
+    await page.callMethod('incrementCounter')
+    const count = await page.$('.count');
+    expect(await count.text()).toEqual('当前计数：1');
+    const doubleCount = await page.$('.doubleCount');
+    expect(await doubleCount.text()).toEqual('计数翻倍：2');
+  });
+  it('store incrementPatchCounter', async () => {
+    await page.callMethod('incrementPatchCounter')
+    const count = await page.$('.count');
+    expect(await count.text()).toEqual('当前计数：2');
+    const doubleCount = await page.$('.doubleCount');
+    expect(await doubleCount.text()).toEqual('计数翻倍：4');
+  });
+  it('store actions', async () => {
+    const increment = await page.$('.increment');
+    await increment.tap()
+    const countIn = await page.$('.count');
+    expect(await countIn.text()).toEqual('当前计数：3');
+    const doubleCountIn = await page.$('.doubleCount');
+    expect(await doubleCountIn.text()).toEqual('计数翻倍：6');
+
+    const decrement = await page.$('.decrement');
+    await decrement.tap()
+    const countDe = await page.$('.count');
+    expect(await countDe.text()).toEqual('当前计数：2');
+    const doubleCountDe = await page.$('.doubleCount');
+    expect(await doubleCountDe.text()).toEqual('计数翻倍：4');
+  });
+});
diff --git a/pages/template/pinia/pinia.vue b/pages/template/pinia/pinia.vue
new file mode 100644
index 00000000..7e9a1b0b
--- /dev/null
+++ b/pages/template/pinia/pinia.vue
@@ -0,0 +1,32 @@
+<template>
+  <view class="uni-product">
+    <page-head title="Pinia"></page-head>
+    <text class="count">当前计数：{{ counter.count }}</text>
+    <text class="doubleCount" style="margin: 20rpx 0;">计数翻倍：{{ counter.doubleCount }}</text>
+    <button @click="incrementCounter">增加计数</button>
+    <button @click="incrementPatchCounter">使用$patch方法增加计数</button>
+    <button class="increment" @click="counter.increment">通过actions中的increment增加计数</button>
+    <button class="decrement" @click="counter.decrement">通过actions中的decrement减少计数</button>
+  </view>
+</template>
+
+<script>
+import { useCounterStore } from '@/store/counter'
+export default {
+  setup() {
+    const counter = useCounterStore()
+    function incrementCounter() {
+      counter.count++
+    }
+    function incrementPatchCounter() {
+      // 或者使用 $patch 方法
+      counter.$patch({ count: counter.count + 1 })
+    }
+    return {
+      counter,
+      incrementCounter,
+      incrementPatchCounter
+    }
+  }
+}
+</script>
diff --git a/pages/template/renderjs/renderjs.test.js b/pages/template/renderjs/renderjs.test.js
new file mode 100644
index 00000000..ad6a3358
--- /dev/null
+++ b/pages/template/renderjs/renderjs.test.js
@@ -0,0 +1,38 @@
+describe('renderjs', () => {
+	let page, btns;
+	if (process.env.UNI_PLATFORM === "mp-weixin") {
+		// renderjs仅支持App和H5
+		it('is mp-weixin', async () => {
+			expect(1).toBe(1)
+		})
+		return
+	}
+	beforeAll(async () => {
+		page = await program.reLaunch('/pages/template/renderjs/renderjs')
+		await page.waitFor('view');
+		btns = await page.$$('button');
+	});
+	it('check page data', async () => {
+		const data1 = await page.$('.renderjs');
+		expect(await data1.text()).toEqual('serviceData');
+	});
+	it('callMethod renderjs', async () => {
+		await btns[0].tap();
+		await page.waitFor(300);
+		const data2 = await page.$('.renderjs');
+		expect(await data2.text()).toEqual('renderjsData');
+	});
+	it('callMethod service', async () => {
+		await btns[1].tap();
+		await page.waitFor(300);
+		const data3 = await page.$('.renderjs');
+		expect(await data3.text()).toEqual('serviceData改变了');
+	});
+	if (process.env.UNI_PLATFORM === "h5") {
+		it('trigger getServiceData', async () => {
+			expect(await page.data('newValue')).toEqual('serviceData改变了');
+			expect(await page.data('oldValue')).toEqual('renderjsData');
+		});
+	}
+
+});
diff --git a/pages/template/renderjs/renderjs.vue b/pages/template/renderjs/renderjs.vue
new file mode 100644
index 00000000..498e0cbf
--- /dev/null
+++ b/pages/template/renderjs/renderjs.vue
@@ -0,0 +1,60 @@
+<template>
+	<view>
+		<page-head :title="title"></page-head>
+		<view :data="data" :change:data="renderjs.getServiceData" class="renderjs" style="margin:40rpx;">
+			{{data}}
+		</view>
+		<button @click="renderjs.sendRenderjsData">调用renderjs中的sendRenderjsData方法</button>
+		<button @click="changeServiceData">改变data的值,renderjs层收到改变后的数据</button>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				title: 'renderjs',
+				data: 'serviceData',
+			};
+		},
+		methods: {
+			changeServiceData() {
+				this.data = "serviceData改变了";
+			},
+			getRenderData(renderjsValue) {
+				console.log('renderjs返回的值-->', renderjsValue);
+				this.data = renderjsValue
+			}
+		}
+	};
+</script>
+
+<script module="renderjs" lang="renderjs">
+	export default {
+		data() {
+			return {
+				value: 'renderjsData',
+				newValue: '',
+				oldValue: ''
+			}
+		},
+		methods: {
+			// 监听 service 层数据变更
+			getServiceData(newValue, oldValue, ownerVm, vm) {
+				// console.log('data变化了newValue', newValue)
+				// console.log('data变化了oldValue', oldValue)
+				this.newValue = newValue
+				this.oldValue = oldValue
+			},
+			// 调用 service 层的方法
+			sendRenderjsData(event, ownerInstance) {
+				// vue3-h5，ownerInstance undefined
+				if(ownerInstance){
+					ownerInstance.callMethod('getRenderData', this.value)
+				}else{
+					this.$ownerInstance.callMethod('getRenderData', this.value)
+				}
+			}
+		}
+	};
+</script>
diff --git a/pages/template/tabbar/tabbar.nvue b/pages/template/tabbar/tabbar.nvue
index 17b812d1..abfa65a0 100644
--- a/pages/template/tabbar/tabbar.nvue
+++ b/pages/template/tabbar/tabbar.nvue
@@ -78,11 +78,11 @@
                 "width": 563,
                 "height": 316
             }, {
-                "url": "https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b4cd3000-517d-11eb-a16f-5b3e54966275.jpg",
+                "url": "https://web-ext-storage.dcloud.net.cn/hello-uni-app/template-tabbar-2.jpg",
                 "width": 641,
                 "height": 360
             }, {
-                "url": "https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b7c7f970-517d-11eb-97b7-0dc4655d6e68.jpg",
+                "url": "https://web-assets.dcloud.net.cn/unidoc/zh/shuijiao-small.jpg",
                 "width": 640,
                 "height": 360
             }],
@@ -95,7 +95,7 @@
             "datetime": "2小时前",
             "article_type": 4,
             "title": "uni-app 支持原生小程序自定义组件，更开放、更自由",
-            "image_url": "https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b2e201d0-517d-11eb-8a36-ebb87efcf8c0.jpg",
+            "image_url": "https://web-ext-storage.dcloud.net.cn/hello-uni-app/template-tabbar-1.jpg",
             "source": "DCloud",
             "comment_count": 69
         }
diff --git a/pages/template/vuex-nvue/vuex-nvue.nvue b/pages/template/vuex-nvue/vuex-nvue.nvue
new file mode 100644
index 00000000..588910af
--- /dev/null
+++ b/pages/template/vuex-nvue/vuex-nvue.nvue
@@ -0,0 +1,56 @@
+<template>
+  <view class="uni-product">
+	<page-head title="vuex:nvue页面"></page-head>
+    <text class="username">用户名：{{username}}</text>
+    <text class="sex">性别：{{sex}}</text>
+    <view class="age">年龄：{{age}}</view>
+    <view class="doubleAge">年龄翻倍：{{doubleAge}}</view>
+    <button @click="addAge">增加1岁</button>
+    <button @click="addAgeTen">增加10岁</button>
+    <button @click="addAgeAction">增加20岁</button>
+    <button @click="resetAge">重置</button>
+  </view>
+</template>
+<script>
+  import store from '@/store/index.js';
+  // import {mapState} from 'vuex'
+  export default {
+    data() {
+      return {}
+    },
+    computed: {
+      // ...mapState(['age']),
+      username() {
+        return this.$store.state.username
+      },
+      sex() {
+        return store.state.sex
+      },
+      age() {
+        return store.state.age
+      },
+      doubleAge() {
+        return store.getters.doubleAge
+      }
+    },
+    methods: {
+      addAge() {
+        store.commit('increment')
+      },
+      addAgeTen() {
+        store.commit('incrementTen', {
+          amount: 10
+        })
+      },
+      addAgeAction () {
+        // 以载荷形式分发
+        store.dispatch('incrementAsync', {
+          amount: 20
+        })
+      },
+      resetAge(){
+        store.commit('resetAge')
+      }
+    }
+  }
+</script>
diff --git a/pages/template/vuex-vue/vuex-vue.vue b/pages/template/vuex-vue/vuex-vue.vue
new file mode 100644
index 00000000..90597403
--- /dev/null
+++ b/pages/template/vuex-vue/vuex-vue.vue
@@ -0,0 +1,53 @@
+<template>
+  <view class="uni-product">
+	<page-head title="vuex:vue页面"></page-head>
+    <text class="username">用户名：{{username}}</text>
+    <text class="sex">性别：{{sex}}</text>
+    <view class="age">年龄：{{age}}</view>
+    <view class="doubleAge">年龄翻倍：{{doubleAge}}</view>
+    <button @click="addAge">增加1岁</button>
+    <button @click="addAgeTen">增加10岁</button>
+    <button @click="addAgeAction">增加20岁</button>
+    <button @click="resetAge">重置</button>
+  </view>
+</template>
+<script>
+  import store from '@/store/index.js';
+  import { mapState } from 'vuex'
+  export default {
+    data() {
+      return {}
+    },
+    computed: {
+      ...mapState(['age']),
+      username() {
+        return this.$store.state.username
+      },
+      sex() {
+        return store.state.sex
+      },
+      doubleAge() {
+        return store.getters.doubleAge
+      }
+    },
+    methods: {
+      addAge() {
+        store.commit('increment')
+      },
+      addAgeTen() {
+        store.commit('incrementTen', {
+          amount: 10
+        })
+      },
+      addAgeAction () {
+        // 以载荷形式分发
+        store.dispatch('incrementAsync', {
+          amount: 20
+        })
+      },
+      resetAge(){
+        store.commit('resetAge')
+      }
+    }
+  }
+</script>
diff --git a/pages/template/vuex-vue/vuex.test.js b/pages/template/vuex-vue/vuex.test.js
new file mode 100644
index 00000000..9f4bdaf8
--- /dev/null
+++ b/pages/template/vuex-vue/vuex.test.js
@@ -0,0 +1,91 @@
+let page;
+const containsVite = process.env.UNI_CLI_PATH.includes('uniapp-cli-vite');
+const isApp = process.env.UNI_PLATFORM.includes('app');
+const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase();
+const isHarmony = platformInfo.startsWith('harmony')
+function createTests(pagePath, type) {
+	return describe(`测试页面路径: ${pagePath}`, () => {
+		async function toScreenshot(imgName) {
+			await page.waitFor(300)
+			const image = await program.screenshot({
+				deviceShot: true
+			});
+			expect(image).toSaveImageSnapshot({
+				customSnapshotIdentifier() {
+					return imgName
+				}
+			})
+			await page.waitFor(500);
+		}
+		if (platformInfo === 'ios_simulator 13.7') {
+			it('skip', async () => {
+				expect(1).toBe(1)
+			})
+			return
+		}
+		beforeAll(async () => {
+			page = await program.reLaunch(pagePath)
+			await page.waitFor('view');
+			// isHarmony不支持截图跳过
+			if (!isHarmony) {await toScreenshot(type)}
+		});
+		afterAll(async () => {
+			await page.callMethod('resetAge')
+		});
+		it('check page data', async () => {
+			const username = await page.$('.username');
+			expect(await username.text()).toEqual('用户名：foo');
+			const sex = await page.$('.sex');
+			expect(await sex.text()).toEqual('性别：男');
+			const age = await page.$('.age');
+			expect(await age.text()).toEqual('年龄：10');
+			const doubleAge = await page.$('.doubleAge');
+			expect(await doubleAge.text()).toEqual('年龄翻倍：20');
+		});
+		it('store mutations', async () => {
+			await page.callMethod('addAge')
+			const age = await page.$('.age');
+			expect(await age.text()).toEqual('年龄：11');
+			const doubleAge = await page.$('.doubleAge');
+			expect(await doubleAge.text()).toEqual('年龄翻倍：22');
+		});
+		it('store getters', async () => {
+			await page.callMethod('addAgeTen')
+			const age = await page.$('.age');
+			expect(await age.text()).toEqual('年龄：21');
+			const doubleAge = await page.$('.doubleAge');
+			expect(await doubleAge.text()).toEqual('年龄翻倍：42');
+		});
+		it('store actions', async () => {
+			await page.callMethod('addAgeAction')
+			const age = await page.$('.age');
+			expect(await age.text()).toEqual('年龄：41');
+			const doubleAge = await page.$('.doubleAge');
+			expect(await doubleAge.text()).toEqual('年龄翻倍：82');
+		});
+	})
+}
+
+// vue3-nvue不支持自动化测试
+const nvuePath = '/pages/template/vuex-nvue/vuex-nvue'
+const vuepath = '/pages/template/vuex-vue/vuex-vue'
+if (containsVite) {
+	// vue3
+	if (isApp) {
+		createTests(vuepath, 'vue3-App-vue');
+	} else if (process.env.UNI_PLATFORM == 'h5') {
+		createTests(vuepath, 'vue3-H5-vue');
+	} else {
+		createTests(vuepath, 'vue3-Mp-vue');
+	}
+} else {
+	// vue2
+	if (isApp) {
+		createTests(nvuePath, 'vue2-App-nvue');
+		createTests(vuepath, 'vue2-App-vue');
+	} else if (process.env.UNI_PLATFORM == 'h5') {
+		createTests(vuepath, 'vue2-H5-vue');
+	} else {
+		createTests(vuepath, 'vue2-Mp-vue');
+	}
+}
diff --git a/platforms/app-plus/shake/shake.vue b/platforms/app-plus/shake/shake.vue
index 01ce86be..eb13a6c4 100644
--- a/platforms/app-plus/shake/shake.vue
+++ b/platforms/app-plus/shake/shake.vue
@@ -21,15 +21,15 @@
 		computed:{
 			pageIndex() {
 				if (this.index === 1) {
-					return 'aff47ed0-517d-11eb-8ff1-d5dcf8779628'
+					return 'shake-1'
 				} else if (this.index === 2) {
-					return '1fc36f80-5199-11eb-a16f-5b3e54966275'
+					return 'shake-2'
 				} else if (this.index === 3) {
-					return '20a3bd60-5199-11eb-97b7-0dc4655d6e68'
+					return 'shake-3'
 				} else if (this.index === 4) {
-					return '8b872410-51a7-11eb-8a36-ebb87efcf8c0'
+					return 'shake-4'
 				} else {
-					return 'aff47ed0-517d-11eb-8ff1-d5dcf8779628'
+					return 'shake-1'
 				}
 			}
 		},
@@ -46,7 +46,7 @@
 						if (this.index > 4) {
 							this.index = 1
 						}
-						this.img = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/' + this.pageIndex + '.jpg';
+						this.img = 'https://web-ext-storage.dcloud.net.cn/hello-uni-app/' + this.pageIndex + '.jpg';
 					}, 2000);
 					this.show = true;
 					if (t) {
diff --git a/static/image-resize-3.0.1.min.js b/static/web/image-resize-3.0.1.min.js
similarity index 100%
rename from static/image-resize-3.0.1.min.js
rename to static/web/image-resize-3.0.1.min.js
diff --git a/static/quill-1.3.7.min.js b/static/web/quill-1.3.7.min.js
similarity index 100%
rename from static/quill-1.3.7.min.js
rename to static/web/quill-1.3.7.min.js
diff --git a/store/counter.js b/store/counter.js
new file mode 100644
index 00000000..1e2adf77
--- /dev/null
+++ b/store/counter.js
@@ -0,0 +1,17 @@
+import { defineStore } from 'pinia'
+export const useCounterStore = defineStore('counter', {
+  state: () => ({
+    count: 0
+  }),
+  getters: {
+    doubleCount: (state) => state.count * 2
+  },
+  actions: {
+    increment() {
+      this.count++
+    },
+    decrement() {
+      this.count--
+    }
+  }
+})
diff --git a/store/index.js b/store/index.js
index 9da3f760..2d0a3275 100644
--- a/store/index.js
+++ b/store/index.js
@@ -22,7 +22,11 @@ const store = createStore({
 		leftWinActive: '/pages/component/view/view',
 		activeOpen: '',
 		menu: [],
-		univerifyErrorMsg: ''
+		univerifyErrorMsg: '',
+		// vuex测试例使用
+		username: "foo",
+		sex: "男",
+		age: 10
 	},
 	mutations: {
 		login(state, provider) {
@@ -66,14 +70,32 @@ const store = createStore({
 		},
 		setUniverifyErrorMsg(state,payload = ''){
 			state.univerifyErrorMsg = payload
+		},
+		// vuex测试例使用
+		increment(state) {
+		  state.age++;
+		},
+		incrementTen(state, payload) {
+		  state.age += payload.amount
+		},
+		resetAge(state){
+		  state.age = 10
 		}
 	},
 	getters: {
 		currentColor(state) {
 			return state.colorList[state.colorIndex]
+		},
+		// vuex测试例使用
+		doubleAge(state) {
+		  return state.age * 2;
 		}
 	},
-	actions: {
+	actions: {
+		// vuex测试例使用
+		incrementAsync(context , payload) {
+		  context.commit('incrementTen',payload)
+		},
 		// lazy loading openid
 		getUserOpenId: async function({
 			commit,
diff --git a/template.h5.html b/template.h5.html
index 1dbec302..b84b7af2 100644
--- a/template.h5.html
+++ b/template.h5.html
@@ -41,8 +41,8 @@
 			// 	document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
 			// })
 		</script>
-		<script src="<%= BASE_URL %>static/image-resize-3.0.1.min.js"></script>
-		<script src="<%= BASE_URL %>static/quill-1.3.7.min.js"></script>
+		<script src="<%= BASE_URL %>static/web/image-resize-3.0.1.min.js"></script>
+		<script src="<%= BASE_URL %>static/web/quill-1.3.7.min.js"></script>
 		<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
 	</head>
 	<body>
diff --git a/uni_modules/uni-calendar/changelog.md b/uni_modules/uni-calendar/changelog.md
index a728bb80..30ca0df7 100644
--- a/uni_modules/uni-calendar/changelog.md
+++ b/uni_modules/uni-calendar/changelog.md
@@ -1,3 +1,5 @@
+## 1.4.12（2024-09-21）
+- 修复 calendar在选择日期范围后重新选择日期需要点两次的Bug
 ## 1.4.11（2024-01-10）
 - 修复 回到今天时，月份显示不一致问题
 ## 1.4.10（2023-04-10）
diff --git a/uni_modules/uni-calendar/components/uni-calendar/calendar.js b/uni_modules/uni-calendar/components/uni-calendar/calendar.js
index b8d7d6fc..55eed81d 100644
--- a/uni_modules/uni-calendar/components/uni-calendar/calendar.js
+++ b/uni_modules/uni-calendar/components/uni-calendar/calendar.js
@@ -351,10 +351,8 @@ var calendar = {
         s = '\u521d\u5341'; break
       case 20:
         s = '\u4e8c\u5341'; break
-        break
       case 30:
         s = '\u4e09\u5341'; break
-        break
       default :
         s = this.nStr2[Math.floor(d / 10)]
         s += this.nStr1[d % 10]
diff --git a/uni_modules/uni-calendar/components/uni-calendar/util.js b/uni_modules/uni-calendar/components/uni-calendar/util.js
index 671f61e0..6e949d73 100644
--- a/uni_modules/uni-calendar/components/uni-calendar/util.js
+++ b/uni_modules/uni-calendar/components/uni-calendar/util.js
@@ -296,7 +296,7 @@ class Calendar {
 
 		if (!this.range) return
 		if (before && after) {
-			this.multipleStatus.before = ''
+			this.multipleStatus.before = fullDate
 			this.multipleStatus.after = ''
 			this.multipleStatus.data = []
 		} else {
diff --git a/uni_modules/uni-calendar/package.json b/uni_modules/uni-calendar/package.json
index bceaed37..ec924e91 100644
--- a/uni_modules/uni-calendar/package.json
+++ b/uni_modules/uni-calendar/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-calendar",
   "displayName": "uni-calendar 日历",
-  "version": "1.4.11",
+  "version": "1.4.12",
   "description": "日历组件",
   "keywords": [
     "uni-ui",
@@ -44,7 +44,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
@@ -82,4 +83,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/uni_modules/uni-combox/changelog.md b/uni_modules/uni-combox/changelog.md
index 15256a2e..64972dbc 100644
--- a/uni_modules/uni-combox/changelog.md
+++ b/uni_modules/uni-combox/changelog.md
@@ -1,3 +1,5 @@
+## 1.0.2（2024-09-21）
+- 新增 clearAble属性
 ## 1.0.1（2021-11-23）
 - 优化 label、label-width 属性
 ## 1.0.0（2021-11-19）
diff --git a/uni_modules/uni-combox/components/uni-combox/uni-combox.vue b/uni_modules/uni-combox/components/uni-combox/uni-combox.vue
index 98bf152e..ed1f7cd4 100644
--- a/uni_modules/uni-combox/components/uni-combox/uni-combox.vue
+++ b/uni_modules/uni-combox/components/uni-combox/uni-combox.vue
@@ -4,10 +4,11 @@
 			<text>{{label}}</text>
 		</view>
 		<view class="uni-combox__input-box">
-			<input class="uni-combox__input" type="text" :placeholder="placeholder" 
-			placeholder-class="uni-combox__input-plac" v-model="inputVal" @input="onInput" @focus="onFocus" 
-@blur="onBlur" />
-			<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#999" @click="toggleSelector">
+			<input class="uni-combox__input" type="text" :placeholder="placeholder" placeholder-class="uni-combox__input-plac"
+				v-model="inputVal" @input="onInput" @focus="onFocus" @blur="onBlur" />
+			<uni-icons v-if="!inputVal || !clearAble" :type="showSelector? 'top' : 'bottom'" size="14" color="#999" @click="toggleSelector">
+			</uni-icons>
+			<uni-icons v-if="inputVal && clearAble" type="clear" size="24" color="#999" @click="clean">
 			</uni-icons>
 		</view>
 		<view class="uni-combox__selector" v-if="showSelector">
@@ -16,8 +17,8 @@
 				<view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0">
 					<text>{{emptyTips}}</text>
 				</view>
-				<view class="uni-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index" 
-				@click="onSelectorClick(index)">
+				<view class="uni-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index"
+					@click="onSelectorClick(index)">
 					<text>{{item}}</text>
 				</view>
 			</scroll-view>
@@ -41,6 +42,10 @@
 		name: 'uniCombox',
 		emits: ['input', 'update:modelValue'],
 		props: {
+			clearAble: {
+				type: Boolean,
+				default: false
+			},
 			border: {
 				type: Boolean,
 				default: true
@@ -143,6 +148,10 @@
 					this.$emit('input', this.inputVal)
 					this.$emit('update:modelValue', this.inputVal)
 				})
+			},
+			clean() {
+				this.inputVal = ''
+				this.onInput()
 			}
 		}
 	}
@@ -272,4 +281,4 @@
 	.uni-combox__no-border {
 		border: none;
 	}
-</style>
+</style>
diff --git a/uni_modules/uni-combox/package.json b/uni_modules/uni-combox/package.json
index 3fed6140..779716d7 100644
--- a/uni_modules/uni-combox/package.json
+++ b/uni_modules/uni-combox/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-combox",
   "displayName": "uni-combox 组合框",
-  "version": "1.0.1",
+  "version": "1.0.2",
   "description": "可以选择也可以输入的表单项 ",
   "keywords": [
     "uni-ui",
@@ -17,11 +17,7 @@
   "directories": {
     "example": "../../temps/example_temps"
   },
-  "dcloudext": {
-    "category": [
-      "前端组件",
-      "通用组件"
-    ],
+"dcloudext": {
     "sale": {
       "regular": {
         "price": "0.00"
@@ -38,7 +34,8 @@
       "data": "无",
       "permissions": "无"
     },
-    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
   },
   "uni_modules": {
     "dependencies": [
@@ -49,7 +46,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
@@ -87,4 +85,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json b/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json
index 35d1d3ad..3b735925 100644
--- a/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json
+++ b/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json
@@ -1,9 +1,13 @@
 {
-  "name": "uni-config-center",
-  "version": "0.0.3",
-  "description": "配置中心",
-  "main": "index.js",
-  "keywords": [],
-  "author": "DCloud",
-  "license": "Apache-2.0"
+    "name": "uni-config-center",
+    "version": "0.0.3",
+    "description": "配置中心",
+    "main": "index.js",
+    "keywords": [],
+    "author": "DCloud",
+    "license": "Apache-2.0",
+    "origin-plugin-dev-name": "uni-config-center",
+    "origin-plugin-version": "0.0.3",
+    "plugin-dev-name": "uni-config-center",
+    "plugin-version": "0.0.3"
 }
\ No newline at end of file
diff --git a/uni_modules/uni-countdown/changelog.md b/uni_modules/uni-countdown/changelog.md
index 16fc324b..13374184 100644
--- a/uni_modules/uni-countdown/changelog.md
+++ b/uni_modules/uni-countdown/changelog.md
@@ -1,3 +1,5 @@
+## 1.2.4（2024-09-21）
+- 新增 支持控制显示位数 默认显示2位
 ## 1.2.3（2024-02-20）
 - 新增 支持控制小时，分钟的显隐：showHour showMinute
 ## 1.2.2（2022-01-19）
diff --git a/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue b/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
index 820209b8..7c965465 100644
--- a/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
+++ b/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
@@ -96,6 +96,10 @@
 			timestamp: {
 				type: Number,
 				default: 0
+			},
+			filterShow : {
+				type:Object,
+				default:{}
 			}
 		},
 		data() {
@@ -208,23 +212,14 @@
 					second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
 				} else {
 					this.timeUp()
-				}
-				if (day < 10) {
-					day = '0' + day
-				}
-				if (hour < 10) {
-					hour = '0' + hour
-				}
-				if (minute < 10) {
-					minute = '0' + minute
-				}
-				if (second < 10) {
-					second = '0' + second
-				}
-				this.d = day
-				this.h = hour
-				this.i = minute
-				this.s = second
+				}
+				this.d  = String(day).padStart(this.validFilterShow(this.filterShow.d), '0')
+				this.h = String(hour).padStart(this.validFilterShow(this.filterShow.h), '0')
+				this.i = String(minute).padStart(this.validFilterShow(this.filterShow.m), '0')
+				this.s = String(second).padStart(this.validFilterShow(this.filterShow.s), '0')
+			},
+			validFilterShow(filter){
+				return (filter && filter > 0) ? filter : 2;
 			},
 			startData() {
 				this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
diff --git a/uni_modules/uni-countdown/package.json b/uni_modules/uni-countdown/package.json
index 66220744..9ec970b6 100644
--- a/uni_modules/uni-countdown/package.json
+++ b/uni_modules/uni-countdown/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-countdown",
   "displayName": "uni-countdown 倒计时",
-  "version": "1.2.3",
+  "version": "1.2.4",
   "description": "CountDown 倒计时组件",
   "keywords": [
     "uni-ui",
@@ -42,7 +42,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
@@ -80,4 +81,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/uni_modules/uni-data-checkbox/changelog.md b/uni_modules/uni-data-checkbox/changelog.md
index b475fcbb..7c99f6ce 100644
--- a/uni_modules/uni-data-checkbox/changelog.md
+++ b/uni_modules/uni-data-checkbox/changelog.md
@@ -1,3 +1,5 @@
+## 1.0.6（2024-10-22）
+- 新增 当 multiple 为 false 且传递的 value 为 数组时，使用数组第一项用作反显
 ## 1.0.5（2024-03-20）
 - 修复 单选模式下选中样式不生效的bug
 ## 1.0.4（2024-01-27）
diff --git a/uni_modules/uni-data-checkbox/components/uni-data-checkbox/clientdb.js b/uni_modules/uni-data-checkbox/components/uni-data-checkbox/clientdb.js
new file mode 100644
index 00000000..789572b5
--- /dev/null
+++ b/uni_modules/uni-data-checkbox/components/uni-data-checkbox/clientdb.js
@@ -0,0 +1,316 @@
+
+const events = {
+	load: 'load',
+	error: 'error'
+}
+const pageMode = {
+	add: 'add',
+	replace: 'replace'
+}
+
+const attrs = [
+	'pageCurrent',
+	'pageSize',
+	'collection',
+	'action',
+	'field',
+	'getcount',
+	'orderby',
+	'where'
+]
+
+export default {
+	data() {
+		return {
+			loading: false,
+			listData: this.getone ? {} : [],
+			paginationInternal: {
+				current: this.pageCurrent,
+				size: this.pageSize,
+				count: 0
+			},
+			errorMessage: ''
+		}
+	},
+	created() {
+		let db = null;
+		let dbCmd = null;
+
+		if(this.collection){
+			this.db = uniCloud.database();
+			this.dbCmd = this.db.command;
+		}
+
+		this._isEnded = false
+
+		this.$watch(() => {
+			let al = []
+			attrs.forEach(key => {
+				al.push(this[key])
+			})
+			return al
+		}, (newValue, oldValue) => {
+			this.paginationInternal.pageSize = this.pageSize
+
+			let needReset = false
+			for (let i = 2; i < newValue.length; i++) {
+				if (newValue[i] != oldValue[i]) {
+					needReset = true
+					break
+				}
+			}
+			if (needReset) {
+				this.clear()
+				this.reset()
+			}
+			if (newValue[0] != oldValue[0]) {
+				this.paginationInternal.current = this.pageCurrent
+			}
+
+			this._execLoadData()
+		})
+
+		// #ifdef H5
+		if (process.env.NODE_ENV === 'development') {
+			this._debugDataList = []
+			if (!window.unidev) {
+				window.unidev = {
+					clientDB: {
+						data: []
+					}
+				}
+			}
+			unidev.clientDB.data.push(this._debugDataList)
+		}
+		// #endif
+
+		// #ifdef MP-TOUTIAO
+		let changeName
+		let events = this.$scope.dataset.eventOpts
+		for (let i = 0; i < events.length; i++) {
+			let event = events[i]
+			if (event[0].includes('^load')) {
+				changeName = event[1][0][0]
+			}
+		}
+		if (changeName) {
+			let parent = this.$parent
+			let maxDepth = 16
+			this._changeDataFunction = null
+			while (parent && maxDepth > 0) {
+				let fun = parent[changeName]
+				if (fun && typeof fun === 'function') {
+					this._changeDataFunction = fun
+					maxDepth = 0
+					break
+				}
+				parent = parent.$parent
+				maxDepth--;
+			}
+		}
+		// #endif
+
+		// if (!this.manual) {
+		// 	this.loadData()
+		// }
+	},
+	// #ifdef H5
+	beforeDestroy() {
+		if (process.env.NODE_ENV === 'development' && window.unidev) {
+			let cd = this._debugDataList
+			let dl = unidev.clientDB.data
+			for (let i = dl.length - 1; i >= 0; i--) {
+				if (dl[i] === cd) {
+					dl.splice(i, 1)
+					break
+				}
+			}
+		}
+	},
+	// #endif
+	methods: {
+		loadData(args1, args2) {
+			let callback = null
+			if (typeof args1 === 'object') {
+				if (args1.clear) {
+					this.clear()
+					this.reset()
+				}
+				if (args1.current !== undefined) {
+					this.paginationInternal.current = args1.current
+				}
+				if (typeof args2 === 'function') {
+					callback = args2
+				}
+			} else if (typeof args1 === 'function') {
+				callback = args1
+			}
+
+			this._execLoadData(callback)
+		},
+		loadMore() {
+			if (this._isEnded) {
+				return
+			}
+			this._execLoadData()
+		},
+		refresh() {
+			this.clear()
+			this._execLoadData()
+		},
+		clear() {
+			this._isEnded = false
+			this.listData = []
+		},
+		reset() {
+			this.paginationInternal.current = 1
+		},
+		remove(id, {
+			action,
+			callback,
+			confirmTitle,
+			confirmContent
+		} = {}) {
+			if (!id || !id.length) {
+				return
+			}
+			uni.showModal({
+				title: confirmTitle || '提示',
+				content: confirmContent || '是否删除该数据',
+				showCancel: true,
+				success: (res) => {
+					if (!res.confirm) {
+						return
+					}
+					this._execRemove(id, action, callback)
+				}
+			})
+		},
+		_execLoadData(callback) {
+			if (this.loading) {
+				return
+			}
+			this.loading = true
+			this.errorMessage = ''
+
+			this._getExec().then((res) => {
+				this.loading = false
+				const {
+					data,
+					count
+				} = res.result
+				this._isEnded = data.length < this.pageSize
+
+				callback && callback(data, this._isEnded)
+				this._dispatchEvent(events.load, data)
+
+				if (this.getone) {
+					this.listData = data.length ? data[0] : undefined
+				} else if (this.pageData === pageMode.add) {
+					this.listData.push(...data)
+					if (this.listData.length) {
+						this.paginationInternal.current++
+					}
+				} else if (this.pageData === pageMode.replace) {
+					this.listData = data
+					this.paginationInternal.count = count
+				}
+
+				// #ifdef H5
+				if (process.env.NODE_ENV === 'development') {
+					this._debugDataList.length = 0
+					this._debugDataList.push(...JSON.parse(JSON.stringify(this.listData)))
+				}
+				// #endif
+			}).catch((err) => {
+				this.loading = false
+				this.errorMessage = err
+				callback && callback()
+				this.$emit(events.error, err)
+			})
+		},
+		_getExec() {
+			let exec = this.db
+			if (this.action) {
+				exec = exec.action(this.action)
+			}
+
+			exec = exec.collection(this.collection)
+
+			if (!(!this.where || !Object.keys(this.where).length)) {
+				exec = exec.where(this.where)
+			}
+			if (this.field) {
+				exec = exec.field(this.field)
+			}
+			if (this.orderby) {
+				exec = exec.orderBy(this.orderby)
+			}
+
+			const {
+				current,
+				size
+			} = this.paginationInternal
+			exec = exec.skip(size * (current - 1)).limit(size).get({
+				getCount: this.getcount
+			})
+
+			return exec
+		},
+		_execRemove(id, action, callback) {
+			if (!this.collection || !id) {
+				return
+			}
+
+			const ids = Array.isArray(id) ? id : [id]
+			if (!ids.length) {
+				return
+			}
+
+			uni.showLoading({
+				mask: true
+			})
+
+			let exec = this.db
+			if (action) {
+				exec = exec.action(action)
+			}
+
+			exec.collection(this.collection).where({
+				_id: dbCmd.in(ids)
+			}).remove().then((res) => {
+				callback && callback(res.result)
+				if (this.pageData === pageMode.replace) {
+					this.refresh()
+				} else {
+					this.removeData(ids)
+				}
+			}).catch((err) => {
+				uni.showModal({
+					content: err.message,
+					showCancel: false
+				})
+			}).finally(() => {
+				uni.hideLoading()
+			})
+		},
+		removeData(ids) {
+			let il = ids.slice(0)
+			let dl = this.listData
+			for (let i = dl.length - 1; i >= 0; i--) {
+				let index = il.indexOf(dl[i]._id)
+				if (index >= 0) {
+					dl.splice(i, 1)
+					il.splice(index, 1)
+				}
+			}
+		},
+		_dispatchEvent(type, data) {
+			if (this._changeDataFunction) {
+				this._changeDataFunction(data, this._isEnded)
+			} else {
+				this.$emit(type, data, this._isEnded)
+			}
+		}
+	}
+}
diff --git a/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue b/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
index 6e03c6e4..4da7bbeb 100644
--- a/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
+++ b/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
@@ -1,849 +1,853 @@
-<template>
-	<view class="uni-data-checklist" :style="{'margin-top':isTop+'px'}">
-		<template v-if="!isLocal">
-			<view class="uni-data-loading">
-				<uni-load-more v-if="!mixinDatacomErrorMessage" status="loading" iconType="snow" :iconSize="18"
-					:content-text="contentText"></uni-load-more>
-				<text v-else>{{mixinDatacomErrorMessage}}</text>
-			</view>
-		</template>
-		<template v-else>
-			<checkbox-group v-if="multiple" class="checklist-group" :class="{'is-list':mode==='list' || wrap}"
-				@change="change">
-				<label class="checklist-box"
-					:class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
-					:style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
-					<checkbox class="hidden" hidden :disabled="disabled || !!item.disabled" :value="item[map.value]+''"
-						:checked="item.selected" />
-					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')"
-						class="checkbox__inner" :style="item.styleIcon">
-						<view class="checkbox__inner-icon"></view>
-					</view>
-					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
-						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
-						<view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view>
-					</view>
-				</label>
-			</checkbox-group>
-			<radio-group v-else class="checklist-group" :class="{'is-list':mode==='list','is-wrap':wrap}" @change="change">
-				<label class="checklist-box"
-					:class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
-					:style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
-					<radio class="hidden" hidden :disabled="disabled || item.disabled" :value="item[map.value]+''"
-						:checked="item.selected" />
-					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="radio__inner"
-						:style="item.styleBackgroud">
-						<view class="radio__inner-icon" :style="item.styleIcon"></view>
-					</view>
-					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
-						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
-						<view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view>
-					</view>
-				</label>
-			</radio-group>
-		</template>
-	</view>
-</template>
-
-<script>
-	/**
-	 * DataChecklist 数据选择器
-	 * @description 通过数据渲染 checkbox 和 radio
-	 * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
-	 * @property {String} mode = [default| list | button | tag] 显示模式
-	 * @value default  	默认横排模式
-	 * @value list		列表模式
-	 * @value button	按钮模式
-	 * @value tag 		标签模式
-	 * @property {Boolean} multiple = [true|false] 是否多选
-	 * @property {Array|String|Number} value 默认值
-	 * @property {Array} localdata 本地数据 ，格式 [{text:'',value:''}]
-	 * @property {Number|String} min 最小选择个数 ，multiple为true时生效
-	 * @property {Number|String} max 最大选择个数 ，multiple为true时生效
-	 * @property {Boolean} wrap 是否换行显示
-	 * @property {String} icon = [left|right]  list 列表模式下icon显示位置
-	 * @property {Boolean} selectedColor 选中颜色
-	 * @property {Boolean} emptyText 没有数据时显示的文字 ，本地数据无效
-	 * @property {Boolean} selectedTextColor 选中文本颜色，如不填写则自动显示
-	 * @property {Object} map 字段映射， 默认 map={text:'text',value:'value'}
-	 * @value left 左侧显示
-	 * @value right 右侧显示
-	 * @event {Function} change  选中发生变化触发
-	 */
-
-	export default {
-		name: 'uniDataChecklist',
-		mixins: [uniCloud.mixinDatacom || {}],
-		emits: ['input', 'update:modelValue', 'change'],
-		props: {
-			mode: {
-				type: String,
-				default: 'default'
-			},
-
-			multiple: {
-				type: Boolean,
-				default: false
-			},
-			value: {
-				type: [Array, String, Number],
-				default () {
-					return ''
-				}
-			},
-			// TODO vue3
-			modelValue: {
-				type: [Array, String, Number],
-				default () {
-					return '';
-				}
-			},
-			localdata: {
-				type: Array,
-				default () {
-					return []
-				}
-			},
-			min: {
-				type: [Number, String],
-				default: ''
-			},
-			max: {
-				type: [Number, String],
-				default: ''
-			},
-			wrap: {
-				type: Boolean,
-				default: false
-			},
-			icon: {
-				type: String,
-				default: 'left'
-			},
-			selectedColor: {
-				type: String,
-				default: ''
-			},
-			selectedTextColor: {
-				type: String,
-				default: ''
-			},
-			emptyText: {
-				type: String,
-				default: '暂无数据'
-			},
-			disabled: {
-				type: Boolean,
-				default: false
-			},
-			map: {
-				type: Object,
-				default () {
-					return {
-						text: 'text',
-						value: 'value'
-					}
-				}
-			}
-		},
-		watch: {
-			localdata: {
-				handler(newVal) {
-					this.range = newVal
-					this.dataList = this.getDataList(this.getSelectedValue(newVal))
-				},
-				deep: true
-			},
-			mixinDatacomResData(newVal) {
-				this.range = newVal
-				this.dataList = this.getDataList(this.getSelectedValue(newVal))
-			},
-			value(newVal) {
-				this.dataList = this.getDataList(newVal)
-				// fix by mehaotian is_reset 在 uni-forms 中定义
-				// if(!this.is_reset){
-				// 	this.is_reset = false
-				// 	this.formItem && this.formItem.setValue(newVal)
-				// }
-			},
-			modelValue(newVal) {
-				this.dataList = this.getDataList(newVal);
-				// if(!this.is_reset){
-				// 	this.is_reset = false
-				// 	this.formItem && this.formItem.setValue(newVal)
-				// }
-			}
-		},
-		data() {
-			return {
-				dataList: [],
-				range: [],
-				contentText: {
-					contentdown: '查看更多',
-					contentrefresh: '加载中',
-					contentnomore: '没有更多'
-				},
-				isLocal: true,
-				styles: {
-					selectedColor: '#2979ff',
-					selectedTextColor: '#666',
-				},
-				isTop: 0
-			};
-		},
-		computed: {
-			dataValue() {
-				if (this.value === '') return this.modelValue
-				if (this.modelValue === '') return this.value
-				return this.value
-			}
-		},
-		created() {
-			// this.form = this.getForm('uniForms')
-			// this.formItem = this.getForm('uniFormsItem')
-			// this.formItem && this.formItem.setValue(this.value)
-
-			// if (this.formItem) {
-			// 	this.isTop = 6
-			// 	if (this.formItem.name) {
-			// 		// 如果存在name添加默认值,否则formData 中不存在这个字段不校验
-			// 		if(!this.is_reset){
-			// 			this.is_reset = false
-			// 			this.formItem.setValue(this.dataValue)
-			// 		}
-			// 		this.rename = this.formItem.name
-			// 		this.form.inputChildrens.push(this)
-			// 	}
-			// }
-
-			if (this.localdata && this.localdata.length !== 0) {
-				this.isLocal = true
-				this.range = this.localdata
-				this.dataList = this.getDataList(this.getSelectedValue(this.range))
-			} else {
-				if (this.collection) {
-					this.isLocal = false
-					this.loadData()
-				}
-			}
-		},
-		methods: {
-			loadData() {
-				this.mixinDatacomGet().then(res => {
-					this.mixinDatacomResData = res.result.data
-					if (this.mixinDatacomResData.length === 0) {
-						this.isLocal = false
-						this.mixinDatacomErrorMessage = this.emptyText
-					} else {
-						this.isLocal = true
-					}
-				}).catch(err => {
-					this.mixinDatacomErrorMessage = err.message
-				})
-			},
-			/**
-			 * 获取父元素实例
-			 */
-			getForm(name = 'uniForms') {
-				let parent = this.$parent;
-				let parentName = parent.$options.name;
-				while (parentName !== name) {
-					parent = parent.$parent;
-					if (!parent) return false
-					parentName = parent.$options.name;
-				}
-				return parent;
-			},
-			change(e) {
-				const values = e.detail.value
-
-				let detail = {
-					value: [],
-					data: []
-				}
-
-				if (this.multiple) {
-					this.range.forEach(item => {
-
-						if (values.includes(item[this.map.value] + '')) {
-							detail.value.push(item[this.map.value])
-							detail.data.push(item)
-						}
-					})
-				} else {
-					const range = this.range.find(item => (item[this.map.value] + '') === values)
-					if (range) {
-						detail = {
-							value: range[this.map.value],
-							data: range
-						}
-					}
-				}
-				// this.formItem && this.formItem.setValue(detail.value)
-				// TODO 兼容 vue2
-				this.$emit('input', detail.value);
-				// // TOTO 兼容 vue3
-				this.$emit('update:modelValue', detail.value);
-				this.$emit('change', {
-					detail
-				})
-				if (this.multiple) {
-					// 如果 v-model 没有绑定 ，则走内部逻辑
-					// if (this.value.length === 0) {
-					this.dataList = this.getDataList(detail.value, true)
-					// }
-				} else {
-					this.dataList = this.getDataList(detail.value)
-				}
-			},
-
-			/**
-			 * 获取渲染的新数组
-			 * @param {Object} value 选中内容
-			 */
-			getDataList(value) {
-				// 解除引用关系，破坏原引用关系，避免污染源数据
-				let dataList = JSON.parse(JSON.stringify(this.range))
-				let list = []
-				if (this.multiple) {
-					if (!Array.isArray(value)) {
-						value = []
-					}
-				}
-				dataList.forEach((item, index) => {
-					item.disabled = item.disable || item.disabled || false
-					if (this.multiple) {
-						if (value.length > 0) {
-							let have = value.find(val => val === item[this.map.value])
-							item.selected = have !== undefined
-						} else {
-							item.selected = false
-						}
-					} else {
-						item.selected = value === item[this.map.value]
-					}
-
-					list.push(item)
-				})
-				return this.setRange(list)
-			},
-			/**
-			 * 处理最大最小值
-			 * @param {Object} list
-			 */
-			setRange(list) {
-				let selectList = list.filter(item => item.selected)
-				let min = Number(this.min) || 0
-				let max = Number(this.max) || ''
-				list.forEach((item, index) => {
-					if (this.multiple) {
-						if (selectList.length <= min) {
-							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
-							if (have !== undefined) {
-								item.disabled = true
-							}
-						}
-
-						if (selectList.length >= max && max !== '') {
-							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
-							if (have === undefined) {
-								item.disabled = true
-							}
-						}
-					}
-					this.setStyles(item, index)
-					list[index] = item
-				})
-				return list
-			},
-			/**
-			 * 设置 class
-			 * @param {Object} item
-			 * @param {Object} index
-			 */
-			setStyles(item, index) {
-				//  设置自定义样式
-				item.styleBackgroud = this.setStyleBackgroud(item)
-				item.styleIcon = this.setStyleIcon(item)
-				item.styleIconText = this.setStyleIconText(item)
-				item.styleRightIcon = this.setStyleRightIcon(item)
-			},
-
-			/**
-			 * 获取选中值
-			 * @param {Object} range
-			 */
-			getSelectedValue(range) {
-				if (!this.multiple) return this.dataValue
-				let selectedArr = []
-				range.forEach((item) => {
-					if (item.selected) {
-						selectedArr.push(item[this.map.value])
-					}
-				})
-				return this.dataValue.length > 0 ? this.dataValue : selectedArr
-			},
-
-			/**
-			 * 设置背景样式
-			 */
-			setStyleBackgroud(item) {
-				let styles = {}
-				let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
-				if (this.selectedColor) {
-					if (this.mode !== 'list') {
-						styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
-					}
-					if (this.mode === 'tag') {
-						styles['background-color'] = item.selected ? selectedColor : '#f5f5f5'
-					}
-				}
-				let classles = ''
-				for (let i in styles) {
-					classles += `${i}:${styles[i]};`
-				}
-				return classles
-			},
-			setStyleIcon(item) {
-				let styles = {}
-				let classles = ''
-				if (this.selectedColor) {
-					let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
-					styles['background-color'] = item.selected ? selectedColor : '#fff'
-					styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
-
-					if (!item.selected && item.disabled) {
-						styles['background-color'] = '#F2F6FC'
-						styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
-					}
-				}
-				for (let i in styles) {
-					classles += `${i}:${styles[i]};`
-				}
-				return classles
-			},
-			setStyleIconText(item) {
-				let styles = {}
-				let classles = ''
-				if (this.selectedColor) {
-					let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
-					if (this.mode === 'tag') {
-						styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : '#fff') : '#666'
-					} else {
-						styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : selectedColor) : '#666'
-					}
-					if (!item.selected && item.disabled) {
-						styles.color = '#999'
-					}
-				}
-				for (let i in styles) {
-					classles += `${i}:${styles[i]};`
-				}
-				return classles
-			},
-			setStyleRightIcon(item) {
-				let styles = {}
-				let classles = ''
-				if (this.mode === 'list') {
-					styles['border-color'] = item.selected ? this.styles.selectedColor : '#DCDFE6'
-				}
-				for (let i in styles) {
-					classles += `${i}:${styles[i]};`
-				}
-
-				return classles
-			}
-		}
-	}
-</script>
-
-<style lang="scss">
-	$uni-primary: #2979ff !default;
-	$border-color: #DCDFE6;
-	$disable: 0.4;
-
-	@mixin flex {
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-	}
-
-	.uni-data-loading {
-		@include flex;
-		flex-direction: row;
-		justify-content: center;
-		align-items: center;
-		height: 36px;
-		padding-left: 10px;
-		color: #999;
-	}
-
-	.uni-data-checklist {
-		position: relative;
-		z-index: 0;
-		flex: 1;
-
-		// 多选样式
-		.checklist-group {
-			@include flex;
-			flex-direction: row;
-			flex-wrap: wrap;
-
-			&.is-list {
-				flex-direction: column;
-			}
-
-			.checklist-box {
-				@include flex;
-				flex-direction: row;
-				align-items: center;
-				position: relative;
-				margin: 5px 0;
-				margin-right: 25px;
-
-				.hidden {
-					position: absolute;
-					opacity: 0;
-				}
-
-				// 文字样式
-				.checklist-content {
-					@include flex;
-					flex: 1;
-					flex-direction: row;
-					align-items: center;
-					justify-content: space-between;
-
-					.checklist-text {
-						font-size: 14px;
-						color: #666;
-						margin-left: 5px;
-						line-height: 14px;
-					}
-
-					.checkobx__list {
-						border-right-width: 1px;
-						border-right-color: #007aff;
-						border-right-style: solid;
-						border-bottom-width: 1px;
-						border-bottom-color: #007aff;
-						border-bottom-style: solid;
-						height: 12px;
-						width: 6px;
-						left: -5px;
-						transform-origin: center;
-						transform: rotate(45deg);
-						opacity: 0;
-					}
-				}
-
-				// 多选样式
-				.checkbox__inner {
-					/* #ifndef APP-NVUE */
-					flex-shrink: 0;
-					box-sizing: border-box;
-					/* #endif */
-					position: relative;
-					width: 16px;
-					height: 16px;
-					border: 1px solid $border-color;
-					border-radius: 4px;
-					background-color: #fff;
-					z-index: 1;
-
-					.checkbox__inner-icon {
-						position: absolute;
-						/* #ifdef APP-NVUE */
-						top: 2px;
-						/* #endif */
-						/* #ifndef APP-NVUE */
-						top: 1px;
-						/* #endif */
-						left: 5px;
-						height: 8px;
-						width: 4px;
-						border-right-width: 1px;
-						border-right-color: #fff;
-						border-right-style: solid;
-						border-bottom-width: 1px;
-						border-bottom-color: #fff;
-						border-bottom-style: solid;
-						opacity: 0;
-						transform-origin: center;
-						transform: rotate(40deg);
-					}
-				}
-
-				// 单选样式
-				.radio__inner {
-					@include flex;
-					/* #ifndef APP-NVUE */
-					flex-shrink: 0;
-					box-sizing: border-box;
-					/* #endif */
-					justify-content: center;
-					align-items: center;
-					position: relative;
-					width: 16px;
-					height: 16px;
-					border: 1px solid $border-color;
-					border-radius: 16px;
-					background-color: #fff;
-					z-index: 1;
-
-					.radio__inner-icon {
-						width: 8px;
-						height: 8px;
-						border-radius: 10px;
-						opacity: 0;
-					}
-				}
-
-				// 默认样式
-				&.is--default {
-
-					// 禁用
-					&.is-disable {
-						/* #ifdef H5 */
-						cursor: not-allowed;
-
-						/* #endif */
-						.checkbox__inner {
-							background-color: #F2F6FC;
-							border-color: $border-color;
-							/* #ifdef H5 */
-							cursor: not-allowed;
-							/* #endif */
-						}
-
-						.radio__inner {
-							background-color: #F2F6FC;
-							border-color: $border-color;
-						}
-
-						.checklist-text {
-							color: #999;
-						}
-					}
-
-					// 选中
-					&.is-checked {
-						.checkbox__inner {
-							border-color: $uni-primary;
-							background-color: $uni-primary;
-
-							.checkbox__inner-icon {
-								opacity: 1;
-								transform: rotate(45deg);
-							}
-						}
-
-						.radio__inner {
-							border-color: $uni-primary;
-
-							.radio__inner-icon {
-								opacity: 1;
-								background-color: $uni-primary;
-							}
-						}
-
-						.checklist-text {
-							color: $uni-primary;
-						}
-
-						// 选中禁用
-						&.is-disable {
-							.checkbox__inner {
-								opacity: $disable;
-							}
-
-							.checklist-text {
-								opacity: $disable;
-							}
-
-							.radio__inner {
-								opacity: $disable;
-							}
-						}
-					}
-				}
-
-				// 按钮样式
-				&.is--button {
-					margin-right: 10px;
-					padding: 5px 10px;
-					border: 1px $border-color solid;
-					border-radius: 3px;
-					transition: border-color 0.2s;
-
-					// 禁用
-					&.is-disable {
-						/* #ifdef H5 */
-						cursor: not-allowed;
-						/* #endif */
-						border: 1px #eee solid;
-						opacity: $disable;
-
-						.checkbox__inner {
-							background-color: #F2F6FC;
-							border-color: $border-color;
-							/* #ifdef H5 */
-							cursor: not-allowed;
-							/* #endif */
-						}
-
-						.radio__inner {
-							background-color: #F2F6FC;
-							border-color: $border-color;
-							/* #ifdef H5 */
-							cursor: not-allowed;
-							/* #endif */
-						}
-
-						.checklist-text {
-							color: #999;
-						}
-					}
-
-					&.is-checked {
-						border-color: $uni-primary;
-
-						.checkbox__inner {
-							border-color: $uni-primary;
-							background-color: $uni-primary;
-
-							.checkbox__inner-icon {
-								opacity: 1;
-								transform: rotate(45deg);
-							}
-						}
-
-						.radio__inner {
-							border-color: $uni-primary;
-
-							.radio__inner-icon {
-								opacity: 1;
-								background-color: $uni-primary;
-							}
-						}
-
-						.checklist-text {
-							color: $uni-primary;
-						}
-
-						// 选中禁用
-						&.is-disable {
-							opacity: $disable;
-						}
-					}
-				}
-
-				// 标签样式
-				&.is--tag {
-					margin-right: 10px;
-					padding: 5px 10px;
-					border: 1px $border-color solid;
-					border-radius: 3px;
-					background-color: #f5f5f5;
-
-					.checklist-text {
-						margin: 0;
-						color: #666;
-					}
-
-					// 禁用
-					&.is-disable {
-						/* #ifdef H5 */
-						cursor: not-allowed;
-						/* #endif */
-						opacity: $disable;
-					}
-
-					&.is-checked {
-						background-color: $uni-primary;
-						border-color: $uni-primary;
-
-						.checklist-text {
-							color: #fff;
-						}
-					}
-				}
-
-				// 列表样式
-				&.is--list {
-					/* #ifndef APP-NVUE */
-					display: flex;
-					/* #endif */
-					padding: 10px 15px;
-					padding-left: 0;
-					margin: 0;
-
-					&.is-list-border {
-						border-top: 1px #eee solid;
-					}
-
-					// 禁用
-					&.is-disable {
-						/* #ifdef H5 */
-						cursor: not-allowed;
-
-						/* #endif */
-						.checkbox__inner {
-							background-color: #F2F6FC;
-							border-color: $border-color;
-							/* #ifdef H5 */
-							cursor: not-allowed;
-							/* #endif */
-						}
-
-						.checklist-text {
-							color: #999;
-						}
-					}
-
-					&.is-checked {
-						.checkbox__inner {
-							border-color: $uni-primary;
-							background-color: $uni-primary;
-
-							.checkbox__inner-icon {
-								opacity: 1;
-								transform: rotate(45deg);
-							}
-						}
-
+<template>
+	<view class="uni-data-checklist" :style="{'margin-top':isTop+'px'}">
+		<template v-if="!isLocal">
+			<view class="uni-data-loading">
+				<uni-load-more v-if="!mixinDatacomErrorMessage" status="loading" iconType="snow" :iconSize="18"
+					:content-text="contentText"></uni-load-more>
+				<text v-else>{{mixinDatacomErrorMessage}}</text>
+			</view>
+		</template>
+		<template v-else>
+			<checkbox-group v-if="multiple" class="checklist-group" :class="{'is-list':mode==='list' || wrap}"
+				@change="change">
+				<label class="checklist-box"
+					:class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
+					:style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
+					<checkbox class="hidden" hidden :disabled="disabled || !!item.disabled" :value="item[map.value]+''"
+						:checked="item.selected" />
+					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')"
+						class="checkbox__inner" :style="item.styleIcon">
+						<view class="checkbox__inner-icon"></view>
+					</view>
+					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
+						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
+						<view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view>
+					</view>
+				</label>
+			</checkbox-group>
+			<radio-group v-else class="checklist-group" :class="{'is-list':mode==='list','is-wrap':wrap}" @change="change">
+				<label class="checklist-box"
+					:class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
+					:style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
+					<radio class="hidden" hidden :disabled="disabled || item.disabled" :value="item[map.value]+''"
+						:checked="item.selected" />
+					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="radio__inner"
+						:style="item.styleBackgroud">
+						<view class="radio__inner-icon" :style="item.styleIcon"></view>
+					</view>
+					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
+						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
+						<view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view>
+					</view>
+				</label>
+			</radio-group>
+		</template>
+	</view>
+</template>
+
+<script>
+	/**
+	 * DataChecklist 数据选择器
+	 * @description 通过数据渲染 checkbox 和 radio
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
+	 * @property {String} mode = [default| list | button | tag] 显示模式
+	 * @value default  	默认横排模式
+	 * @value list		列表模式
+	 * @value button	按钮模式
+	 * @value tag 		标签模式
+	 * @property {Boolean} multiple = [true|false] 是否多选
+	 * @property {Array|String|Number} value 默认值
+	 * @property {Array} localdata 本地数据 ，格式 [{text:'',value:''}]
+	 * @property {Number|String} min 最小选择个数 ，multiple为true时生效
+	 * @property {Number|String} max 最大选择个数 ，multiple为true时生效
+	 * @property {Boolean} wrap 是否换行显示
+	 * @property {String} icon = [left|right]  list 列表模式下icon显示位置
+	 * @property {Boolean} selectedColor 选中颜色
+	 * @property {Boolean} emptyText 没有数据时显示的文字 ，本地数据无效
+	 * @property {Boolean} selectedTextColor 选中文本颜色，如不填写则自动显示
+	 * @property {Object} map 字段映射， 默认 map={text:'text',value:'value'}
+	 * @value left 左侧显示
+	 * @value right 右侧显示
+	 * @event {Function} change  选中发生变化触发
+	 */
+
+	export default {
+		name: 'uniDataChecklist',
+		mixins: [uniCloud.mixinDatacom || {}],
+		emits: ['input', 'update:modelValue', 'change'],
+		props: {
+			mode: {
+				type: String,
+				default: 'default'
+			},
+
+			multiple: {
+				type: Boolean,
+				default: false
+			},
+			value: {
+				type: [Array, String, Number],
+				default () {
+					return ''
+				}
+			},
+			// TODO vue3
+			modelValue: {
+				type: [Array, String, Number],
+				default () {
+					return '';
+				}
+			},
+			localdata: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			min: {
+				type: [Number, String],
+				default: ''
+			},
+			max: {
+				type: [Number, String],
+				default: ''
+			},
+			wrap: {
+				type: Boolean,
+				default: false
+			},
+			icon: {
+				type: String,
+				default: 'left'
+			},
+			selectedColor: {
+				type: String,
+				default: ''
+			},
+			selectedTextColor: {
+				type: String,
+				default: ''
+			},
+			emptyText: {
+				type: String,
+				default: '暂无数据'
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			map: {
+				type: Object,
+				default () {
+					return {
+						text: 'text',
+						value: 'value'
+					}
+				}
+			}
+		},
+		watch: {
+			localdata: {
+				handler(newVal) {
+					this.range = newVal
+					this.dataList = this.getDataList(this.getSelectedValue(newVal))
+				},
+				deep: true
+			},
+			mixinDatacomResData(newVal) {
+				this.range = newVal
+				this.dataList = this.getDataList(this.getSelectedValue(newVal))
+			},
+			value(newVal) {
+				this.dataList = this.getDataList(newVal)
+				// fix by mehaotian is_reset 在 uni-forms 中定义
+				// if(!this.is_reset){
+				// 	this.is_reset = false
+				// 	this.formItem && this.formItem.setValue(newVal)
+				// }
+			},
+			modelValue(newVal) {
+				this.dataList = this.getDataList(newVal);
+				// if(!this.is_reset){
+				// 	this.is_reset = false
+				// 	this.formItem && this.formItem.setValue(newVal)
+				// }
+			}
+		},
+		data() {
+			return {
+				dataList: [],
+				range: [],
+				contentText: {
+					contentdown: '查看更多',
+					contentrefresh: '加载中',
+					contentnomore: '没有更多'
+				},
+				isLocal: true,
+				styles: {
+					selectedColor: '#2979ff',
+					selectedTextColor: '#666',
+				},
+				isTop: 0
+			};
+		},
+		computed: {
+			dataValue() {
+				if (this.value === '') return this.modelValue
+				if (this.modelValue === '') return this.value
+				return this.value
+			}
+		},
+		created() {
+			// this.form = this.getForm('uniForms')
+			// this.formItem = this.getForm('uniFormsItem')
+			// this.formItem && this.formItem.setValue(this.value)
+
+			// if (this.formItem) {
+			// 	this.isTop = 6
+			// 	if (this.formItem.name) {
+			// 		// 如果存在name添加默认值,否则formData 中不存在这个字段不校验
+			// 		if(!this.is_reset){
+			// 			this.is_reset = false
+			// 			this.formItem.setValue(this.dataValue)
+			// 		}
+			// 		this.rename = this.formItem.name
+			// 		this.form.inputChildrens.push(this)
+			// 	}
+			// }
+
+			if (this.localdata && this.localdata.length !== 0) {
+				this.isLocal = true
+				this.range = this.localdata
+				this.dataList = this.getDataList(this.getSelectedValue(this.range))
+			} else {
+				if (this.collection) {
+					this.isLocal = false
+					this.loadData()
+				}
+			}
+		},
+		methods: {
+			loadData() {
+				this.mixinDatacomGet().then(res => {
+					this.mixinDatacomResData = res.result.data
+					if (this.mixinDatacomResData.length === 0) {
+						this.isLocal = false
+						this.mixinDatacomErrorMessage = this.emptyText
+					} else {
+						this.isLocal = true
+					}
+				}).catch(err => {
+					this.mixinDatacomErrorMessage = err.message
+				})
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getForm(name = 'uniForms') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+			change(e) {
+				const values = e.detail.value
+
+				let detail = {
+					value: [],
+					data: []
+				}
+
+				if (this.multiple) {
+					this.range.forEach(item => {
+
+						if (values.includes(item[this.map.value] + '')) {
+							detail.value.push(item[this.map.value])
+							detail.data.push(item)
+						}
+					})
+				} else {
+					const range = this.range.find(item => (item[this.map.value] + '') === values)
+					if (range) {
+						detail = {
+							value: range[this.map.value],
+							data: range
+						}
+					}
+				}
+				// this.formItem && this.formItem.setValue(detail.value)
+				// TODO 兼容 vue2
+				this.$emit('input', detail.value);
+				// // TOTO 兼容 vue3
+				this.$emit('update:modelValue', detail.value);
+				this.$emit('change', {
+					detail
+				})
+				if (this.multiple) {
+					// 如果 v-model 没有绑定 ，则走内部逻辑
+					// if (this.value.length === 0) {
+					this.dataList = this.getDataList(detail.value, true)
+					// }
+				} else {
+					this.dataList = this.getDataList(detail.value)
+				}
+			},
+
+			/**
+			 * 获取渲染的新数组
+			 * @param {Object} value 选中内容
+			 */
+			getDataList(value) {
+				// 解除引用关系，破坏原引用关系，避免污染源数据
+				let dataList = JSON.parse(JSON.stringify(this.range))
+				let list = []
+				if (this.multiple) {
+					if (!Array.isArray(value)) {
+						value = []
+					}
+				} else {
+					if (Array.isArray(value) && value.length) {
+						value = value[0]
+					}
+				}
+				dataList.forEach((item, index) => {
+					item.disabled = item.disable || item.disabled || false
+					if (this.multiple) {
+						if (value.length > 0) {
+							let have = value.find(val => val === item[this.map.value])
+							item.selected = have !== undefined
+						} else {
+							item.selected = false
+						}
+					} else {
+						item.selected = value === item[this.map.value]
+					}
+
+					list.push(item)
+				})
+				return this.setRange(list)
+			},
+			/**
+			 * 处理最大最小值
+			 * @param {Object} list
+			 */
+			setRange(list) {
+				let selectList = list.filter(item => item.selected)
+				let min = Number(this.min) || 0
+				let max = Number(this.max) || ''
+				list.forEach((item, index) => {
+					if (this.multiple) {
+						if (selectList.length <= min) {
+							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
+							if (have !== undefined) {
+								item.disabled = true
+							}
+						}
+
+						if (selectList.length >= max && max !== '') {
+							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
+							if (have === undefined) {
+								item.disabled = true
+							}
+						}
+					}
+					this.setStyles(item, index)
+					list[index] = item
+				})
+				return list
+			},
+			/**
+			 * 设置 class
+			 * @param {Object} item
+			 * @param {Object} index
+			 */
+			setStyles(item, index) {
+				//  设置自定义样式
+				item.styleBackgroud = this.setStyleBackgroud(item)
+				item.styleIcon = this.setStyleIcon(item)
+				item.styleIconText = this.setStyleIconText(item)
+				item.styleRightIcon = this.setStyleRightIcon(item)
+			},
+
+			/**
+			 * 获取选中值
+			 * @param {Object} range
+			 */
+			getSelectedValue(range) {
+				if (!this.multiple) return this.dataValue
+				let selectedArr = []
+				range.forEach((item) => {
+					if (item.selected) {
+						selectedArr.push(item[this.map.value])
+					}
+				})
+				return this.dataValue.length > 0 ? this.dataValue : selectedArr
+			},
+
+			/**
+			 * 设置背景样式
+			 */
+			setStyleBackgroud(item) {
+				let styles = {}
+				let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
+				if (this.selectedColor) {
+					if (this.mode !== 'list') {
+						styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
+					}
+					if (this.mode === 'tag') {
+						styles['background-color'] = item.selected ? selectedColor : '#f5f5f5'
+					}
+				}
+				let classles = ''
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+				return classles
+			},
+			setStyleIcon(item) {
+				let styles = {}
+				let classles = ''
+				if (this.selectedColor) {
+					let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
+					styles['background-color'] = item.selected ? selectedColor : '#fff'
+					styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
+
+					if (!item.selected && item.disabled) {
+						styles['background-color'] = '#F2F6FC'
+						styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
+					}
+				}
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+				return classles
+			},
+			setStyleIconText(item) {
+				let styles = {}
+				let classles = ''
+				if (this.selectedColor) {
+					let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
+					if (this.mode === 'tag') {
+						styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : '#fff') : '#666'
+					} else {
+						styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : selectedColor) : '#666'
+					}
+					if (!item.selected && item.disabled) {
+						styles.color = '#999'
+					}
+				}
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+				return classles
+			},
+			setStyleRightIcon(item) {
+				let styles = {}
+				let classles = ''
+				if (this.mode === 'list') {
+					styles['border-color'] = item.selected ? this.styles.selectedColor : '#DCDFE6'
+				}
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+
+				return classles
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-primary: #2979ff !default;
+	$border-color: #DCDFE6;
+	$disable: 0.4;
+
+	@mixin flex {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+	}
+
+	.uni-data-loading {
+		@include flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 36px;
+		padding-left: 10px;
+		color: #999;
+	}
+
+	.uni-data-checklist {
+		position: relative;
+		z-index: 0;
+		flex: 1;
+
+		// 多选样式
+		.checklist-group {
+			@include flex;
+			flex-direction: row;
+			flex-wrap: wrap;
+
+			&.is-list {
+				flex-direction: column;
+			}
+
+			.checklist-box {
+				@include flex;
+				flex-direction: row;
+				align-items: center;
+				position: relative;
+				margin: 5px 0;
+				margin-right: 25px;
+
+				.hidden {
+					position: absolute;
+					opacity: 0;
+				}
+
+				// 文字样式
+				.checklist-content {
+					@include flex;
+					flex: 1;
+					flex-direction: row;
+					align-items: center;
+					justify-content: space-between;
+
+					.checklist-text {
+						font-size: 14px;
+						color: #666;
+						margin-left: 5px;
+						line-height: 14px;
+					}
+
+					.checkobx__list {
+						border-right-width: 1px;
+						border-right-color: #007aff;
+						border-right-style: solid;
+						border-bottom-width: 1px;
+						border-bottom-color: #007aff;
+						border-bottom-style: solid;
+						height: 12px;
+						width: 6px;
+						left: -5px;
+						transform-origin: center;
+						transform: rotate(45deg);
+						opacity: 0;
+					}
+				}
+
+				// 多选样式
+				.checkbox__inner {
+					/* #ifndef APP-NVUE */
+					flex-shrink: 0;
+					box-sizing: border-box;
+					/* #endif */
+					position: relative;
+					width: 16px;
+					height: 16px;
+					border: 1px solid $border-color;
+					border-radius: 4px;
+					background-color: #fff;
+					z-index: 1;
+
+					.checkbox__inner-icon {
+						position: absolute;
+						/* #ifdef APP-NVUE */
+						top: 2px;
+						/* #endif */
+						/* #ifndef APP-NVUE */
+						top: 1px;
+						/* #endif */
+						left: 5px;
+						height: 8px;
+						width: 4px;
+						border-right-width: 1px;
+						border-right-color: #fff;
+						border-right-style: solid;
+						border-bottom-width: 1px;
+						border-bottom-color: #fff;
+						border-bottom-style: solid;
+						opacity: 0;
+						transform-origin: center;
+						transform: rotate(40deg);
+					}
+				}
+
+				// 单选样式
+				.radio__inner {
+					@include flex;
+					/* #ifndef APP-NVUE */
+					flex-shrink: 0;
+					box-sizing: border-box;
+					/* #endif */
+					justify-content: center;
+					align-items: center;
+					position: relative;
+					width: 16px;
+					height: 16px;
+					border: 1px solid $border-color;
+					border-radius: 16px;
+					background-color: #fff;
+					z-index: 1;
+
+					.radio__inner-icon {
+						width: 8px;
+						height: 8px;
+						border-radius: 10px;
+						opacity: 0;
+					}
+				}
+
+				// 默认样式
+				&.is--default {
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+
+						/* #endif */
+						.checkbox__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+
 						.radio__inner {
-							border-color: $uni-primary;
-							.radio__inner-icon {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+						}
+
+						.checklist-text {
+							color: #999;
+						}
+					}
+
+					// 选中
+					&.is-checked {
+						.checkbox__inner {
+							border-color: $uni-primary;
+							background-color: $uni-primary;
+
+							.checkbox__inner-icon {
 								opacity: 1;
-								background-color: $uni-primary;
-							}
-						}
-
-						.checklist-text {
-							color: $uni-primary;
-						}
-
-						.checklist-content {
-							.checkobx__list {
-								opacity: 1;
-								border-color: $uni-primary;
-							}
-						}
-
-						// 选中禁用
-						&.is-disable {
-							.checkbox__inner {
-								opacity: $disable;
-							}
-
-							.checklist-text {
-								opacity: $disable;
-							}
-						}
-					}
-				}
-			}
-		}
-	}
+								transform: rotate(45deg);
+							}
+						}
+
+						.radio__inner {
+							border-color: $uni-primary;
+
+							.radio__inner-icon {
+								opacity: 1;
+								background-color: $uni-primary;
+							}
+						}
+
+						.checklist-text {
+							color: $uni-primary;
+						}
+
+						// 选中禁用
+						&.is-disable {
+							.checkbox__inner {
+								opacity: $disable;
+							}
+
+							.checklist-text {
+								opacity: $disable;
+							}
+
+							.radio__inner {
+								opacity: $disable;
+							}
+						}
+					}
+				}
+
+				// 按钮样式
+				&.is--button {
+					margin-right: 10px;
+					padding: 5px 10px;
+					border: 1px $border-color solid;
+					border-radius: 3px;
+					transition: border-color 0.2s;
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+						/* #endif */
+						border: 1px #eee solid;
+						opacity: $disable;
+
+						.checkbox__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+
+						.radio__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+
+						.checklist-text {
+							color: #999;
+						}
+					}
+
+					&.is-checked {
+						border-color: $uni-primary;
+
+						.checkbox__inner {
+							border-color: $uni-primary;
+							background-color: $uni-primary;
+
+							.checkbox__inner-icon {
+								opacity: 1;
+								transform: rotate(45deg);
+							}
+						}
+
+						.radio__inner {
+							border-color: $uni-primary;
+
+							.radio__inner-icon {
+								opacity: 1;
+								background-color: $uni-primary;
+							}
+						}
+
+						.checklist-text {
+							color: $uni-primary;
+						}
+
+						// 选中禁用
+						&.is-disable {
+							opacity: $disable;
+						}
+					}
+				}
+
+				// 标签样式
+				&.is--tag {
+					margin-right: 10px;
+					padding: 5px 10px;
+					border: 1px $border-color solid;
+					border-radius: 3px;
+					background-color: #f5f5f5;
+
+					.checklist-text {
+						margin: 0;
+						color: #666;
+					}
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+						/* #endif */
+						opacity: $disable;
+					}
+
+					&.is-checked {
+						background-color: $uni-primary;
+						border-color: $uni-primary;
+
+						.checklist-text {
+							color: #fff;
+						}
+					}
+				}
+
+				// 列表样式
+				&.is--list {
+					/* #ifndef APP-NVUE */
+					display: flex;
+					/* #endif */
+					padding: 10px 15px;
+					padding-left: 0;
+					margin: 0;
+
+					&.is-list-border {
+						border-top: 1px #eee solid;
+					}
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+
+						/* #endif */
+						.checkbox__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+
+						.checklist-text {
+							color: #999;
+						}
+					}
+
+					&.is-checked {
+						.checkbox__inner {
+							border-color: $uni-primary;
+							background-color: $uni-primary;
+
+							.checkbox__inner-icon {
+								opacity: 1;
+								transform: rotate(45deg);
+							}
+						}
+
+						.radio__inner {
+							border-color: $uni-primary;
+							.radio__inner-icon {
+								opacity: 1;
+								background-color: $uni-primary;
+							}
+						}
+
+						.checklist-text {
+							color: $uni-primary;
+						}
+
+						.checklist-content {
+							.checkobx__list {
+								opacity: 1;
+								border-color: $uni-primary;
+							}
+						}
+
+						// 选中禁用
+						&.is-disable {
+							.checkbox__inner {
+								opacity: $disable;
+							}
+
+							.checklist-text {
+								opacity: $disable;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
 </style>
diff --git a/uni_modules/uni-data-checkbox/package.json b/uni_modules/uni-data-checkbox/package.json
index fc15e8b2..f823e8b0 100644
--- a/uni_modules/uni-data-checkbox/package.json
+++ b/uni_modules/uni-data-checkbox/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-data-checkbox",
   "displayName": "uni-data-checkbox 数据选择器",
-  "version": "1.0.5",
+  "version": "1.0.6",
   "description": "通过数据驱动的单选框和复选框",
   "keywords": [
     "uni-ui",
@@ -43,12 +43,15 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
-          "app-vue": "y",
-          "app-nvue": "y"
+            "app-vue": "y",
+            "app-nvue": "y",
+            "app-harmony": "u",
+            "app-uvue": "u"
         },
         "H5-mobile": {
           "Safari": "y",
diff --git a/uni_modules/uni-data-picker/changelog.md b/uni_modules/uni-data-picker/changelog.md
index d7893b03..e095788a 100644
--- a/uni_modules/uni-data-picker/changelog.md
+++ b/uni_modules/uni-data-picker/changelog.md
@@ -1,77 +1,79 @@
-## 2.0.0（2023-12-14）
+## 2.0.1（2024-08-22）
+- 修复 uni-app-x v-model 没有更新传入值的 bug
+## 2.0.0（2023-12-11）
 - 新增 支持 uni-app-x
-## 1.1.2（2023-04-11）
-- 修复 更改 modelValue 报错的 bug
-- 修复 v-for 未使用 key 值控制台 warning
-## 1.1.1（2023-02-21）
-- 修复代码合并时引发 value 属性为空时不渲染数据的问题
-## 1.1.0（2023-02-15）
-- 修复 localdata 不支持动态更新的bug
-## 1.0.9（2023-02-15）
-- 修复 localdata 不支持动态更新的bug
-## 1.0.8（2022-09-16）
-- 可以使用 uni-scss 控制主题色
-## 1.0.7（2022-07-06）
-- 优化 pc端图标位置不正确的问题
-## 1.0.6（2022-07-05）
-- 优化 显示样式
-## 1.0.5（2022-07-04）
-- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
-## 1.0.4（2022-04-19）
-- 修复 字节小程序 本地数据无法选择下一级的Bug
-## 1.0.3（2022-02-25）
-- 修复 nvue 不支持的 v-show 的 bug
-## 1.0.2（2022-02-25）
-- 修复 条件编译 nvue 不支持的 css 样式
-## 1.0.1（2021-11-23）
-- 修复 由上个版本引发的map、v-model等属性不生效的bug
-## 1.0.0（2021-11-19）
-- 优化 组件 UI，并提供设计资源，详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
-- 文档迁移，详见:[https://uniapp.dcloud.io/component/uniui/uni-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
-## 0.4.9（2021-10-28）
-- 修复 VUE2 v-model 概率无效的 bug
-## 0.4.8（2021-10-27）
-- 修复 v-model 概率无效的 bug
-## 0.4.7（2021-10-25）
-- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+
-- 修复 树型 uniCloud 数据类型为 int 时报错的 bug
-## 0.4.6（2021-10-19）
-- 修复 非 VUE3 v-model 为 0 时无法选中的 bug
-## 0.4.5（2021-09-26）
-- 新增 清除已选项的功能（通过 clearIcon 属性配置是否显示按钮），同时提供 clear 方法以供调用，二者等效
-- 修复 readonly 为 true 时报错的 bug
-## 0.4.4（2021-09-26）
-- 修复 上一版本造成的 map 属性失效的 bug
-- 新增 ellipsis 属性，支持配置 tab 选项长度过长时是否自动省略
-## 0.4.3（2021-09-24）
-- 修复 某些情况下级联未触发的 bug
-## 0.4.2（2021-09-23）
-- 新增 提供 show 和 hide 方法，开发者可以通过 ref 调用
-- 新增 选项内容过长自动添加省略号
-## 0.4.1（2021-09-15）
-- 新增 map 属性 字段映射，将 text/value 映射到数据中的其他字段
-## 0.4.0（2021-07-13）
-- 组件兼容 vue3，如何创建 vue3 项目，详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
-## 0.3.5（2021-06-04）
-- 修复 无法加载云端数据的问题
-## 0.3.4（2021-05-28）
-- 修复 v-model 无效问题
-- 修复 loaddata 为空数据组时加载时间过长问题
-- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点
-## 0.3.3（2021-05-12）
-- 新增 组件示例地址
-## 0.3.2（2021-04-22）
-- 修复 非树形数据有 where 属性查询报错的问题
-## 0.3.1（2021-04-15）
-- 修复 本地数据概率无法回显时问题
-## 0.3.0（2021-04-07）
-- 新增 支持云端非树形表结构数据
-- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题
-## 0.2.0（2021-03-15）
-- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题
-## 0.1.9（2021-03-09）
-- 修复 微信小程序某些情况下无法选择的问题
-## 0.1.8（2021-02-05）
-- 优化 部分样式在 nvue 上的兼容表现
-## 0.1.7（2021-02-05）
-- 调整为 uni_modules 目录规范
+## 1.1.2（2023-04-11）
+- 修复 更改 modelValue 报错的 bug
+- 修复 v-for 未使用 key 值控制台 warning
+## 1.1.1（2023-02-21）
+- 修复代码合并时引发 value 属性为空时不渲染数据的问题
+## 1.1.0（2023-02-15）
+- 修复 localdata 不支持动态更新的bug
+## 1.0.9（2023-02-15）
+- 修复 localdata 不支持动态更新的bug
+## 1.0.8（2022-09-16）
+- 可以使用 uni-scss 控制主题色
+## 1.0.7（2022-07-06）
+- 优化 pc端图标位置不正确的问题
+## 1.0.6（2022-07-05）
+- 优化 显示样式
+## 1.0.5（2022-07-04）
+- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
+## 1.0.4（2022-04-19）
+- 修复 字节小程序 本地数据无法选择下一级的Bug
+## 1.0.3（2022-02-25）
+- 修复 nvue 不支持的 v-show 的 bug
+## 1.0.2（2022-02-25）
+- 修复 条件编译 nvue 不支持的 css 样式
+## 1.0.1（2021-11-23）
+- 修复 由上个版本引发的map、v-model等属性不生效的bug
+## 1.0.0（2021-11-19）
+- 优化 组件 UI，并提供设计资源，详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移，详见:[https://uniapp.dcloud.io/component/uniui/uni-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+## 0.4.9（2021-10-28）
+- 修复 VUE2 v-model 概率无效的 bug
+## 0.4.8（2021-10-27）
+- 修复 v-model 概率无效的 bug
+## 0.4.7（2021-10-25）
+- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+
+- 修复 树型 uniCloud 数据类型为 int 时报错的 bug
+## 0.4.6（2021-10-19）
+- 修复 非 VUE3 v-model 为 0 时无法选中的 bug
+## 0.4.5（2021-09-26）
+- 新增 清除已选项的功能（通过 clearIcon 属性配置是否显示按钮），同时提供 clear 方法以供调用，二者等效
+- 修复 readonly 为 true 时报错的 bug
+## 0.4.4（2021-09-26）
+- 修复 上一版本造成的 map 属性失效的 bug
+- 新增 ellipsis 属性，支持配置 tab 选项长度过长时是否自动省略
+## 0.4.3（2021-09-24）
+- 修复 某些情况下级联未触发的 bug
+## 0.4.2（2021-09-23）
+- 新增 提供 show 和 hide 方法，开发者可以通过 ref 调用
+- 新增 选项内容过长自动添加省略号
+## 0.4.1（2021-09-15）
+- 新增 map 属性 字段映射，将 text/value 映射到数据中的其他字段
+## 0.4.0（2021-07-13）
+- 组件兼容 vue3，如何创建 vue3 项目，详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.3.5（2021-06-04）
+- 修复 无法加载云端数据的问题
+## 0.3.4（2021-05-28）
+- 修复 v-model 无效问题
+- 修复 loaddata 为空数据组时加载时间过长问题
+- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点
+## 0.3.3（2021-05-12）
+- 新增 组件示例地址
+## 0.3.2（2021-04-22）
+- 修复 非树形数据有 where 属性查询报错的问题
+## 0.3.1（2021-04-15）
+- 修复 本地数据概率无法回显时问题
+## 0.3.0（2021-04-07）
+- 新增 支持云端非树形表结构数据
+- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题
+## 0.2.0（2021-03-15）
+- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题
+## 0.1.9（2021-03-09）
+- 修复 微信小程序某些情况下无法选择的问题
+## 0.1.8（2021-02-05）
+- 优化 部分样式在 nvue 上的兼容表现
+## 0.1.7（2021-02-05）
+- 调整为 uni_modules 目录规范
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js b/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
index a747b9fc..6ef26a26 100644
--- a/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
@@ -1,45 +1,45 @@
-// #ifdef H5
-export default {
-  name: 'Keypress',
-  props: {
-    disable: {
-      type: Boolean,
-      default: false
-    }
-  },
-  mounted () {
-    const keyNames = {
-      esc: ['Esc', 'Escape'],
-      tab: 'Tab',
-      enter: 'Enter',
-      space: [' ', 'Spacebar'],
-      up: ['Up', 'ArrowUp'],
-      left: ['Left', 'ArrowLeft'],
-      right: ['Right', 'ArrowRight'],
-      down: ['Down', 'ArrowDown'],
-      delete: ['Backspace', 'Delete', 'Del']
-    }
-    const listener = ($event) => {
-      if (this.disable) {
-        return
-      }
-      const keyName = Object.keys(keyNames).find(key => {
-        const keyName = $event.key
-        const value = keyNames[key]
-        return value === keyName || (Array.isArray(value) && value.includes(keyName))
-      })
-      if (keyName) {
-        // 避免和其他按键事件冲突
-        setTimeout(() => {
-          this.$emit(keyName, {})
-        }, 0)
-      }
-    }
-    document.addEventListener('keyup', listener)
-    this.$once('hook:beforeDestroy', () => {
-      document.removeEventListener('keyup', listener)
-    })
-  },
-	render: () => {}
-}
-// #endif
+// #ifdef H5
+export default {
+  name: 'Keypress',
+  props: {
+    disable: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted () {
+    const keyNames = {
+      esc: ['Esc', 'Escape'],
+      tab: 'Tab',
+      enter: 'Enter',
+      space: [' ', 'Spacebar'],
+      up: ['Up', 'ArrowUp'],
+      left: ['Left', 'ArrowLeft'],
+      right: ['Right', 'ArrowRight'],
+      down: ['Down', 'ArrowDown'],
+      delete: ['Backspace', 'Delete', 'Del']
+    }
+    const listener = ($event) => {
+      if (this.disable) {
+        return
+      }
+      const keyName = Object.keys(keyNames).find(key => {
+        const keyName = $event.key
+        const value = keyNames[key]
+        return value === keyName || (Array.isArray(value) && value.includes(keyName))
+      })
+      if (keyName) {
+        // 避免和其他按键事件冲突
+        setTimeout(() => {
+          this.$emit(keyName, {})
+        }, 0)
+      }
+    }
+    document.addEventListener('keyup', listener)
+    this.$once('hook:beforeDestroy', () => {
+      document.removeEventListener('keyup', listener)
+    })
+  },
+	render: () => {}
+}
+// #endif
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
index fda8103a..dcbfd5f0 100644
--- a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
@@ -1,380 +1,381 @@
-<template>
-  <view class="uni-data-tree">
-    <view class="uni-data-tree-input" @click="handleInput">
-      <slot :data="selectedPaths" :error="error">
-        <view class="input-value" :class="{'input-value-border': border}">
-          <text v-if="error!=null" class="error-text">{{error!.errMsg}}</text>
-          <scroll-view v-if="selectedPaths.length" class="selected-path" scroll-x="true">
-            <view class="selected-list">
-              <template v-for="(item, index) in selectedPaths">
-                <text class="text-color">{{item[mappingTextName]}}</text>
-                <text v-if="index<selectedPaths.length-1" class="input-split-line">{{split}}</text>
-              </template>
-            </view>
-          </scroll-view>
-          <text v-else-if="error==null&&!loading" class="placeholder">{{placeholder}}</text>
-          <view v-if="!readonly" class="arrow-area">
-            <view class="input-arrow"></view>
-          </view>
-        </view>
-      </slot>
-      <view v-if="loading && !isOpened" class="selected-loading">
-        <slot name="picker-loading" :loading="loading"></slot>
-      </view>
-    </view>
-    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
-    <view class="uni-data-tree-dialog" v-if="isOpened">
-      <view class="uni-popper__arrow"></view>
-      <view class="dialog-caption">
-        <view class="dialog-title-view">
-          <text class="dialog-title">{{popupTitle}}</text>
-        </view>
-        <view class="dialog-close" @click="handleClose">
-          <view class="dialog-close-plus" data-id="close"></view>
-          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
-        </view>
-      </view>
-      <view ref="pickerView" class="uni-data-pickerview">
-        <view v-if="error!=null" class="error">
-          <text class="error-text">{{error!.errMsg}}</text>
-        </view>
-        <scroll-view v-if="!isCloudDataList" :scroll-x="true">
-          <view class="selected-node-list">
-            <template v-for="(item, index) in selectedNodes">
-              <text class="selected-node-item" :class="{'selected-node-item-active':index==selectedIndex}"
-                @click="onTabSelect(index)">
-                {{item[mappingTextName]}}
-              </text>
-            </template>
-          </view>
-        </scroll-view>
-        <list-view class="list-view" :scroll-y="true">
-          <list-item class="list-item" v-for="(item, _) in currentDataList" @click="onNodeClick(item)">
-            <text class="item-text" :class="{'item-text-disabled': item['disable']}">{{item[mappingTextName]}}</text>
-            <text class="check" v-if="item[mappingValueName] == selectedNodes[selectedIndex][mappingValueName]"></text>
-          </list-item>
-        </list-view>
-        <view class="loading-cover" v-if="loading">
-          <slot name="pickerview-loading" :loading="loading"></slot>
-        </view>
-      </view>
-    </view>
-  </view>
-</template>
-
-<script>
-  import { dataPicker } from "../uni-data-pickerview/uni-data-picker.uts"
-
-  /**
-   * DataPicker 级联选择
-   * @description 支持单列、和多列级联选择。列数没有限制，如果屏幕显示不全，顶部tab区域会左右滚动。
-   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
-   * @property {String} popup-title 弹出窗口标题
-   * @property {Array} localdata 本地数据，参考
-   * @property {Boolean} border = [true|false] 是否有边框
-   * @property {Boolean} readonly = [true|false] 是否仅读
-   * @property {Boolean} preload = [true|false] 是否预加载数据
-   * @value true 开启预加载数据，点击弹出窗口后显示已加载数据
-   * @value false 关闭预加载数据，点击弹出窗口后开始加载数据
-   * @property {Boolean} step-searh = [true|false] 是否分布查询
-   * @value true 启用分布查询，仅查询当前选中节点
-   * @value false 关闭分布查询，一次查询出所有数据
-   * @property {String|DBFieldString} self-field 分布查询当前字段名称
-   * @property {String|DBFieldString} parent-field 分布查询父字段名称
-   * @property {String|DBCollectionString} collection 表名
-   * @property {String|DBFieldString} field 查询字段，多个字段用 `,` 分割
-   * @property {String} orderby 排序字段及正序倒叙设置
-   * @property {String|JQLString} where 查询条件
-   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
-   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
-   */
-  export default {
-    name: 'UniDataPicker',
-    emits: ['popupopened', 'popupclosed', 'nodeclick', 'change', 'input', 'update:modelValue', 'inputclick'],
-    mixins: [dataPicker],
-    props: {
-      popupTitle: {
-        type: String,
-        default: '请选择'
-      },
-      placeholder: {
-        type: String,
-        default: '请选择'
-      },
-      heightMobile: {
-        type: String,
-        default: ''
-      },
-      readonly: {
-        type: Boolean,
-        default: false
-      },
-      clearIcon: {
-        type: Boolean,
-        default: true
-      },
-      border: {
-        type: Boolean,
-        default: true
-      },
-      split: {
-        type: String,
-        default: '/'
-      },
-      ellipsis: {
-        type: Boolean,
-        default: true
-      }
-    },
-    data() {
-      return {
-        isOpened: false
-      }
-    },
-    computed: {
-      isShowClearIcon() : boolean {
-        if (this.readonly) {
-          return false
-        }
-
-        if (this.clearIcon && this.selectedPaths.length > 0) {
-          return true
-        }
-
-        return false
-      }
-    },
-    created() {
-      this.load()
-    },
-    methods: {
-      clear() {
-      },
-      load() {
-        if (this.isLocalData) {
-          this.loadLocalData()
-        } else if (this.isCloudDataList || this.isCloudDataTree) {
-          this.loadCloudDataPath()
-        }
-      },
-      show() {
-        this.isOpened = true
-        this.$emit('popupopened')
-        if (!this.hasCloudTreeData) {
-          this.loadData()
-        }
-      },
-      hide() {
-        this.isOpened = false
-        this.$emit('popupclosed')
-      },
-      handleInput() {
-        if (this.readonly) {
-          this.$emit('inputclick')
-        } else {
-          this.show()
-        }
-      },
-      handleClose() {
-        this.hide()
-      },
-      onFinish() {
-        this.selectedPaths = this.getChangeNodes()
-        this.$emit('change', this.selectedPaths)
-        this.hide()
-      }
-    }
-  }
-</script>
-
-<style>
-  @import url("../uni-data-pickerview/uni-data-pickerview.css");
-
-  .uni-data-tree {
-    position: relative;
-  }
-
-  .uni-data-tree-input {
-    position: relative;
-  }
-
-  .selected-loading {
-    display: flex;
-    justify-content: center;
-    position: absolute;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-  }
-
-  .error-text {
-    flex: 1;
-    font-size: 12px;
-    color: #DD524D;
-  }
-
-  .input-value {
-    flex-direction: row;
-    align-items: center;
-    flex-wrap: nowrap;
-    padding: 5px 5px;
-    padding-right: 5px;
-    overflow: hidden;
-    min-height: 28px;
-  }
-
-  .input-value-border {
-    border: 1px solid #e5e5e5;
-    border-radius: 5px;
-  }
-
-  .selected-path {
-    flex: 1;
-    flex-direction: row;
-    overflow: hidden;
-  }
-
-  .load-more {
-    width: 40px;
-  }
-
-  .selected-list {
-    flex-direction: row;
-    flex-wrap: nowrap;
-  }
-
-  .selected-item {
-    flex-direction: row;
-    flex-wrap: nowrap;
-  }
-
-  .text-color {
-    font-size: 14px;
-    color: #333;
-  }
-
-  .placeholder {
-    color: grey;
-    font-size: 14px;
-  }
-
-  .input-split-line {
-    opacity: .5;
-    margin-left: 1px;
-    margin-right: 1px;
-  }
-
-  .arrow-area {
-    position: relative;
-    padding: 0 12px;
-    margin-left: auto;
-    justify-content: center;
-    transform: rotate(-45deg);
-    transform-origin: center;
-  }
-
-  .input-arrow {
-    width: 8px;
-    height: 8px;
-    border-left: 2px solid #999;
-    border-bottom: 2px solid #999;
-  }
-
-  .uni-data-tree-cover {
-    position: fixed;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    background-color: rgba(0, 0, 0, .4);
-    flex-direction: column;
-    z-index: 100;
-  }
-
-  .uni-data-tree-dialog {
-    position: fixed;
-    left: 0;
-    top: 20%;
-    right: 0;
-    bottom: 0;
-    background-color: #FFFFFF;
-    border-top-left-radius: 10px;
-    border-top-right-radius: 10px;
-    flex-direction: column;
-    z-index: 102;
-    overflow: hidden;
-  }
-
-  .dialog-caption {
-    position: relative;
-    flex-direction: row;
-  }
-
-  .dialog-title-view {
-    flex: 1;
-  }
-
-  .dialog-title {
-    align-self: center;
-    padding: 0 10px;
-    line-height: 44px;
-  }
-
-  .dialog-close {
-    position: absolute;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    flex-direction: row;
-    align-items: center;
-    padding: 0 15px;
-  }
-
-  .dialog-close-plus {
-    width: 16px;
-    height: 2px;
-    background-color: #666;
-    border-radius: 2px;
-    transform: rotate(45deg);
-  }
-
-  .dialog-close-rotate {
-    position: absolute;
-    transform: rotate(-45deg);
-  }
-
-  .uni-data-pickerview {
-    flex: 1;
-  }
-
-  .icon-clear {
-    display: flex;
-    align-items: center;
-  }
-
-  /* #ifdef H5 */
-  @media all and (min-width: 768px) {
-    .uni-data-tree-cover {
-      background-color: transparent;
-    }
-
-    .uni-data-tree-dialog {
-      position: absolute;
-      top: 55px;
-      height: auto;
-      min-height: 400px;
-      max-height: 50vh;
-      background-color: #fff;
-      border: 1px solid #EBEEF5;
-      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-      border-radius: 4px;
-      overflow: unset;
-    }
-
-    .dialog-caption {
-      display: none;
-    }
-  }
-  /* #endif */
-</style>
+<template>
+  <view class="uni-data-tree">
+    <view class="uni-data-tree-input" @click="handleInput">
+      <slot :data="selectedPaths" :error="error">
+        <view class="input-value" :class="{'input-value-border': border}">
+          <text v-if="error!=null" class="error-text">{{error!.errMsg}}</text>
+          <scroll-view v-if="selectedPaths.length" class="selected-path" scroll-x="true">
+            <view class="selected-list">
+              <template v-for="(item, index) in selectedPaths">
+                <text class="text-color">{{item[mappingTextName]}}</text>
+                <text v-if="index<selectedPaths.length-1" class="input-split-line">{{split}}</text>
+              </template>
+            </view>
+          </scroll-view>
+          <text v-else-if="error==null&&!loading" class="placeholder">{{placeholder}}</text>
+          <view v-if="!readonly" class="arrow-area">
+            <view class="input-arrow"></view>
+          </view>
+        </view>
+      </slot>
+      <view v-if="loading && !isOpened" class="selected-loading">
+        <slot name="picker-loading" :loading="loading"></slot>
+      </view>
+    </view>
+    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
+    <view class="uni-data-tree-dialog" v-if="isOpened">
+      <view class="uni-popper__arrow"></view>
+      <view class="dialog-caption">
+        <view class="dialog-title-view">
+          <text class="dialog-title">{{popupTitle}}</text>
+        </view>
+        <view class="dialog-close" @click="handleClose">
+          <view class="dialog-close-plus" data-id="close"></view>
+          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
+        </view>
+      </view>
+      <view ref="pickerView" class="uni-data-pickerview">
+        <view v-if="error!=null" class="error">
+          <text class="error-text">{{error!.errMsg}}</text>
+        </view>
+        <scroll-view v-if="!isCloudDataList" :scroll-x="true">
+          <view class="selected-node-list">
+            <template v-for="(item, index) in selectedNodes">
+              <text class="selected-node-item" :class="{'selected-node-item-active':index==selectedIndex}"
+                @click="onTabSelect(index)">
+                {{item[mappingTextName]}}
+              </text>
+            </template>
+          </view>
+        </scroll-view>
+        <list-view class="list-view" :scroll-y="true">
+          <list-item class="list-item" v-for="(item, _) in currentDataList" @click="onNodeClick(item)">
+            <text class="item-text" :class="{'item-text-disabled': item['disable']}">{{item[mappingTextName]}}</text>
+            <text class="check" v-if="item[mappingValueName] == selectedNodes[selectedIndex][mappingValueName]"></text>
+          </list-item>
+        </list-view>
+        <view class="loading-cover" v-if="loading">
+          <slot name="pickerview-loading" :loading="loading"></slot>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+  import { dataPicker } from "../uni-data-pickerview/uni-data-picker.uts"
+
+  /**
+   * DataPicker 级联选择
+   * @description 支持单列、和多列级联选择。列数没有限制，如果屏幕显示不全，顶部tab区域会左右滚动。
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+   * @property {String} popup-title 弹出窗口标题
+   * @property {Array} localdata 本地数据，参考
+   * @property {Boolean} border = [true|false] 是否有边框
+   * @property {Boolean} readonly = [true|false] 是否仅读
+   * @property {Boolean} preload = [true|false] 是否预加载数据
+   * @value true 开启预加载数据，点击弹出窗口后显示已加载数据
+   * @value false 关闭预加载数据，点击弹出窗口后开始加载数据
+   * @property {Boolean} step-searh = [true|false] 是否分布查询
+   * @value true 启用分布查询，仅查询当前选中节点
+   * @value false 关闭分布查询，一次查询出所有数据
+   * @property {String|DBFieldString} self-field 分布查询当前字段名称
+   * @property {String|DBFieldString} parent-field 分布查询父字段名称
+   * @property {String|DBCollectionString} collection 表名
+   * @property {String|DBFieldString} field 查询字段，多个字段用 `,` 分割
+   * @property {String} orderby 排序字段及正序倒叙设置
+   * @property {String|JQLString} where 查询条件
+   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
+   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
+   */
+  export default {
+    name: 'UniDataPicker',
+    emits: ['popupopened', 'popupclosed', 'nodeclick', 'change', 'input', 'update:modelValue', 'inputclick'],
+    mixins: [dataPicker],
+    props: {
+      popupTitle: {
+        type: String,
+        default: '请选择'
+      },
+      placeholder: {
+        type: String,
+        default: '请选择'
+      },
+      heightMobile: {
+        type: String,
+        default: ''
+      },
+      readonly: {
+        type: Boolean,
+        default: false
+      },
+      clearIcon: {
+        type: Boolean,
+        default: true
+      },
+      border: {
+        type: Boolean,
+        default: true
+      },
+      split: {
+        type: String,
+        default: '/'
+      },
+      ellipsis: {
+        type: Boolean,
+        default: true
+      }
+    },
+    data() {
+      return {
+        isOpened: false
+      }
+    },
+    computed: {
+      isShowClearIcon() : boolean {
+        if (this.readonly) {
+          return false
+        }
+
+        if (this.clearIcon && this.selectedPaths.length > 0) {
+          return true
+        }
+
+        return false
+      }
+    },
+    created() {
+      this.load()
+    },
+    methods: {
+      clear() {
+      },
+      load() {
+        if (this.isLocalData) {
+          this.loadLocalData()
+        } else if (this.isCloudDataList || this.isCloudDataTree) {
+          this.loadCloudDataPath()
+        }
+      },
+      show() {
+        this.isOpened = true
+        this.$emit('popupopened')
+        if (!this.hasCloudTreeData) {
+          this.loadData()
+        }
+      },
+      hide() {
+        this.isOpened = false
+        this.$emit('popupclosed')
+      },
+      handleInput() {
+        if (this.readonly) {
+          this.$emit('inputclick')
+        } else {
+          this.show()
+        }
+      },
+      handleClose() {
+        this.hide()
+      },
+      onFinish() {
+        this.selectedPaths = this.getChangeNodes()
+        this.$emit('update:modelValue', this.selectedPaths)
+        this.$emit('change', this.selectedPaths)
+        this.hide()
+      }
+    }
+  }
+</script>
+
+<style>
+  @import url("../uni-data-pickerview/uni-data-pickerview.css");
+
+  .uni-data-tree {
+    position: relative;
+  }
+
+  .uni-data-tree-input {
+    position: relative;
+  }
+
+  .selected-loading {
+    display: flex;
+    justify-content: center;
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+  }
+
+  .error-text {
+    flex: 1;
+    font-size: 12px;
+    color: #DD524D;
+  }
+
+  .input-value {
+    flex-direction: row;
+    align-items: center;
+    flex-wrap: nowrap;
+    padding: 5px 5px;
+    padding-right: 5px;
+    overflow: hidden;
+    min-height: 28px;
+  }
+
+  .input-value-border {
+    border: 1px solid #e5e5e5;
+    border-radius: 5px;
+  }
+
+  .selected-path {
+    flex: 1;
+    flex-direction: row;
+    overflow: hidden;
+  }
+
+  .load-more {
+    width: 40px;
+  }
+
+  .selected-list {
+    flex-direction: row;
+    flex-wrap: nowrap;
+  }
+
+  .selected-item {
+    flex-direction: row;
+    flex-wrap: nowrap;
+  }
+
+  .text-color {
+    font-size: 14px;
+    color: #333;
+  }
+
+  .placeholder {
+    color: grey;
+    font-size: 14px;
+  }
+
+  .input-split-line {
+    opacity: .5;
+    margin-left: 1px;
+    margin-right: 1px;
+  }
+
+  .arrow-area {
+    position: relative;
+    padding: 0 12px;
+    margin-left: auto;
+    justify-content: center;
+    transform: rotate(-45deg);
+    transform-origin: center;
+  }
+
+  .input-arrow {
+    width: 8px;
+    height: 8px;
+    border-left: 2px solid #999;
+    border-bottom: 2px solid #999;
+  }
+
+  .uni-data-tree-cover {
+    position: fixed;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, .4);
+    flex-direction: column;
+    z-index: 100;
+  }
+
+  .uni-data-tree-dialog {
+    position: fixed;
+    left: 0;
+    top: 20%;
+    right: 0;
+    bottom: 0;
+    background-color: #FFFFFF;
+    border-top-left-radius: 10px;
+    border-top-right-radius: 10px;
+    flex-direction: column;
+    z-index: 102;
+    overflow: hidden;
+  }
+
+  .dialog-caption {
+    position: relative;
+    flex-direction: row;
+  }
+
+  .dialog-title-view {
+    flex: 1;
+  }
+
+  .dialog-title {
+    align-self: center;
+    padding: 0 10px;
+    line-height: 44px;
+  }
+
+  .dialog-close {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    flex-direction: row;
+    align-items: center;
+    padding: 0 15px;
+  }
+
+  .dialog-close-plus {
+    width: 16px;
+    height: 2px;
+    background-color: #666;
+    border-radius: 2px;
+    transform: rotate(45deg);
+  }
+
+  .dialog-close-rotate {
+    position: absolute;
+    transform: rotate(-45deg);
+  }
+
+  .uni-data-pickerview {
+    flex: 1;
+  }
+
+  .icon-clear {
+    display: flex;
+    align-items: center;
+  }
+
+  /* #ifdef H5 */
+  @media all and (min-width: 768px) {
+    .uni-data-tree-cover {
+      background-color: transparent;
+    }
+
+    .uni-data-tree-dialog {
+      position: absolute;
+      top: 55px;
+      height: auto;
+      min-height: 400px;
+      max-height: 50vh;
+      background-color: #fff;
+      border: 1px solid #EBEEF5;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+      border-radius: 4px;
+      overflow: unset;
+    }
+
+    .dialog-caption {
+      display: none;
+    }
+  }
+  /* #endif */
+</style>
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
index c86d5476..179a4e0b 100644
--- a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
@@ -1,551 +1,551 @@
-<template>
-  <view class="uni-data-tree">
-    <view class="uni-data-tree-input" @click="handleInput">
-      <slot :options="options" :data="inputSelected" :error="errorMessage">
-        <view class="input-value" :class="{'input-value-border': border}">
-          <text v-if="errorMessage" class="selected-area error-text">{{errorMessage}}</text>
-          <view v-else-if="loading && !isOpened" class="selected-area">
-            <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
-          </view>
-          <scroll-view v-else-if="inputSelected.length" class="selected-area" scroll-x="true">
-            <view class="selected-list">
-              <view class="selected-item" v-for="(item,index) in inputSelected" :key="index">
-                <text class="text-color">{{item.text}}</text><text v-if="index<inputSelected.length-1"
-                  class="input-split-line">{{split}}</text>
-              </view>
-            </view>
-          </scroll-view>
-          <text v-else class="selected-area placeholder">{{placeholder}}</text>
-          <view v-if="clearIcon && !readonly && inputSelected.length" class="icon-clear" @click.stop="clear">
-            <uni-icons type="clear" color="#c0c4cc" size="24"></uni-icons>
-          </view>
-          <view class="arrow-area" v-if="(!clearIcon || !inputSelected.length) && !readonly ">
-            <view class="input-arrow"></view>
-          </view>
-        </view>
-      </slot>
-    </view>
-    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
-    <view class="uni-data-tree-dialog" v-if="isOpened">
-      <view class="uni-popper__arrow"></view>
-      <view class="dialog-caption">
-        <view class="title-area">
-          <text class="dialog-title">{{popupTitle}}</text>
-        </view>
-        <view class="dialog-close" @click="handleClose">
-          <view class="dialog-close-plus" data-id="close"></view>
-          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
-        </view>
-      </view>
-      <data-picker-view class="picker-view" ref="pickerView" v-model="dataValue" :localdata="localdata"
-        :preload="preload" :collection="collection" :field="field" :orderby="orderby" :where="where"
-        :step-searh="stepSearh" :self-field="selfField" :parent-field="parentField" :managed-mode="true" :map="map"
-        :ellipsis="ellipsis" @change="onchange" @datachange="ondatachange" @nodeclick="onnodeclick">
-      </data-picker-view>
-    </view>
-  </view>
-</template>
-
-<script>
-  import dataPicker from "../uni-data-pickerview/uni-data-picker.js"
-  import DataPickerView from "../uni-data-pickerview/uni-data-pickerview.vue"
-
-  /**
-   * DataPicker 级联选择
-   * @description 支持单列、和多列级联选择。列数没有限制，如果屏幕显示不全，顶部tab区域会左右滚动。
-   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
-   * @property {String} popup-title 弹出窗口标题
-   * @property {Array} localdata 本地数据，参考
-   * @property {Boolean} border = [true|false] 是否有边框
-   * @property {Boolean} readonly = [true|false] 是否仅读
-   * @property {Boolean} preload = [true|false] 是否预加载数据
-   * @value true 开启预加载数据，点击弹出窗口后显示已加载数据
-   * @value false 关闭预加载数据，点击弹出窗口后开始加载数据
-   * @property {Boolean} step-searh = [true|false] 是否分布查询
-   * @value true 启用分布查询，仅查询当前选中节点
-   * @value false 关闭分布查询，一次查询出所有数据
-   * @property {String|DBFieldString} self-field 分布查询当前字段名称
-   * @property {String|DBFieldString} parent-field 分布查询父字段名称
-   * @property {String|DBCollectionString} collection 表名
-   * @property {String|DBFieldString} field 查询字段，多个字段用 `,` 分割
-   * @property {String} orderby 排序字段及正序倒叙设置
-   * @property {String|JQLString} where 查询条件
-   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
-   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
-   */
-  export default {
-    name: 'UniDataPicker',
-    emits: ['popupopened', 'popupclosed', 'nodeclick', 'input', 'change', 'update:modelValue','inputclick'],
-    mixins: [dataPicker],
-    components: {
-      DataPickerView
-    },
-    props: {
-      options: {
-        type: [Object, Array],
-        default () {
-          return {}
-        }
-      },
-      popupTitle: {
-        type: String,
-        default: '请选择'
-      },
-      placeholder: {
-        type: String,
-        default: '请选择'
-      },
-      heightMobile: {
-        type: String,
-        default: ''
-      },
-      readonly: {
-        type: Boolean,
-        default: false
-      },
-      clearIcon: {
-        type: Boolean,
-        default: true
-      },
-      border: {
-        type: Boolean,
-        default: true
-      },
-      split: {
-        type: String,
-        default: '/'
-      },
-      ellipsis: {
-        type: Boolean,
-        default: true
-      }
-    },
-    data() {
-      return {
-        isOpened: false,
-        inputSelected: []
-      }
-    },
-    created() {
-      this.$nextTick(() => {
-        this.load();
-      })
-    },
-    watch: {
-			localdata: {
-				handler() {
-					this.load()
-				},
-        deep: true
-			},
-    },
-    methods: {
-      clear() {
-        this._dispatchEvent([]);
-      },
-      onPropsChange() {
-        this._treeData = [];
-        this.selectedIndex = 0;
-
-        this.load();
-      },
-      load() {
-        if (this.readonly) {
-          this._processReadonly(this.localdata, this.dataValue);
-          return;
-        }
-
-        // 回显本地数据
-        if (this.isLocalData) {
-          this.loadData();
-          this.inputSelected = this.selected.slice(0);
-        } else if (this.isCloudDataList || this.isCloudDataTree) { // 回显 Cloud 数据
-          this.loading = true;
-          this.getCloudDataValue().then((res) => {
-            this.loading = false;
-            this.inputSelected = res;
-          }).catch((err) => {
-            this.loading = false;
-            this.errorMessage = err;
-          })
-        }
-      },
-      show() {
-        this.isOpened = true
-        setTimeout(() => {
-          this.$refs.pickerView.updateData({
-            treeData: this._treeData,
-            selected: this.selected,
-            selectedIndex: this.selectedIndex
-          })
-        }, 200)
-        this.$emit('popupopened')
-      },
-      hide() {
-        this.isOpened = false
-        this.$emit('popupclosed')
-      },
-      handleInput() {
-        if (this.readonly) {
-					this.$emit('inputclick')
-          return
-        }
-        this.show()
-      },
-      handleClose(e) {
-        this.hide()
-      },
-      onnodeclick(e) {
-        this.$emit('nodeclick', e)
-      },
-      ondatachange(e) {
-        this._treeData = this.$refs.pickerView._treeData
-      },
-      onchange(e) {
-        this.hide()
-        this.$nextTick(() => {
-          this.inputSelected = e;
-        })
-        this._dispatchEvent(e)
-      },
-      _processReadonly(dataList, value) {
-        var isTree = dataList.findIndex((item) => {
-          return item.children
-        })
-        if (isTree > -1) {
-          let inputValue
-          if (Array.isArray(value)) {
-            inputValue = value[value.length - 1]
-            if (typeof inputValue === 'object' && inputValue.value) {
-              inputValue = inputValue.value
-            }
-          } else {
-            inputValue = value
-          }
-          this.inputSelected = this._findNodePath(inputValue, this.localdata)
-          return
-        }
-
-        if (!this.hasValue) {
-          this.inputSelected = []
-          return
-        }
-
-        let result = []
-        for (let i = 0; i < value.length; i++) {
-          var val = value[i]
-          var item = dataList.find((v) => {
-            return v.value == val
-          })
-          if (item) {
-            result.push(item)
-          }
-        }
-        if (result.length) {
-          this.inputSelected = result
-        }
-      },
-      _filterForArray(data, valueArray) {
-        var result = []
-        for (let i = 0; i < valueArray.length; i++) {
-          var value = valueArray[i]
-          var found = data.find((item) => {
-            return item.value == value
-          })
-          if (found) {
-            result.push(found)
-          }
-        }
-        return result
-      },
-      _dispatchEvent(selected) {
-        let item = {}
-        if (selected.length) {
-          var value = new Array(selected.length)
-          for (var i = 0; i < selected.length; i++) {
-            value[i] = selected[i].value
-          }
-          item = selected[selected.length - 1]
-        } else {
-          item.value = ''
-        }
-        if (this.formItem) {
-          this.formItem.setValue(item.value)
-        }
-
-        this.$emit('input', item.value)
-        this.$emit('update:modelValue', item.value)
-        this.$emit('change', {
-          detail: {
-            value: selected
-          }
-        })
-      }
-    }
-  }
-</script>
-
-<style>
-  .uni-data-tree {
-    flex: 1;
-    position: relative;
-    font-size: 14px;
-  }
-
-  .error-text {
-    color: #DD524D;
-  }
-
-  .input-value {
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: row;
-    align-items: center;
-    flex-wrap: nowrap;
-    font-size: 14px;
-    /* line-height: 35px; */
-    padding: 0 10px;
-    padding-right: 5px;
-    overflow: hidden;
-    height: 35px;
-    /* #ifndef APP-NVUE */
-    box-sizing: border-box;
-    /* #endif */
-  }
-
-  .input-value-border {
-    border: 1px solid #e5e5e5;
-    border-radius: 5px;
-  }
-
-  .selected-area {
-    flex: 1;
-    overflow: hidden;
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: row;
-  }
-
-  .load-more {
-    /* #ifndef APP-NVUE */
-    margin-right: auto;
-    /* #endif */
-    /* #ifdef APP-NVUE */
-    width: 40px;
-    /* #endif */
-  }
-
-  .selected-list {
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: row;
-    flex-wrap: nowrap;
-    /* padding: 0 5px; */
-  }
-
-  .selected-item {
-    flex-direction: row;
-    /* padding: 0 1px; */
-    /* #ifndef APP-NVUE */
-    white-space: nowrap;
-    /* #endif */
-  }
-
-  .text-color {
-    color: #333;
-  }
-
-  .placeholder {
-    color: grey;
-    font-size: 12px;
-  }
-
-  .input-split-line {
-    opacity: .5;
-  }
-
-  .arrow-area {
-    position: relative;
-    width: 20px;
-    /* #ifndef APP-NVUE */
-    margin-bottom: 5px;
-    margin-left: auto;
-    display: flex;
-    /* #endif */
-    justify-content: center;
-    transform: rotate(-45deg);
-    transform-origin: center;
-  }
-
-  .input-arrow {
-    width: 7px;
-    height: 7px;
-    border-left: 1px solid #999;
-    border-bottom: 1px solid #999;
-  }
-
-  .uni-data-tree-cover {
-    position: fixed;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    background-color: rgba(0, 0, 0, .4);
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: column;
-    z-index: 100;
-  }
-
-  .uni-data-tree-dialog {
-    position: fixed;
-    left: 0;
-    /* #ifndef APP-NVUE */
-    top: 20%;
-    /* #endif */
-    /* #ifdef APP-NVUE */
-    top: 200px;
-    /* #endif */
-    right: 0;
-    bottom: 0;
-    background-color: #FFFFFF;
-    border-top-left-radius: 10px;
-    border-top-right-radius: 10px;
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: column;
-    z-index: 102;
-    overflow: hidden;
-    /* #ifdef APP-NVUE */
-    width: 750rpx;
-    /* #endif */
-  }
-
-  .dialog-caption {
-    position: relative;
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: row;
-    /* border-bottom: 1px solid #f0f0f0; */
-  }
-
-  .title-area {
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    align-items: center;
-    /* #ifndef APP-NVUE */
-    margin: auto;
-    /* #endif */
-    padding: 0 10px;
-  }
-
-  .dialog-title {
-    /* font-weight: bold; */
-    line-height: 44px;
-  }
-
-  .dialog-close {
-    position: absolute;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: row;
-    align-items: center;
-    padding: 0 15px;
-  }
-
-  .dialog-close-plus {
-    width: 16px;
-    height: 2px;
-    background-color: #666;
-    border-radius: 2px;
-    transform: rotate(45deg);
-  }
-
-  .dialog-close-rotate {
-    position: absolute;
-    transform: rotate(-45deg);
-  }
-
-  .picker-view {
-    flex: 1;
-    overflow: hidden;
-  }
-
-  .icon-clear {
-    display: flex;
-    align-items: center;
-  }
-
-  /* #ifdef H5 */
-  @media all and (min-width: 768px) {
-    .uni-data-tree-cover {
-      background-color: transparent;
-    }
-
-    .uni-data-tree-dialog {
-      position: absolute;
-      top: 55px;
-      height: auto;
-      min-height: 400px;
-      max-height: 50vh;
-      background-color: #fff;
-      border: 1px solid #EBEEF5;
-      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-      border-radius: 4px;
-      overflow: unset;
-    }
-
-    .dialog-caption {
-      display: none;
-    }
-
-    .icon-clear {
-      /* margin-right: 5px; */
-    }
-  }
-
-  /* #endif */
-
-  /* picker 弹出层通用的指示小三角, todo：扩展至上下左右方向定位 */
-  /* #ifndef APP-NVUE */
-  .uni-popper__arrow,
-  .uni-popper__arrow::after {
-    position: absolute;
-    display: block;
-    width: 0;
-    height: 0;
-    border-color: transparent;
-    border-style: solid;
-    border-width: 6px;
-  }
-
-  .uni-popper__arrow {
-    filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
-    top: -6px;
-    left: 10%;
-    margin-right: 3px;
-    border-top-width: 0;
-    border-bottom-color: #EBEEF5;
-  }
-
-  .uni-popper__arrow::after {
-    content: " ";
-    top: 1px;
-    margin-left: -6px;
-    border-top-width: 0;
-    border-bottom-color: #fff;
-  }
-
-  /* #endif */
-</style>
+<template>
+  <view class="uni-data-tree">
+    <view class="uni-data-tree-input" @click="handleInput">
+      <slot :options="options" :data="inputSelected" :error="errorMessage">
+        <view class="input-value" :class="{'input-value-border': border}">
+          <text v-if="errorMessage" class="selected-area error-text">{{errorMessage}}</text>
+          <view v-else-if="loading && !isOpened" class="selected-area">
+            <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
+          </view>
+          <scroll-view v-else-if="inputSelected.length" class="selected-area" scroll-x="true">
+            <view class="selected-list">
+              <view class="selected-item" v-for="(item,index) in inputSelected" :key="index">
+                <text class="text-color">{{item.text}}</text><text v-if="index<inputSelected.length-1"
+                  class="input-split-line">{{split}}</text>
+              </view>
+            </view>
+          </scroll-view>
+          <text v-else class="selected-area placeholder">{{placeholder}}</text>
+          <view v-if="clearIcon && !readonly && inputSelected.length" class="icon-clear" @click.stop="clear">
+            <uni-icons type="clear" color="#c0c4cc" size="24"></uni-icons>
+          </view>
+          <view class="arrow-area" v-if="(!clearIcon || !inputSelected.length) && !readonly ">
+            <view class="input-arrow"></view>
+          </view>
+        </view>
+      </slot>
+    </view>
+    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
+    <view class="uni-data-tree-dialog" v-if="isOpened">
+      <view class="uni-popper__arrow"></view>
+      <view class="dialog-caption">
+        <view class="title-area">
+          <text class="dialog-title">{{popupTitle}}</text>
+        </view>
+        <view class="dialog-close" @click="handleClose">
+          <view class="dialog-close-plus" data-id="close"></view>
+          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
+        </view>
+      </view>
+      <data-picker-view class="picker-view" ref="pickerView" v-model="dataValue" :localdata="localdata"
+        :preload="preload" :collection="collection" :field="field" :orderby="orderby" :where="where"
+        :step-searh="stepSearh" :self-field="selfField" :parent-field="parentField" :managed-mode="true" :map="map"
+        :ellipsis="ellipsis" @change="onchange" @datachange="ondatachange" @nodeclick="onnodeclick">
+      </data-picker-view>
+    </view>
+  </view>
+</template>
+
+<script>
+  import dataPicker from "../uni-data-pickerview/uni-data-picker.js"
+  import DataPickerView from "../uni-data-pickerview/uni-data-pickerview.vue"
+
+  /**
+   * DataPicker 级联选择
+   * @description 支持单列、和多列级联选择。列数没有限制，如果屏幕显示不全，顶部tab区域会左右滚动。
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+   * @property {String} popup-title 弹出窗口标题
+   * @property {Array} localdata 本地数据，参考
+   * @property {Boolean} border = [true|false] 是否有边框
+   * @property {Boolean} readonly = [true|false] 是否仅读
+   * @property {Boolean} preload = [true|false] 是否预加载数据
+   * @value true 开启预加载数据，点击弹出窗口后显示已加载数据
+   * @value false 关闭预加载数据，点击弹出窗口后开始加载数据
+   * @property {Boolean} step-searh = [true|false] 是否分布查询
+   * @value true 启用分布查询，仅查询当前选中节点
+   * @value false 关闭分布查询，一次查询出所有数据
+   * @property {String|DBFieldString} self-field 分布查询当前字段名称
+   * @property {String|DBFieldString} parent-field 分布查询父字段名称
+   * @property {String|DBCollectionString} collection 表名
+   * @property {String|DBFieldString} field 查询字段，多个字段用 `,` 分割
+   * @property {String} orderby 排序字段及正序倒叙设置
+   * @property {String|JQLString} where 查询条件
+   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
+   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
+   */
+  export default {
+    name: 'UniDataPicker',
+    emits: ['popupopened', 'popupclosed', 'nodeclick', 'input', 'change', 'update:modelValue','inputclick'],
+    mixins: [dataPicker],
+    components: {
+      DataPickerView
+    },
+    props: {
+      options: {
+        type: [Object, Array],
+        default () {
+          return {}
+        }
+      },
+      popupTitle: {
+        type: String,
+        default: '请选择'
+      },
+      placeholder: {
+        type: String,
+        default: '请选择'
+      },
+      heightMobile: {
+        type: String,
+        default: ''
+      },
+      readonly: {
+        type: Boolean,
+        default: false
+      },
+      clearIcon: {
+        type: Boolean,
+        default: true
+      },
+      border: {
+        type: Boolean,
+        default: true
+      },
+      split: {
+        type: String,
+        default: '/'
+      },
+      ellipsis: {
+        type: Boolean,
+        default: true
+      }
+    },
+    data() {
+      return {
+        isOpened: false,
+        inputSelected: []
+      }
+    },
+    created() {
+      this.$nextTick(() => {
+        this.load();
+      })
+    },
+    watch: {
+			localdata: {
+				handler() {
+					this.load()
+				},
+        deep: true
+			},
+    },
+    methods: {
+      clear() {
+        this._dispatchEvent([]);
+      },
+      onPropsChange() {
+        this._treeData = [];
+        this.selectedIndex = 0;
+
+        this.load();
+      },
+      load() {
+        if (this.readonly) {
+          this._processReadonly(this.localdata, this.dataValue);
+          return;
+        }
+
+        // 回显本地数据
+        if (this.isLocalData) {
+          this.loadData();
+          this.inputSelected = this.selected.slice(0);
+        } else if (this.isCloudDataList || this.isCloudDataTree) { // 回显 Cloud 数据
+          this.loading = true;
+          this.getCloudDataValue().then((res) => {
+            this.loading = false;
+            this.inputSelected = res;
+          }).catch((err) => {
+            this.loading = false;
+            this.errorMessage = err;
+          })
+        }
+      },
+      show() {
+        this.isOpened = true
+        setTimeout(() => {
+          this.$refs.pickerView.updateData({
+            treeData: this._treeData,
+            selected: this.selected,
+            selectedIndex: this.selectedIndex
+          })
+        }, 200)
+        this.$emit('popupopened')
+      },
+      hide() {
+        this.isOpened = false
+        this.$emit('popupclosed')
+      },
+      handleInput() {
+        if (this.readonly) {
+					this.$emit('inputclick')
+          return
+        }
+        this.show()
+      },
+      handleClose(e) {
+        this.hide()
+      },
+      onnodeclick(e) {
+        this.$emit('nodeclick', e)
+      },
+      ondatachange(e) {
+        this._treeData = this.$refs.pickerView._treeData
+      },
+      onchange(e) {
+        this.hide()
+        this.$nextTick(() => {
+          this.inputSelected = e;
+        })
+        this._dispatchEvent(e)
+      },
+      _processReadonly(dataList, value) {
+        var isTree = dataList.findIndex((item) => {
+          return item.children
+        })
+        if (isTree > -1) {
+          let inputValue
+          if (Array.isArray(value)) {
+            inputValue = value[value.length - 1]
+            if (typeof inputValue === 'object' && inputValue.value) {
+              inputValue = inputValue.value
+            }
+          } else {
+            inputValue = value
+          }
+          this.inputSelected = this._findNodePath(inputValue, this.localdata)
+          return
+        }
+
+        if (!this.hasValue) {
+          this.inputSelected = []
+          return
+        }
+
+        let result = []
+        for (let i = 0; i < value.length; i++) {
+          var val = value[i]
+          var item = dataList.find((v) => {
+            return v.value == val
+          })
+          if (item) {
+            result.push(item)
+          }
+        }
+        if (result.length) {
+          this.inputSelected = result
+        }
+      },
+      _filterForArray(data, valueArray) {
+        var result = []
+        for (let i = 0; i < valueArray.length; i++) {
+          var value = valueArray[i]
+          var found = data.find((item) => {
+            return item.value == value
+          })
+          if (found) {
+            result.push(found)
+          }
+        }
+        return result
+      },
+      _dispatchEvent(selected) {
+        let item = {}
+        if (selected.length) {
+          var value = new Array(selected.length)
+          for (var i = 0; i < selected.length; i++) {
+            value[i] = selected[i].value
+          }
+          item = selected[selected.length - 1]
+        } else {
+          item.value = ''
+        }
+        if (this.formItem) {
+          this.formItem.setValue(item.value)
+        }
+
+        this.$emit('input', item.value)
+        this.$emit('update:modelValue', item.value)
+        this.$emit('change', {
+          detail: {
+            value: selected
+          }
+        })
+      }
+    }
+  }
+</script>
+
+<style>
+  .uni-data-tree {
+    flex: 1;
+    position: relative;
+    font-size: 14px;
+  }
+
+  .error-text {
+    color: #DD524D;
+  }
+
+  .input-value {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    align-items: center;
+    flex-wrap: nowrap;
+    font-size: 14px;
+    /* line-height: 35px; */
+    padding: 0 10px;
+    padding-right: 5px;
+    overflow: hidden;
+    height: 35px;
+    /* #ifndef APP-NVUE */
+    box-sizing: border-box;
+    /* #endif */
+  }
+
+  .input-value-border {
+    border: 1px solid #e5e5e5;
+    border-radius: 5px;
+  }
+
+  .selected-area {
+    flex: 1;
+    overflow: hidden;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+  }
+
+  .load-more {
+    /* #ifndef APP-NVUE */
+    margin-right: auto;
+    /* #endif */
+    /* #ifdef APP-NVUE */
+    width: 40px;
+    /* #endif */
+  }
+
+  .selected-list {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    flex-wrap: nowrap;
+    /* padding: 0 5px; */
+  }
+
+  .selected-item {
+    flex-direction: row;
+    /* padding: 0 1px; */
+    /* #ifndef APP-NVUE */
+    white-space: nowrap;
+    /* #endif */
+  }
+
+  .text-color {
+    color: #333;
+  }
+
+  .placeholder {
+    color: grey;
+    font-size: 12px;
+  }
+
+  .input-split-line {
+    opacity: .5;
+  }
+
+  .arrow-area {
+    position: relative;
+    width: 20px;
+    /* #ifndef APP-NVUE */
+    margin-bottom: 5px;
+    margin-left: auto;
+    display: flex;
+    /* #endif */
+    justify-content: center;
+    transform: rotate(-45deg);
+    transform-origin: center;
+  }
+
+  .input-arrow {
+    width: 7px;
+    height: 7px;
+    border-left: 1px solid #999;
+    border-bottom: 1px solid #999;
+  }
+
+  .uni-data-tree-cover {
+    position: fixed;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, .4);
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    z-index: 100;
+  }
+
+  .uni-data-tree-dialog {
+    position: fixed;
+    left: 0;
+    /* #ifndef APP-NVUE */
+    top: 20%;
+    /* #endif */
+    /* #ifdef APP-NVUE */
+    top: 200px;
+    /* #endif */
+    right: 0;
+    bottom: 0;
+    background-color: #FFFFFF;
+    border-top-left-radius: 10px;
+    border-top-right-radius: 10px;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    z-index: 102;
+    overflow: hidden;
+    /* #ifdef APP-NVUE */
+    width: 750rpx;
+    /* #endif */
+  }
+
+  .dialog-caption {
+    position: relative;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    /* border-bottom: 1px solid #f0f0f0; */
+  }
+
+  .title-area {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    align-items: center;
+    /* #ifndef APP-NVUE */
+    margin: auto;
+    /* #endif */
+    padding: 0 10px;
+  }
+
+  .dialog-title {
+    /* font-weight: bold; */
+    line-height: 44px;
+  }
+
+  .dialog-close {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    align-items: center;
+    padding: 0 15px;
+  }
+
+  .dialog-close-plus {
+    width: 16px;
+    height: 2px;
+    background-color: #666;
+    border-radius: 2px;
+    transform: rotate(45deg);
+  }
+
+  .dialog-close-rotate {
+    position: absolute;
+    transform: rotate(-45deg);
+  }
+
+  .picker-view {
+    flex: 1;
+    overflow: hidden;
+  }
+
+  .icon-clear {
+    display: flex;
+    align-items: center;
+  }
+
+  /* #ifdef H5 */
+  @media all and (min-width: 768px) {
+    .uni-data-tree-cover {
+      background-color: transparent;
+    }
+
+    .uni-data-tree-dialog {
+      position: absolute;
+      top: 55px;
+      height: auto;
+      min-height: 400px;
+      max-height: 50vh;
+      background-color: #fff;
+      border: 1px solid #EBEEF5;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+      border-radius: 4px;
+      overflow: unset;
+    }
+
+    .dialog-caption {
+      display: none;
+    }
+
+    .icon-clear {
+      /* margin-right: 5px; */
+    }
+  }
+
+  /* #endif */
+
+  /* picker 弹出层通用的指示小三角, todo：扩展至上下左右方向定位 */
+  /* #ifndef APP-NVUE */
+  .uni-popper__arrow,
+  .uni-popper__arrow::after {
+    position: absolute;
+    display: block;
+    width: 0;
+    height: 0;
+    border-color: transparent;
+    border-style: solid;
+    border-width: 6px;
+  }
+
+  .uni-popper__arrow {
+    filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+    top: -6px;
+    left: 10%;
+    margin-right: 3px;
+    border-top-width: 0;
+    border-bottom-color: #EBEEF5;
+  }
+
+  .uni-popper__arrow::after {
+    content: " ";
+    top: 1px;
+    margin-left: -6px;
+    border-top-width: 0;
+    border-bottom-color: #fff;
+  }
+
+  /* #endif */
+</style>
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
index 4d9f95fb..cfae22a4 100644
--- a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
@@ -1,622 +1,622 @@
-export default {
-  props: {
-    localdata: {
-      type: [Array, Object],
-      default () {
-        return []
-      }
-    },
-    spaceInfo: {
-      type: Object,
-      default () {
-        return {}
-      }
-    },
-    collection: {
-      type: String,
-      default: ''
-    },
-    action: {
-      type: String,
-      default: ''
-    },
-    field: {
-      type: String,
-      default: ''
-    },
-    orderby: {
-      type: String,
-      default: ''
-    },
-    where: {
-      type: [String, Object],
-      default: ''
-    },
-    pageData: {
-      type: String,
-      default: 'add'
-    },
-    pageCurrent: {
-      type: Number,
-      default: 1
-    },
-    pageSize: {
-      type: Number,
-      default: 500
-    },
-    getcount: {
-      type: [Boolean, String],
-      default: false
-    },
-    getone: {
-      type: [Boolean, String],
-      default: false
-    },
-    gettree: {
-      type: [Boolean, String],
-      default: false
-    },
-    manual: {
-      type: Boolean,
-      default: false
-    },
-    value: {
-      type: [Array, String, Number],
-      default () {
-        return []
-      }
-    },
-    modelValue: {
-      type: [Array, String, Number],
-      default () {
-        return []
-      }
-    },
-    preload: {
-      type: Boolean,
-      default: false
-    },
-    stepSearh: {
-      type: Boolean,
-      default: true
-    },
-    selfField: {
-      type: String,
-      default: ''
-    },
-    parentField: {
-      type: String,
-      default: ''
-    },
-    multiple: {
-      type: Boolean,
-      default: false
-    },
-    map: {
-      type: Object,
-      default () {
-        return {
-          text: "text",
-          value: "value"
-        }
-      }
-    }
-  },
-  data() {
-    return {
-      loading: false,
-      errorMessage: '',
-      loadMore: {
-        contentdown: '',
-        contentrefresh: '',
-        contentnomore: ''
-      },
-      dataList: [],
-      selected: [],
-      selectedIndex: 0,
-      page: {
-        current: this.pageCurrent,
-        size: this.pageSize,
-        count: 0
-      }
-    }
-  },
-  computed: {
-    isLocalData() {
-      return !this.collection.length;
-    },
-    isCloudData() {
-      return this.collection.length > 0;
-    },
-    isCloudDataList() {
-      return (this.isCloudData && (!this.parentField && !this.selfField));
-    },
-    isCloudDataTree() {
-      return (this.isCloudData && this.parentField && this.selfField);
-    },
-    dataValue() {
-      let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null ||
-        this.modelValue !== undefined);
-      return isModelValue ? this.modelValue : this.value;
-    },
-    hasValue() {
-      if (typeof this.dataValue === 'number') {
-        return true
-      }
-      return (this.dataValue != null) && (this.dataValue.length > 0)
-    }
-  },
-  created() {
-    this.$watch(() => {
-      var al = [];
-      ['pageCurrent',
-        'pageSize',
-        'spaceInfo',
-        'value',
-        'modelValue',
-        'localdata',
-        'collection',
-        'action',
-        'field',
-        'orderby',
-        'where',
-        'getont',
-        'getcount',
-        'gettree'
-      ].forEach(key => {
-        al.push(this[key])
-      });
-      return al
-    }, (newValue, oldValue) => {
-      let needReset = false
-      for (let i = 2; i < newValue.length; i++) {
-        if (newValue[i] != oldValue[i]) {
-          needReset = true
-          break
-        }
-      }
-      if (newValue[0] != oldValue[0]) {
-        this.page.current = this.pageCurrent
-      }
-      this.page.size = this.pageSize
-
-      this.onPropsChange()
-    })
-    this._treeData = []
-  },
-  methods: {
-    onPropsChange() {
-      this._treeData = [];
-    },
-
-    // 填充 pickview 数据
-    async loadData() {
-      if (this.isLocalData) {
-        this.loadLocalData();
-      } else if (this.isCloudDataList) {
-        this.loadCloudDataList();
-      } else if (this.isCloudDataTree) {
-        this.loadCloudDataTree();
-      }
-    },
-
-    // 加载本地数据
-    async loadLocalData() {
-      this._treeData = [];
-      this._extractTree(this.localdata, this._treeData);
-
-      let inputValue = this.dataValue;
-      if (inputValue === undefined) {
-        return;
-      }
-
-      if (Array.isArray(inputValue)) {
-        inputValue = inputValue[inputValue.length - 1];
-        if (typeof inputValue === 'object' && inputValue[this.map.value]) {
-          inputValue = inputValue[this.map.value];
-        }
-      }
-
-      this.selected = this._findNodePath(inputValue, this.localdata);
-    },
-
-    // 加载 Cloud 数据 (单列)
-    async loadCloudDataList() {
-      if (this.loading) {
-        return;
-      }
-      this.loading = true;
-
-      try {
-        let response = await this.getCommand();
-        let responseData = response.result.data;
-
-        this._treeData = responseData;
-
-        this._updateBindData();
-        this._updateSelected();
-
-        this.onDataChange();
-      } catch (e) {
-        this.errorMessage = e;
-      } finally {
-        this.loading = false;
-      }
-    },
-
-    // 加载 Cloud 数据 (树形)
-    async loadCloudDataTree() {
-      if (this.loading) {
-        return;
-      }
-      this.loading = true;
-
-      try {
-        let commandOptions = {
-          field: this._cloudDataPostField(),
-          where: this._cloudDataTreeWhere()
-        };
-        if (this.gettree) {
-          commandOptions.startwith = `${this.selfField}=='${this.dataValue}'`;
-        }
-
-        let response = await this.getCommand(commandOptions);
-        let responseData = response.result.data;
-
-        this._treeData = responseData;
-        this._updateBindData();
-        this._updateSelected();
-
-        this.onDataChange();
-      } catch (e) {
-        this.errorMessage = e;
-      } finally {
-        this.loading = false;
-      }
-    },
-
-    // 加载 Cloud 数据 (节点)
-    async loadCloudDataNode(callback) {
-      if (this.loading) {
-        return;
-      }
-      this.loading = true;
-
-      try {
-        let commandOptions = {
-          field: this._cloudDataPostField(),
-          where: this._cloudDataNodeWhere()
-        };
-
-        let response = await this.getCommand(commandOptions);
-        let responseData = response.result.data;
-
-        callback(responseData);
-      } catch (e) {
-        this.errorMessage = e;
-      } finally {
-        this.loading = false;
-      }
-    },
-
-    // 回显 Cloud 数据
-    getCloudDataValue() {
-      if (this.isCloudDataList) {
-        return this.getCloudDataListValue();
-      }
-
-      if (this.isCloudDataTree) {
-        return this.getCloudDataTreeValue();
-      }
-    },
-
-    // 回显 Cloud 数据 (单列)
-    getCloudDataListValue() {
-      // 根据 field's as value标识匹配 where 条件
-      let where = [];
-      let whereField = this._getForeignKeyByField();
-      if (whereField) {
-        where.push(`${whereField} == '${this.dataValue}'`)
-      }
-
-      where = where.join(' || ');
-
-      if (this.where) {
-        where = `(${this.where}) && (${where})`
-      }
-
-      return this.getCommand({
-        field: this._cloudDataPostField(),
-        where
-      }).then((res) => {
-        this.selected = res.result.data;
-        return res.result.data;
-      });
-    },
-
-    // 回显 Cloud 数据 (树形)
-    getCloudDataTreeValue() {
-      return this.getCommand({
-        field: this._cloudDataPostField(),
-        getTreePath: {
-          startWith: `${this.selfField}=='${this.dataValue}'`
-        }
-      }).then((res) => {
-        let treePath = [];
-        this._extractTreePath(res.result.data, treePath);
-        this.selected = treePath;
-        return treePath;
-      });
-    },
-
-    getCommand(options = {}) {
-      /* eslint-disable no-undef */
-      let db = uniCloud.database(this.spaceInfo)
-
-      const action = options.action || this.action
-      if (action) {
-        db = db.action(action)
-      }
-
-      const collection = options.collection || this.collection
-      db = db.collection(collection)
-
-      const where = options.where || this.where
-      if (!(!where || !Object.keys(where).length)) {
-        db = db.where(where)
-      }
-
-      const field = options.field || this.field
-      if (field) {
-        db = db.field(field)
-      }
-
-      const orderby = options.orderby || this.orderby
-      if (orderby) {
-        db = db.orderBy(orderby)
-      }
-
-      const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
-      const size = options.pageSize !== undefined ? options.pageSize : this.page.size
-      const getCount = options.getcount !== undefined ? options.getcount : this.getcount
-      const getTree = options.gettree !== undefined ? options.gettree : this.gettree
-
-      const getOptions = {
-        getCount,
-        getTree
-      }
-      if (options.getTreePath) {
-        getOptions.getTreePath = options.getTreePath
-      }
-
-      db = db.skip(size * (current - 1)).limit(size).get(getOptions)
-
-      return db
-    },
-
-    _cloudDataPostField() {
-      let fields = [this.field];
-      if (this.parentField) {
-        fields.push(`${this.parentField} as parent_value`);
-      }
-      return fields.join(',');
-    },
-
-    _cloudDataTreeWhere() {
-      let result = []
-      let selected = this.selected
-      let parentField = this.parentField
-      if (parentField) {
-        result.push(`${parentField} == null || ${parentField} == ""`)
-      }
-      if (selected.length) {
-        for (var i = 0; i < selected.length - 1; i++) {
-          result.push(`${parentField} == '${selected[i].value}'`)
-        }
-      }
-
-      let where = []
-      if (this.where) {
-        where.push(`(${this.where})`)
-      }
-
-      if (result.length) {
-        where.push(`(${result.join(' || ')})`)
-      }
-
-      return where.join(' && ')
-    },
-
-    _cloudDataNodeWhere() {
-      let where = []
-      let selected = this.selected;
-      if (selected.length) {
-        where.push(`${this.parentField} == '${selected[selected.length - 1].value}'`);
-      }
-
-      where = where.join(' || ');
-
-      if (this.where) {
-        return `(${this.where}) && (${where})`
-      }
-
-      return where
-    },
-
-    _getWhereByForeignKey() {
-      let result = []
-      let whereField = this._getForeignKeyByField();
-      if (whereField) {
-        result.push(`${whereField} == '${this.dataValue}'`)
-      }
-
-      if (this.where) {
-        return `(${this.where}) && (${result.join(' || ')})`
-      }
-
-      return result.join(' || ')
-    },
-
-    _getForeignKeyByField() {
-      let fields = this.field.split(',');
-      let whereField = null;
-      for (let i = 0; i < fields.length; i++) {
-        const items = fields[i].split('as');
-        if (items.length < 2) {
-          continue;
-        }
-        if (items[1].trim() === 'value') {
-          whereField = items[0].trim();
-          break;
-        }
-      }
-      return whereField;
-    },
-
-    _updateBindData(node) {
-      const {
-        dataList,
-        hasNodes
-      } = this._filterData(this._treeData, this.selected)
-
-      let isleaf = this._stepSearh === false && !hasNodes
-
-      if (node) {
-        node.isleaf = isleaf
-      }
-
-      this.dataList = dataList
-      this.selectedIndex = dataList.length - 1
-
-      if (!isleaf && this.selected.length < dataList.length) {
-        this.selected.push({
-          value: null,
-          text: "请选择"
-        })
-      }
-
-      return {
-        isleaf,
-        hasNodes
-      }
-    },
-
-    _updateSelected() {
-      let dl = this.dataList
-      let sl = this.selected
-      let textField = this.map.text
-      let valueField = this.map.value
-      for (let i = 0; i < sl.length; i++) {
-        let value = sl[i].value
-        let dl2 = dl[i]
-        for (let j = 0; j < dl2.length; j++) {
-          let item2 = dl2[j]
-          if (item2[valueField] === value) {
-            sl[i].text = item2[textField]
-            break
-          }
-        }
-      }
-    },
-
-    _filterData(data, paths) {
-      let dataList = []
-      let hasNodes = true
-
-      dataList.push(data.filter((item) => {
-        return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
-      }))
-      for (let i = 0; i < paths.length; i++) {
-        let value = paths[i].value
-        let nodes = data.filter((item) => {
-          return item.parent_value === value
-        })
-
-        if (nodes.length) {
-          dataList.push(nodes)
-        } else {
-          hasNodes = false
-        }
-      }
-
-      return {
-        dataList,
-        hasNodes
-      }
-    },
-
-    _extractTree(nodes, result, parent_value) {
-      let list = result || []
-      let valueField = this.map.value
-      for (let i = 0; i < nodes.length; i++) {
-        let node = nodes[i]
-
-        let child = {}
-        for (let key in node) {
-          if (key !== 'children') {
-            child[key] = node[key]
-          }
-        }
-        if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
-          child.parent_value = parent_value
-        }
-        result.push(child)
-
-        let children = node.children
-        if (children) {
-          this._extractTree(children, result, node[valueField])
-        }
-      }
-    },
-
-    _extractTreePath(nodes, result) {
-      let list = result || []
-      for (let i = 0; i < nodes.length; i++) {
-        let node = nodes[i]
-
-        let child = {}
-        for (let key in node) {
-          if (key !== 'children') {
-            child[key] = node[key]
-          }
-        }
-        result.push(child)
-
-        let children = node.children
-        if (children) {
-          this._extractTreePath(children, result)
-        }
-      }
-    },
-
-    _findNodePath(key, nodes, path = []) {
-      let textField = this.map.text
-      let valueField = this.map.value
-      for (let i = 0; i < nodes.length; i++) {
-        let node = nodes[i]
-        let children = node.children
-        let text = node[textField]
-        let value = node[valueField]
-
-        path.push({
-          value,
-          text
-        })
-
-        if (value === key) {
-          return path
-        }
-
-        if (children) {
-          const p = this._findNodePath(key, children, path)
-          if (p.length) {
-            return p
-          }
-        }
-
-        path.pop()
-      }
-      return []
-    }
-  }
-}
+export default {
+  props: {
+    localdata: {
+      type: [Array, Object],
+      default () {
+        return []
+      }
+    },
+    spaceInfo: {
+      type: Object,
+      default () {
+        return {}
+      }
+    },
+    collection: {
+      type: String,
+      default: ''
+    },
+    action: {
+      type: String,
+      default: ''
+    },
+    field: {
+      type: String,
+      default: ''
+    },
+    orderby: {
+      type: String,
+      default: ''
+    },
+    where: {
+      type: [String, Object],
+      default: ''
+    },
+    pageData: {
+      type: String,
+      default: 'add'
+    },
+    pageCurrent: {
+      type: Number,
+      default: 1
+    },
+    pageSize: {
+      type: Number,
+      default: 500
+    },
+    getcount: {
+      type: [Boolean, String],
+      default: false
+    },
+    getone: {
+      type: [Boolean, String],
+      default: false
+    },
+    gettree: {
+      type: [Boolean, String],
+      default: false
+    },
+    manual: {
+      type: Boolean,
+      default: false
+    },
+    value: {
+      type: [Array, String, Number],
+      default () {
+        return []
+      }
+    },
+    modelValue: {
+      type: [Array, String, Number],
+      default () {
+        return []
+      }
+    },
+    preload: {
+      type: Boolean,
+      default: false
+    },
+    stepSearh: {
+      type: Boolean,
+      default: true
+    },
+    selfField: {
+      type: String,
+      default: ''
+    },
+    parentField: {
+      type: String,
+      default: ''
+    },
+    multiple: {
+      type: Boolean,
+      default: false
+    },
+    map: {
+      type: Object,
+      default () {
+        return {
+          text: "text",
+          value: "value"
+        }
+      }
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      errorMessage: '',
+      loadMore: {
+        contentdown: '',
+        contentrefresh: '',
+        contentnomore: ''
+      },
+      dataList: [],
+      selected: [],
+      selectedIndex: 0,
+      page: {
+        current: this.pageCurrent,
+        size: this.pageSize,
+        count: 0
+      }
+    }
+  },
+  computed: {
+    isLocalData() {
+      return !this.collection.length;
+    },
+    isCloudData() {
+      return this.collection.length > 0;
+    },
+    isCloudDataList() {
+      return (this.isCloudData && (!this.parentField && !this.selfField));
+    },
+    isCloudDataTree() {
+      return (this.isCloudData && this.parentField && this.selfField);
+    },
+    dataValue() {
+      let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null ||
+        this.modelValue !== undefined);
+      return isModelValue ? this.modelValue : this.value;
+    },
+    hasValue() {
+      if (typeof this.dataValue === 'number') {
+        return true
+      }
+      return (this.dataValue != null) && (this.dataValue.length > 0)
+    }
+  },
+  created() {
+    this.$watch(() => {
+      var al = [];
+      ['pageCurrent',
+        'pageSize',
+        'spaceInfo',
+        'value',
+        'modelValue',
+        'localdata',
+        'collection',
+        'action',
+        'field',
+        'orderby',
+        'where',
+        'getont',
+        'getcount',
+        'gettree'
+      ].forEach(key => {
+        al.push(this[key])
+      });
+      return al
+    }, (newValue, oldValue) => {
+      let needReset = false
+      for (let i = 2; i < newValue.length; i++) {
+        if (newValue[i] != oldValue[i]) {
+          needReset = true
+          break
+        }
+      }
+      if (newValue[0] != oldValue[0]) {
+        this.page.current = this.pageCurrent
+      }
+      this.page.size = this.pageSize
+
+      this.onPropsChange()
+    })
+    this._treeData = []
+  },
+  methods: {
+    onPropsChange() {
+      this._treeData = [];
+    },
+
+    // 填充 pickview 数据
+    async loadData() {
+      if (this.isLocalData) {
+        this.loadLocalData();
+      } else if (this.isCloudDataList) {
+        this.loadCloudDataList();
+      } else if (this.isCloudDataTree) {
+        this.loadCloudDataTree();
+      }
+    },
+
+    // 加载本地数据
+    async loadLocalData() {
+      this._treeData = [];
+      this._extractTree(this.localdata, this._treeData);
+
+      let inputValue = this.dataValue;
+      if (inputValue === undefined) {
+        return;
+      }
+
+      if (Array.isArray(inputValue)) {
+        inputValue = inputValue[inputValue.length - 1];
+        if (typeof inputValue === 'object' && inputValue[this.map.value]) {
+          inputValue = inputValue[this.map.value];
+        }
+      }
+
+      this.selected = this._findNodePath(inputValue, this.localdata);
+    },
+
+    // 加载 Cloud 数据 (单列)
+    async loadCloudDataList() {
+      if (this.loading) {
+        return;
+      }
+      this.loading = true;
+
+      try {
+        let response = await this.getCommand();
+        let responseData = response.result.data;
+
+        this._treeData = responseData;
+
+        this._updateBindData();
+        this._updateSelected();
+
+        this.onDataChange();
+      } catch (e) {
+        this.errorMessage = e;
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 加载 Cloud 数据 (树形)
+    async loadCloudDataTree() {
+      if (this.loading) {
+        return;
+      }
+      this.loading = true;
+
+      try {
+        let commandOptions = {
+          field: this._cloudDataPostField(),
+          where: this._cloudDataTreeWhere()
+        };
+        if (this.gettree) {
+          commandOptions.startwith = `${this.selfField}=='${this.dataValue}'`;
+        }
+
+        let response = await this.getCommand(commandOptions);
+        let responseData = response.result.data;
+
+        this._treeData = responseData;
+        this._updateBindData();
+        this._updateSelected();
+
+        this.onDataChange();
+      } catch (e) {
+        this.errorMessage = e;
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 加载 Cloud 数据 (节点)
+    async loadCloudDataNode(callback) {
+      if (this.loading) {
+        return;
+      }
+      this.loading = true;
+
+      try {
+        let commandOptions = {
+          field: this._cloudDataPostField(),
+          where: this._cloudDataNodeWhere()
+        };
+
+        let response = await this.getCommand(commandOptions);
+        let responseData = response.result.data;
+
+        callback(responseData);
+      } catch (e) {
+        this.errorMessage = e;
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 回显 Cloud 数据
+    getCloudDataValue() {
+      if (this.isCloudDataList) {
+        return this.getCloudDataListValue();
+      }
+
+      if (this.isCloudDataTree) {
+        return this.getCloudDataTreeValue();
+      }
+    },
+
+    // 回显 Cloud 数据 (单列)
+    getCloudDataListValue() {
+      // 根据 field's as value标识匹配 where 条件
+      let where = [];
+      let whereField = this._getForeignKeyByField();
+      if (whereField) {
+        where.push(`${whereField} == '${this.dataValue}'`)
+      }
+
+      where = where.join(' || ');
+
+      if (this.where) {
+        where = `(${this.where}) && (${where})`
+      }
+
+      return this.getCommand({
+        field: this._cloudDataPostField(),
+        where
+      }).then((res) => {
+        this.selected = res.result.data;
+        return res.result.data;
+      });
+    },
+
+    // 回显 Cloud 数据 (树形)
+    getCloudDataTreeValue() {
+      return this.getCommand({
+        field: this._cloudDataPostField(),
+        getTreePath: {
+          startWith: `${this.selfField}=='${this.dataValue}'`
+        }
+      }).then((res) => {
+        let treePath = [];
+        this._extractTreePath(res.result.data, treePath);
+        this.selected = treePath;
+        return treePath;
+      });
+    },
+
+    getCommand(options = {}) {
+      /* eslint-disable no-undef */
+      let db = uniCloud.database(this.spaceInfo)
+
+      const action = options.action || this.action
+      if (action) {
+        db = db.action(action)
+      }
+
+      const collection = options.collection || this.collection
+      db = db.collection(collection)
+
+      const where = options.where || this.where
+      if (!(!where || !Object.keys(where).length)) {
+        db = db.where(where)
+      }
+
+      const field = options.field || this.field
+      if (field) {
+        db = db.field(field)
+      }
+
+      const orderby = options.orderby || this.orderby
+      if (orderby) {
+        db = db.orderBy(orderby)
+      }
+
+      const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
+      const size = options.pageSize !== undefined ? options.pageSize : this.page.size
+      const getCount = options.getcount !== undefined ? options.getcount : this.getcount
+      const getTree = options.gettree !== undefined ? options.gettree : this.gettree
+
+      const getOptions = {
+        getCount,
+        getTree
+      }
+      if (options.getTreePath) {
+        getOptions.getTreePath = options.getTreePath
+      }
+
+      db = db.skip(size * (current - 1)).limit(size).get(getOptions)
+
+      return db
+    },
+
+    _cloudDataPostField() {
+      let fields = [this.field];
+      if (this.parentField) {
+        fields.push(`${this.parentField} as parent_value`);
+      }
+      return fields.join(',');
+    },
+
+    _cloudDataTreeWhere() {
+      let result = []
+      let selected = this.selected
+      let parentField = this.parentField
+      if (parentField) {
+        result.push(`${parentField} == null || ${parentField} == ""`)
+      }
+      if (selected.length) {
+        for (var i = 0; i < selected.length - 1; i++) {
+          result.push(`${parentField} == '${selected[i].value}'`)
+        }
+      }
+
+      let where = []
+      if (this.where) {
+        where.push(`(${this.where})`)
+      }
+
+      if (result.length) {
+        where.push(`(${result.join(' || ')})`)
+      }
+
+      return where.join(' && ')
+    },
+
+    _cloudDataNodeWhere() {
+      let where = []
+      let selected = this.selected;
+      if (selected.length) {
+        where.push(`${this.parentField} == '${selected[selected.length - 1].value}'`);
+      }
+
+      where = where.join(' || ');
+
+      if (this.where) {
+        return `(${this.where}) && (${where})`
+      }
+
+      return where
+    },
+
+    _getWhereByForeignKey() {
+      let result = []
+      let whereField = this._getForeignKeyByField();
+      if (whereField) {
+        result.push(`${whereField} == '${this.dataValue}'`)
+      }
+
+      if (this.where) {
+        return `(${this.where}) && (${result.join(' || ')})`
+      }
+
+      return result.join(' || ')
+    },
+
+    _getForeignKeyByField() {
+      let fields = this.field.split(',');
+      let whereField = null;
+      for (let i = 0; i < fields.length; i++) {
+        const items = fields[i].split('as');
+        if (items.length < 2) {
+          continue;
+        }
+        if (items[1].trim() === 'value') {
+          whereField = items[0].trim();
+          break;
+        }
+      }
+      return whereField;
+    },
+
+    _updateBindData(node) {
+      const {
+        dataList,
+        hasNodes
+      } = this._filterData(this._treeData, this.selected)
+
+      let isleaf = this._stepSearh === false && !hasNodes
+
+      if (node) {
+        node.isleaf = isleaf
+      }
+
+      this.dataList = dataList
+      this.selectedIndex = dataList.length - 1
+
+      if (!isleaf && this.selected.length < dataList.length) {
+        this.selected.push({
+          value: null,
+          text: "请选择"
+        })
+      }
+
+      return {
+        isleaf,
+        hasNodes
+      }
+    },
+
+    _updateSelected() {
+      let dl = this.dataList
+      let sl = this.selected
+      let textField = this.map.text
+      let valueField = this.map.value
+      for (let i = 0; i < sl.length; i++) {
+        let value = sl[i].value
+        let dl2 = dl[i]
+        for (let j = 0; j < dl2.length; j++) {
+          let item2 = dl2[j]
+          if (item2[valueField] === value) {
+            sl[i].text = item2[textField]
+            break
+          }
+        }
+      }
+    },
+
+    _filterData(data, paths) {
+      let dataList = []
+      let hasNodes = true
+
+      dataList.push(data.filter((item) => {
+        return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
+      }))
+      for (let i = 0; i < paths.length; i++) {
+        let value = paths[i].value
+        let nodes = data.filter((item) => {
+          return item.parent_value === value
+        })
+
+        if (nodes.length) {
+          dataList.push(nodes)
+        } else {
+          hasNodes = false
+        }
+      }
+
+      return {
+        dataList,
+        hasNodes
+      }
+    },
+
+    _extractTree(nodes, result, parent_value) {
+      let list = result || []
+      let valueField = this.map.value
+      for (let i = 0; i < nodes.length; i++) {
+        let node = nodes[i]
+
+        let child = {}
+        for (let key in node) {
+          if (key !== 'children') {
+            child[key] = node[key]
+          }
+        }
+        if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
+          child.parent_value = parent_value
+        }
+        result.push(child)
+
+        let children = node.children
+        if (children) {
+          this._extractTree(children, result, node[valueField])
+        }
+      }
+    },
+
+    _extractTreePath(nodes, result) {
+      let list = result || []
+      for (let i = 0; i < nodes.length; i++) {
+        let node = nodes[i]
+
+        let child = {}
+        for (let key in node) {
+          if (key !== 'children') {
+            child[key] = node[key]
+          }
+        }
+        result.push(child)
+
+        let children = node.children
+        if (children) {
+          this._extractTreePath(children, result)
+        }
+      }
+    },
+
+    _findNodePath(key, nodes, path = []) {
+      let textField = this.map.text
+      let valueField = this.map.value
+      for (let i = 0; i < nodes.length; i++) {
+        let node = nodes[i]
+        let children = node.children
+        let text = node[textField]
+        let value = node[valueField]
+
+        path.push({
+          value,
+          text
+        })
+
+        if (value === key) {
+          return path
+        }
+
+        if (children) {
+          const p = this._findNodePath(key, children, path)
+          if (p.length) {
+            return p
+          }
+        }
+
+        path.pop()
+      }
+      return []
+    }
+  }
+}
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
index 1c78a40e..857408de 100644
--- a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
@@ -1,693 +1,692 @@
-export type PaginationType = {
-  current : number,
-  size : number,
-  count : number
-}
-
-export type LoadMoreType = {
-  contentdown : string,
-  contentrefresh : string,
-  contentnomore : string
-}
-
-export type SelectedItemType = {
-  name : string,
-  value : string,
-}
-
-export type GetCommandOptions = {
-  collection ?: UTSJSONObject,
-  field ?: string,
-  orderby ?: string,
-  where ?: any,
-  pageData ?: string,
-  pageCurrent ?: number,
-  pageSize ?: number,
-  getCount ?: boolean,
-  getTree ?: any,
-  getTreePath ?: UTSJSONObject,
-  startwith ?: string,
-  limitlevel ?: number,
-  groupby ?: string,
-  groupField ?: string,
-  distinct ?: boolean,
-  pageIndistinct ?: boolean,
-  foreignKey ?: string,
-  loadtime ?: string,
-  manual ?: boolean
-}
-
-const DefaultSelectedNode = {
-  text: '请选择',
-  value: ''
-}
-
-export const dataPicker = defineMixin({
-  props: {
-    localdata: {
-      type: Array as PropType<Array<UTSJSONObject>>,
-      default: [] as Array<UTSJSONObject>
-    },
-    collection: {
-      type: Object,
-      default: ''
-    },
-    field: {
-      type: String,
-      default: ''
-    },
-    orderby: {
-      type: String,
-      default: ''
-    },
-    where: {
-      type: Object,
-      default: ''
-    },
-    pageData: {
-      type: String,
-      default: 'add'
-    },
-    pageCurrent: {
-      type: Number,
-      default: 1
-    },
-    pageSize: {
-      type: Number,
-      default: 20
-    },
-    getcount: {
-      type: Boolean,
-      default: false
-    },
-    gettree: {
-      type: Object,
-      default: ''
-    },
-    gettreepath: {
-      type: Object,
-      default: ''
-    },
-    startwith: {
-      type: String,
-      default: ''
-    },
-    limitlevel: {
-      type: Number,
-      default: 10
-    },
-    groupby: {
-      type: String,
-      default: ''
-    },
-    groupField: {
-      type: String,
-      default: ''
-    },
-    distinct: {
-      type: Boolean,
-      default: false
-    },
-    pageIndistinct: {
-      type: Boolean,
-      default: false
-    },
-    foreignKey: {
-      type: String,
-      default: ''
-    },
-    loadtime: {
-      type: String,
-      default: 'auto'
-    },
-    manual: {
-      type: Boolean,
-      default: false
-    },
-    preload: {
-      type: Boolean,
-      default: false
-    },
-    stepSearh: {
-      type: Boolean,
-      default: true
-    },
-    selfField: {
-      type: String,
-      default: ''
-    },
-    parentField: {
-      type: String,
-      default: ''
-    },
-    multiple: {
-      type: Boolean,
-      default: false
-    },
-    value: {
-      type: Object,
-      default: ''
-    },
-    modelValue: {
-      type: Object,
-      default: ''
-    },
-    defaultProps: {
-      type: Object as PropType<UTSJSONObject>,
-    }
-  },
-  data() {
-    return {
-      loading: false,
-      error: null as UniCloudError | null,
-      treeData: [] as Array<UTSJSONObject>,
-      selectedIndex: 0,
-      selectedNodes: [] as Array<UTSJSONObject>,
-      selectedPages: [] as Array<UTSJSONObject>[],
-      selectedValue: '',
-      selectedPaths: [] as Array<UTSJSONObject>,
-      pagination: {
-        current: 1,
-        size: 20,
-        count: 0
-      } as PaginationType
-    }
-  },
-  computed: {
-    mappingTextName() : string {
-      // TODO
-      return (this.defaultProps != null) ? this.defaultProps!.getString('text', 'text') : 'text'
-    },
-    mappingValueName() : string {
-      // TODO
-      return (this.defaultProps != null) ? this.defaultProps!.getString('value', 'value') : 'value'
-    },
-    currentDataList() : Array<UTSJSONObject> {
-      if (this.selectedIndex > this.selectedPages.length - 1) {
-        return [] as Array<UTSJSONObject>
-      }
-      return this.selectedPages[this.selectedIndex]
-    },
-    isLocalData() : boolean {
-      return this.localdata.length > 0
-    },
-    isCloudData() : boolean {
-      return this._checkIsNotNull(this.collection)
-    },
-    isCloudDataList() : boolean {
-      return (this.isCloudData && (this.parentField.length == 0 && this.selfField.length == 0))
-    },
-    isCloudDataTree() : boolean {
-      return (this.isCloudData && this.parentField.length > 0 && this.selfField.length > 0)
-    },
-    dataValue() : any {
-      return this.hasModelValue ? this.modelValue : this.value
-    },
-    hasCloudTreeData() : boolean {
-      return this.treeData.length > 0
-    },
-    hasModelValue() : boolean {
-      if (typeof this.modelValue == 'string') {
-        const valueString = this.modelValue as string
-        return (valueString.length > 0)
-      } else if (Array.isArray(this.modelValue)) {
-        const valueArray = this.modelValue as Array<string>
-        return (valueArray.length > 0)
-      }
-      return false
-    },
-    hasCloudDataValue() : boolean {
-      if (typeof this.dataValue == 'string') {
-        const valueString = this.dataValue as string
-        return (valueString.length > 0)
-      }
-      return false
-    }
-  },
-  created() {
-    this.pagination.current = this.pageCurrent
-    this.pagination.size = this.pageSize
-
-    this.$watch(
-      () : any => [
-        this.pageCurrent,
-        this.pageSize,
+export type PaginationType = {
+  current : number,
+  size : number,
+  count : number
+}
+
+export type LoadMoreType = {
+  contentdown : string,
+  contentrefresh : string,
+  contentnomore : string
+}
+
+export type SelectedItemType = {
+  name : string,
+  value : string,
+}
+
+export type GetCommandOptions = {
+  collection ?: UTSJSONObject,
+  field ?: string,
+  orderby ?: string,
+  where ?: any,
+  pageData ?: string,
+  pageCurrent ?: number,
+  pageSize ?: number,
+  getCount ?: boolean,
+  getTree ?: any,
+  getTreePath ?: UTSJSONObject,
+  startwith ?: string,
+  limitlevel ?: number,
+  groupby ?: string,
+  groupField ?: string,
+  distinct ?: boolean,
+  pageIndistinct ?: boolean,
+  foreignKey ?: string,
+  loadtime ?: string,
+  manual ?: boolean
+}
+
+const DefaultSelectedNode = {
+  text: '请选择',
+  value: ''
+}
+
+export const dataPicker = defineMixin({
+  props: {
+    localdata: {
+      type: Array as PropType<Array<UTSJSONObject>>,
+      default: [] as Array<UTSJSONObject>
+    },
+    collection: {
+      type: Object,
+      default: ''
+    },
+    field: {
+      type: String,
+      default: ''
+    },
+    orderby: {
+      type: String,
+      default: ''
+    },
+    where: {
+      type: Object,
+      default: ''
+    },
+    pageData: {
+      type: String,
+      default: 'add'
+    },
+    pageCurrent: {
+      type: Number,
+      default: 1
+    },
+    pageSize: {
+      type: Number,
+      default: 20
+    },
+    getcount: {
+      type: Boolean,
+      default: false
+    },
+    gettree: {
+      type: Object,
+      default: ''
+    },
+    gettreepath: {
+      type: Object,
+      default: ''
+    },
+    startwith: {
+      type: String,
+      default: ''
+    },
+    limitlevel: {
+      type: Number,
+      default: 10
+    },
+    groupby: {
+      type: String,
+      default: ''
+    },
+    groupField: {
+      type: String,
+      default: ''
+    },
+    distinct: {
+      type: Boolean,
+      default: false
+    },
+    pageIndistinct: {
+      type: Boolean,
+      default: false
+    },
+    foreignKey: {
+      type: String,
+      default: ''
+    },
+    loadtime: {
+      type: String,
+      default: 'auto'
+    },
+    manual: {
+      type: Boolean,
+      default: false
+    },
+    preload: {
+      type: Boolean,
+      default: false
+    },
+    stepSearh: {
+      type: Boolean,
+      default: true
+    },
+    selfField: {
+      type: String,
+      default: ''
+    },
+    parentField: {
+      type: String,
+      default: ''
+    },
+    multiple: {
+      type: Boolean,
+      default: false
+    },
+    value: {
+      type: Object,
+      default: ''
+    },
+    modelValue: {
+      type: Object,
+      default: ''
+    },
+    defaultProps: {
+      type: Object as PropType<UTSJSONObject>,
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      error: null as UniCloudError | null,
+      treeData: [] as Array<UTSJSONObject>,
+      selectedIndex: 0,
+      selectedNodes: [] as Array<UTSJSONObject>,
+      selectedPages: [] as Array<UTSJSONObject>[],
+      selectedValue: '',
+      selectedPaths: [] as Array<UTSJSONObject>,
+      pagination: {
+        current: 1,
+        size: 20,
+        count: 0
+      } as PaginationType
+    }
+  },
+  computed: {
+    mappingTextName() : string {
+      // TODO
+      return (this.defaultProps != null) ? this.defaultProps!.getString('text', 'text') : 'text'
+    },
+    mappingValueName() : string {
+      // TODO
+      return (this.defaultProps != null) ? this.defaultProps!.getString('value', 'value') : 'value'
+    },
+    currentDataList() : Array<UTSJSONObject> {
+      if (this.selectedIndex > this.selectedPages.length - 1) {
+        return [] as Array<UTSJSONObject>
+      }
+      return this.selectedPages[this.selectedIndex]
+    },
+    isLocalData() : boolean {
+      return this.localdata.length > 0
+    },
+    isCloudData() : boolean {
+      return this._checkIsNotNull(this.collection)
+    },
+    isCloudDataList() : boolean {
+      return (this.isCloudData && (this.parentField.length == 0 && this.selfField.length == 0))
+    },
+    isCloudDataTree() : boolean {
+      return (this.isCloudData && this.parentField.length > 0 && this.selfField.length > 0)
+    },
+    dataValue() : any {
+      return this.hasModelValue ? this.modelValue : this.value
+    },
+    hasCloudTreeData() : boolean {
+      return this.treeData.length > 0
+    },
+    hasModelValue() : boolean {
+      if (typeof this.modelValue == 'string') {
+        const valueString = this.modelValue as string
+        return (valueString.length > 0)
+      } else if (Array.isArray(this.modelValue)) {
+        const valueArray = this.modelValue as Array<string>
+        return (valueArray.length > 0)
+      }
+      return false
+    },
+    hasCloudDataValue() : boolean {
+      if (typeof this.dataValue == 'string') {
+        const valueString = this.dataValue as string
+        return (valueString.length > 0)
+      }
+      return false
+    }
+  },
+  created() {
+    this.pagination.current = this.pageCurrent
+    this.pagination.size = this.pageSize
+
+    this.$watch(
+      () : any => [
+        this.pageCurrent,
+        this.pageSize,
         this.localdata,
-        this.value,
-        this.collection,
-        this.field,
-        this.getcount,
-        this.orderby,
-        this.where,
-        this.groupby,
-        this.groupField,
-        this.distinct
-      ],
-      (newValue : Array<any>, oldValue : Array<any>) => {
-        this.pagination.size = this.pageSize
-        if (newValue[0] !== oldValue[0]) {
-          this.pagination.current = this.pageCurrent
-        }
-
-        this.onPropsChange()
-      }
-    )
-  },
-  methods: {
-    onPropsChange() {
-      this.selectedIndex = 0
-      this.treeData.length = 0
-      this.selectedNodes.length = 0
-      this.selectedPages.length = 0
-      this.selectedPaths.length = 0
-
-      // 加载数据
-      this.$nextTick(() => {
-        this.loadData()
-      })
-    },
-
-    onTabSelect(index : number) {
-      this.selectedIndex = index
-    },
-
-    onNodeClick(nodeData : UTSJSONObject) {
-      if (nodeData.getBoolean('disable', false)) {
-        return
-      }
-
-      const isLeaf = this._checkIsLeafNode(nodeData)
-
-      this._trimSelectedNodes(nodeData)
-
-      this.$emit('nodeclick', nodeData)
-
-      if (this.isLocalData) {
-        if (isLeaf || !this._checkHasChildren(nodeData)) {
-          this.onFinish()
-        }
-      } else if (this.isCloudDataList) {
-        this.onFinish()
-      } else if (this.isCloudDataTree) {
-        if (isLeaf) {
-          this.onFinish()
-        } else if (!this._checkHasChildren(nodeData)) {
-          // 尝试请求一次，如果没有返回数据标记为叶子节点
-          this.loadCloudDataNode(nodeData)
-        }
-      }
-    },
-
-    getChangeNodes(): Array<UTSJSONObject> {
-      const nodes: Array<UTSJSONObject> = []
-      this.selectedNodes.forEach((node : UTSJSONObject) => {
-        const newNode: UTSJSONObject = {}
-        newNode[this.mappingTextName] = node.getString(this.mappingTextName)
-        newNode[this.mappingValueName] = node.getString(this.mappingValueName)
-        nodes.push(newNode)
-      })
-      return nodes
-    },
-
-    onFinish() { },
-
-    // 加载数据(自动判定环境)
-    loadData() {
-      if (this.isLocalData) {
-        this.loadLocalData()
-      } else if (this.isCloudDataList) {
-        this.loadCloudDataList()
-      } else if (this.isCloudDataTree) {
-        this.loadCloudDataTree()
-      }
-    },
-
-    // 加载本地数据
-    loadLocalData() {
-      this.treeData = this.localdata
-      if (Array.isArray(this.dataValue)) {
-        const value = this.dataValue as Array<UTSJSONObject>
-        this.selectedPaths = value.slice(0)
-        this._pushSelectedTreeNodes(value, this.localdata)
-      } else {
-        this._pushSelectedNodes(this.localdata)
-      }
-    },
-
-    // 加载 Cloud 数据 (单列)
-    loadCloudDataList() {
-      this._loadCloudData(null, (data : Array<UTSJSONObject>) => {
-        this.treeData = data
-        this._pushSelectedNodes(data)
-      })
-    },
-
-    // 加载 Cloud 数据 (树形)
-    loadCloudDataTree() {
-      let commandOptions = {
-        field: this._cloudDataPostField(),
-        where: this._cloudDataTreeWhere(),
-        getTree: true
-      } as GetCommandOptions
-      if (this._checkIsNotNull(this.gettree)) {
-        commandOptions.startwith = `${this.selfField}=='${this.dataValue as string}'`
-      }
-      this._loadCloudData(commandOptions, (data : Array<UTSJSONObject>) => {
-        this.treeData = data
-        if (this.selectedPaths.length > 0) {
-          this._pushSelectedTreeNodes(this.selectedPaths, data)
-        } else {
-          this._pushSelectedNodes(data)
-        }
-      })
-    },
-
-    // 加载 Cloud 数据 (节点)
-    loadCloudDataNode(nodeData : UTSJSONObject) {
-      const commandOptions = {
-        field: this._cloudDataPostField(),
-        where: this._cloudDataNodeWhere()
-      } as GetCommandOptions
-      this._loadCloudData(commandOptions, (data : Array<UTSJSONObject>) => {
-        nodeData['children'] = data
-        if (data.length == 0) {
-          nodeData['isleaf'] = true
-          this.onFinish()
-        } else {
-          this._pushSelectedNodes(data)
-        }
-      })
-    },
-
-    // 回显 Cloud Tree Path
-    loadCloudDataPath() {
-      if (!this.hasCloudDataValue) {
-        return
-      }
-
-      const command : GetCommandOptions = {}
-
-      // 单列
-      if (this.isCloudDataList) {
-        // 根据 field's as value标识匹配 where 条件
-        let where : Array<string> = [];
-        let whereField = this._getForeignKeyByField();
-        if (whereField.length > 0) {
-          where.push(`${whereField} == '${this.dataValue as string}'`)
-        }
-
-        let whereString = where.join(' || ')
-        if (this._checkIsNotNull(this.where)) {
-          whereString = `(${this.where}) && (${whereString})`
-        }
-
-        command.field = this._cloudDataPostField()
-        command.where = whereString
-      }
-
-      // 树形
-      if (this.isCloudDataTree) {
-        command.field = this._cloudDataPostField()
-        command.getTreePath = {
-          startWith: `${this.selfField}=='${this.dataValue as string}'`
-        }
-      }
-
-      this._loadCloudData(command, (data : Array<UTSJSONObject>) => {
-        this._extractTreePath(data, this.selectedPaths)
-      })
-    },
-
-    _loadCloudData(options ?: GetCommandOptions, callback ?: ((data : Array<UTSJSONObject>) => void)) {
-      if (this.loading) {
-        return
-      }
-      this.loading = true
-
-      this.error = null
-
-      this._getCommand(options).then((response : UniCloudDBGetResult) => {
-        callback?.(response.data)
-      }).catch((err : any | null) => {
-        this.error = err as UniCloudError
-      }).finally(() => {
-        this.loading = false
-      })
-    },
-
-    _cloudDataPostField() : string {
-      let fields = [this.field];
-      if (this.parentField.length > 0) {
-        fields.push(`${this.parentField} as parent_value`)
-      }
-      return fields.join(',')
-    },
-
-    _cloudDataTreeWhere() : string {
-      let result : Array<string> = []
-      let selectedNodes = this.selectedNodes.length > 0 ? this.selectedNodes : this.selectedPaths
-      let parentField = this.parentField
-      if (parentField.length > 0) {
-        result.push(`${parentField} == null || ${parentField} == ""`)
-      }
-      if (selectedNodes.length > 0) {
-        for (var i = 0; i < selectedNodes.length - 1; i++) {
-          const parentFieldValue = selectedNodes[i].getString('value', '')
-          result.push(`${parentField} == '${parentFieldValue}'`)
-        }
-      }
-
-      let where : Array<string> = []
-      if (this._checkIsNotNull(this.where)) {
-        where.push(`(${this.where as string})`)
-      }
-
-      if (result.length > 0) {
-        where.push(`(${result.join(' || ')})`)
-      }
-
-      return where.join(' && ')
-    },
-
-    _cloudDataNodeWhere() : string {
-      const where : Array<string> = []
-      if (this.selectedNodes.length > 0) {
-        const value = this.selectedNodes[this.selectedNodes.length - 1].getString('value', '')
-        where.push(`${this.parentField} == '${value}'`)
-      }
-
-      let whereString = where.join(' || ')
-      if (this._checkIsNotNull(this.where)) {
-        return `(${this.where as string}) && (${whereString})`
-      }
-
-      return whereString
-    },
-
-    _getWhereByForeignKey() : string {
-      let result : Array<string> = []
-      let whereField = this._getForeignKeyByField();
-      if (whereField.length > 0) {
-        result.push(`${whereField} == '${this.dataValue as string}'`)
-      }
-
-      if (this._checkIsNotNull(this.where)) {
-        return `(${this.where}) && (${result.join(' || ')})`
-      }
-
-      return result.join(' || ')
-    },
-
-    _getForeignKeyByField() : string {
-      const fields = this.field.split(',')
-      let whereField = ''
-      for (let i = 0; i < fields.length; i++) {
-        const items = fields[i].split('as')
-        if (items.length < 2) {
-          continue
-        }
-        if (items[1].trim() === 'value') {
-          whereField = items[0].trim()
-          break
-        }
-      }
-      return whereField
-    },
-
-    _getCommand(options ?: GetCommandOptions) : Promise<UniCloudDBGetResult> {
-      let db = uniCloud.databaseForJQL()
-
-      let collection = Array.isArray(this.collection) ? db.collection(...(this.collection as Array<any>)) : db.collection(this.collection)
-
-      let filter : UniCloudDBFilter | null = null
-      if (this.foreignKey.length > 0) {
-        filter = collection.foreignKey(this.foreignKey)
-      }
-
-      const where : any = options?.where ?? this.where
-      if (typeof where == 'string') {
-        const whereString = where as string
-        if (whereString.length > 0) {
-          filter = (filter != null) ? filter.where(where) : collection.where(where)
-        }
-      } else {
-        filter = (filter != null) ? filter.where(where) : collection.where(where)
-      }
-
-      let query : UniCloudDBQuery | null = null
-      if (this.field.length > 0) {
-        query = (filter != null) ? filter.field(this.field) : collection.field(this.field)
-      }
-      if (this.groupby.length > 0) {
-        if (query != null) {
-          query = query.groupBy(this.groupby)
-        } else if (filter != null) {
-          query = filter.groupBy(this.groupby)
-        }
-      }
-      if (this.groupField.length > 0) {
-        if (query != null) {
-          query = query.groupField(this.groupField)
-        } else if (filter != null) {
-          query = filter.groupField(this.groupField)
-        }
-      }
-      if (this.distinct == true) {
-        if (query != null) {
-          query = query.distinct(this.field)
-        } else if (filter != null) {
-          query = filter.distinct(this.field)
-        }
-      }
-      if (this.orderby.length > 0) {
-        if (query != null) {
-          query = query.orderBy(this.orderby)
-        } else if (filter != null) {
-          query = filter.orderBy(this.orderby)
-        }
-      }
-
-      const size = this.pagination.size
-      const current = this.pagination.current
-      if (query != null) {
-        query = query.skip(size * (current - 1)).limit(size)
-      } else if (filter != null) {
-        query = filter.skip(size * (current - 1)).limit(size)
-      } else {
-        query = collection.skip(size * (current - 1)).limit(size)
-      }
-
-      const getOptions = {}
-      const treeOptions = {
-        limitLevel: this.limitlevel,
-        startWith: this.startwith
-      }
-      if (this.getcount == true) {
-        getOptions['getCount'] = this.getcount
-      }
-
-      const getTree : any = options?.getTree ?? this.gettree
-      if (typeof getTree == 'string') {
-        const getTreeString = getTree as string
-        if (getTreeString.length > 0) {
-          getOptions['getTree'] = treeOptions
-        }
-      } else if (typeof getTree == 'object') {
-        getOptions['getTree'] = treeOptions
-      } else {
-        getOptions['getTree'] = getTree
-      }
-
-      const getTreePath = options?.getTreePath ?? this.gettreepath
-      if (typeof getTreePath == 'string') {
-        const getTreePathString = getTreePath as string
-        if (getTreePathString.length > 0) {
-          getOptions['getTreePath'] = getTreePath
-        }
-      } else {
-        getOptions['getTreePath'] = getTreePath
-      }
-
-      return query.get(getOptions)
-    },
-
-    _checkIsNotNull(value : any) : boolean {
-      if (typeof value == 'string') {
-        const valueString = value as string
-        return (valueString.length > 0)
-      } else if (value instanceof UTSJSONObject) {
-        return true
-      }
-      return false
-    },
-
-    _checkIsLeafNode(nodeData : UTSJSONObject) : boolean {
-      if (this.selectedIndex >= this.limitlevel) {
-        return true
-      }
-
-      if (nodeData.getBoolean('isleaf', false)) {
-        return true
-      }
-
-      return false
-    },
-
-    _checkHasChildren(nodeData : UTSJSONObject) : boolean {
-      const children = nodeData.getArray('children') ?? ([] as Array<any>)
-      return children.length > 0
-    },
-
-    _pushSelectedNodes(nodes : Array<UTSJSONObject>) {
-      this.selectedNodes.push(DefaultSelectedNode)
-      this.selectedPages.push(nodes)
-      this.selectedIndex = this.selectedPages.length - 1
-    },
-
-    _trimSelectedNodes(nodeData : UTSJSONObject) {
-      this.selectedNodes.splice(this.selectedIndex)
-      this.selectedNodes.push(nodeData)
-
-      if (this.selectedPages.length > 0) {
-        this.selectedPages.splice(this.selectedIndex + 1)
-      }
-
-      const children = nodeData.getArray<UTSJSONObject>('children') ?? ([] as Array<UTSJSONObject>)
-      if (children.length > 0) {
-        this.selectedNodes.push(DefaultSelectedNode)
-        this.selectedPages.push(children)
-      }
-
-      this.selectedIndex = this.selectedPages.length - 1
-    },
-
-    _pushSelectedTreeNodes(paths : Array<UTSJSONObject>, nodes : Array<UTSJSONObject>) {
-      let children : Array<UTSJSONObject> = nodes
-      paths.forEach((node : UTSJSONObject) => {
-        const findNode = children.find((item : UTSJSONObject) : boolean => {
-          return (item.getString(this.mappingValueName) == node.getString(this.mappingValueName))
-        })
-        if (findNode != null) {
-          this.selectedPages.push(children)
-          this.selectedNodes.push(node)
-          children = findNode.getArray<UTSJSONObject>('children') ?? ([] as Array<UTSJSONObject>)
-        }
-      })
-      this.selectedIndex = this.selectedPages.length - 1
-    },
-
-    _extractTreePath(nodes : Array<UTSJSONObject>, result : Array<UTSJSONObject>) {
-      if (nodes.length == 0) {
-        return
-      }
-
-      const node = nodes[0]
-      result.push(node)
-
-      const children = node.getArray<UTSJSONObject>('children')
-      if (Array.isArray(children) && children!.length > 0) {
-        this._extractTreePath(children, result)
-      }
-    }
-  }
+        this.value,
+        this.collection,
+        this.field,
+        this.getcount,
+        this.orderby,
+        this.where,
+        this.groupby,
+        this.groupField,
+        this.distinct
+      ],
+      (newValue : Array<any>, oldValue : Array<any>) => {
+        this.pagination.size = this.pageSize
+        if (newValue[0] !== oldValue[0]) {
+          this.pagination.current = this.pageCurrent
+        }
+
+        this.onPropsChange()
+      }
+    )
+  },
+  methods: {
+    onPropsChange() {
+      this.selectedIndex = 0
+      this.selectedNodes.length = 0
+      this.selectedPages.length = 0
+      this.selectedPaths.length = 0
+
+      // 加载数据
+      this.$nextTick(() => {
+        this.loadData()
+      })
+    },
+
+    onTabSelect(index : number) {
+      this.selectedIndex = index
+    },
+
+    onNodeClick(nodeData : UTSJSONObject) {
+      if (nodeData.getBoolean('disable', false)) {
+        return
+      }
+
+      const isLeaf = this._checkIsLeafNode(nodeData)
+
+      this._trimSelectedNodes(nodeData)
+
+      this.$emit('nodeclick', nodeData)
+
+      if (this.isLocalData) {
+        if (isLeaf || !this._checkHasChildren(nodeData)) {
+          this.onFinish()
+        }
+      } else if (this.isCloudDataList) {
+        this.onFinish()
+      } else if (this.isCloudDataTree) {
+        if (isLeaf) {
+          this.onFinish()
+        } else if (!this._checkHasChildren(nodeData)) {
+          // 尝试请求一次，如果没有返回数据标记为叶子节点
+          this.loadCloudDataNode(nodeData)
+        }
+      }
+    },
+
+    getChangeNodes(): Array<UTSJSONObject> {
+      const nodes: Array<UTSJSONObject> = []
+      this.selectedNodes.forEach((node : UTSJSONObject) => {
+        const newNode: UTSJSONObject = {}
+        newNode[this.mappingTextName] = node.getString(this.mappingTextName)
+        newNode[this.mappingValueName] = node.getString(this.mappingValueName)
+        nodes.push(newNode)
+      })
+      return nodes
+    },
+
+    onFinish() { },
+
+    // 加载数据(自动判定环境)
+    loadData() {
+      if (this.isLocalData) {
+        this.loadLocalData()
+      } else if (this.isCloudDataList) {
+        this.loadCloudDataList()
+      } else if (this.isCloudDataTree) {
+        this.loadCloudDataTree()
+      }
+    },
+
+    // 加载本地数据
+    loadLocalData() {
+      this.treeData = this.localdata
+      if (Array.isArray(this.dataValue)) {
+        const value = this.dataValue as Array<UTSJSONObject>
+        this.selectedPaths = value.slice(0)
+        this._pushSelectedTreeNodes(value, this.localdata)
+      } else {
+        this._pushSelectedNodes(this.localdata)
+      }
+    },
+
+    // 加载 Cloud 数据 (单列)
+    loadCloudDataList() {
+      this._loadCloudData(null, (data : Array<UTSJSONObject>) => {
+        this.treeData = data
+        this._pushSelectedNodes(data)
+      })
+    },
+
+    // 加载 Cloud 数据 (树形)
+    loadCloudDataTree() {
+      let commandOptions = {
+        field: this._cloudDataPostField(),
+        where: this._cloudDataTreeWhere(),
+        getTree: true
+      } as GetCommandOptions
+      if (this._checkIsNotNull(this.gettree)) {
+        commandOptions.startwith = `${this.selfField}=='${this.dataValue as string}'`
+      }
+      this._loadCloudData(commandOptions, (data : Array<UTSJSONObject>) => {
+        this.treeData = data
+        if (this.selectedPaths.length > 0) {
+          this._pushSelectedTreeNodes(this.selectedPaths, data)
+        } else {
+          this._pushSelectedNodes(data)
+        }
+      })
+    },
+
+    // 加载 Cloud 数据 (节点)
+    loadCloudDataNode(nodeData : UTSJSONObject) {
+      const commandOptions = {
+        field: this._cloudDataPostField(),
+        where: this._cloudDataNodeWhere()
+      } as GetCommandOptions
+      this._loadCloudData(commandOptions, (data : Array<UTSJSONObject>) => {
+        nodeData['children'] = data
+        if (data.length == 0) {
+          nodeData['isleaf'] = true
+          this.onFinish()
+        } else {
+          this._pushSelectedNodes(data)
+        }
+      })
+    },
+
+    // 回显 Cloud Tree Path
+    loadCloudDataPath() {
+      if (!this.hasCloudDataValue) {
+        return
+      }
+
+      const command : GetCommandOptions = {}
+
+      // 单列
+      if (this.isCloudDataList) {
+        // 根据 field's as value标识匹配 where 条件
+        let where : Array<string> = [];
+        let whereField = this._getForeignKeyByField();
+        if (whereField.length > 0) {
+          where.push(`${whereField} == '${this.dataValue as string}'`)
+        }
+
+        let whereString = where.join(' || ')
+        if (this._checkIsNotNull(this.where)) {
+          whereString = `(${this.where}) && (${whereString})`
+        }
+
+        command.field = this._cloudDataPostField()
+        command.where = whereString
+      }
+
+      // 树形
+      if (this.isCloudDataTree) {
+        command.field = this._cloudDataPostField()
+        command.getTreePath = {
+          startWith: `${this.selfField}=='${this.dataValue as string}'`
+        }
+      }
+
+      this._loadCloudData(command, (data : Array<UTSJSONObject>) => {
+        this._extractTreePath(data, this.selectedPaths)
+      })
+    },
+
+    _loadCloudData(options ?: GetCommandOptions, callback ?: ((data : Array<UTSJSONObject>) => void)) {
+      if (this.loading) {
+        return
+      }
+      this.loading = true
+
+      this.error = null
+
+      this._getCommand(options).then((response : UniCloudDBGetResult) => {
+        callback?.(response.data)
+      }).catch((err : any | null) => {
+        this.error = err as UniCloudError
+      }).finally(() => {
+        this.loading = false
+      })
+    },
+
+    _cloudDataPostField() : string {
+      let fields = [this.field];
+      if (this.parentField.length > 0) {
+        fields.push(`${this.parentField} as parent_value`)
+      }
+      return fields.join(',')
+    },
+
+    _cloudDataTreeWhere() : string {
+      let result : Array<string> = []
+      let selectedNodes = this.selectedNodes.length > 0 ? this.selectedNodes : this.selectedPaths
+      let parentField = this.parentField
+      if (parentField.length > 0) {
+        result.push(`${parentField} == null || ${parentField} == ""`)
+      }
+      if (selectedNodes.length > 0) {
+        for (var i = 0; i < selectedNodes.length - 1; i++) {
+          const parentFieldValue = selectedNodes[i].getString('value', '')
+          result.push(`${parentField} == '${parentFieldValue}'`)
+        }
+      }
+
+      let where : Array<string> = []
+      if (this._checkIsNotNull(this.where)) {
+        where.push(`(${this.where as string})`)
+      }
+
+      if (result.length > 0) {
+        where.push(`(${result.join(' || ')})`)
+      }
+
+      return where.join(' && ')
+    },
+
+    _cloudDataNodeWhere() : string {
+      const where : Array<string> = []
+      if (this.selectedNodes.length > 0) {
+        const value = this.selectedNodes[this.selectedNodes.length - 1].getString('value', '')
+        where.push(`${this.parentField} == '${value}'`)
+      }
+
+      let whereString = where.join(' || ')
+      if (this._checkIsNotNull(this.where)) {
+        return `(${this.where as string}) && (${whereString})`
+      }
+
+      return whereString
+    },
+
+    _getWhereByForeignKey() : string {
+      let result : Array<string> = []
+      let whereField = this._getForeignKeyByField();
+      if (whereField.length > 0) {
+        result.push(`${whereField} == '${this.dataValue as string}'`)
+      }
+
+      if (this._checkIsNotNull(this.where)) {
+        return `(${this.where}) && (${result.join(' || ')})`
+      }
+
+      return result.join(' || ')
+    },
+
+    _getForeignKeyByField() : string {
+      const fields = this.field.split(',')
+      let whereField = ''
+      for (let i = 0; i < fields.length; i++) {
+        const items = fields[i].split('as')
+        if (items.length < 2) {
+          continue
+        }
+        if (items[1].trim() === 'value') {
+          whereField = items[0].trim()
+          break
+        }
+      }
+      return whereField
+    },
+
+    _getCommand(options ?: GetCommandOptions) : Promise<UniCloudDBGetResult> {
+      let db = uniCloud.databaseForJQL()
+
+      let collection = Array.isArray(this.collection) ? db.collection(...(this.collection as Array<any>)) : db.collection(this.collection)
+
+      let filter : UniCloudDBFilter | null = null
+      if (this.foreignKey.length > 0) {
+        filter = collection.foreignKey(this.foreignKey)
+      }
+
+      const where : any = options?.where ?? this.where
+      if (typeof where == 'string') {
+        const whereString = where as string
+        if (whereString.length > 0) {
+          filter = (filter != null) ? filter.where(where) : collection.where(where)
+        }
+      } else {
+        filter = (filter != null) ? filter.where(where) : collection.where(where)
+      }
+
+      let query : UniCloudDBQuery | null = null
+      if (this.field.length > 0) {
+        query = (filter != null) ? filter.field(this.field) : collection.field(this.field)
+      }
+      if (this.groupby.length > 0) {
+        if (query != null) {
+          query = query.groupBy(this.groupby)
+        } else if (filter != null) {
+          query = filter.groupBy(this.groupby)
+        }
+      }
+      if (this.groupField.length > 0) {
+        if (query != null) {
+          query = query.groupField(this.groupField)
+        } else if (filter != null) {
+          query = filter.groupField(this.groupField)
+        }
+      }
+      if (this.distinct == true) {
+        if (query != null) {
+          query = query.distinct(this.field)
+        } else if (filter != null) {
+          query = filter.distinct(this.field)
+        }
+      }
+      if (this.orderby.length > 0) {
+        if (query != null) {
+          query = query.orderBy(this.orderby)
+        } else if (filter != null) {
+          query = filter.orderBy(this.orderby)
+        }
+      }
+
+      const size = this.pagination.size
+      const current = this.pagination.current
+      if (query != null) {
+        query = query.skip(size * (current - 1)).limit(size)
+      } else if (filter != null) {
+        query = filter.skip(size * (current - 1)).limit(size)
+      } else {
+        query = collection.skip(size * (current - 1)).limit(size)
+      }
+
+      const getOptions = {}
+      const treeOptions = {
+        limitLevel: this.limitlevel,
+        startWith: this.startwith
+      }
+      if (this.getcount == true) {
+        getOptions['getCount'] = this.getcount
+      }
+
+      const getTree : any = options?.getTree ?? this.gettree
+      if (typeof getTree == 'string') {
+        const getTreeString = getTree as string
+        if (getTreeString.length > 0) {
+          getOptions['getTree'] = treeOptions
+        }
+      } else if (typeof getTree == 'object') {
+        getOptions['getTree'] = treeOptions
+      } else {
+        getOptions['getTree'] = getTree
+      }
+
+      const getTreePath = options?.getTreePath ?? this.gettreepath
+      if (typeof getTreePath == 'string') {
+        const getTreePathString = getTreePath as string
+        if (getTreePathString.length > 0) {
+          getOptions['getTreePath'] = getTreePath
+        }
+      } else {
+        getOptions['getTreePath'] = getTreePath
+      }
+
+      return query.get(getOptions)
+    },
+
+    _checkIsNotNull(value : any) : boolean {
+      if (typeof value == 'string') {
+        const valueString = value as string
+        return (valueString.length > 0)
+      } else if (value instanceof UTSJSONObject) {
+        return true
+      }
+      return false
+    },
+
+    _checkIsLeafNode(nodeData : UTSJSONObject) : boolean {
+      if (this.selectedIndex >= this.limitlevel) {
+        return true
+      }
+
+      if (nodeData.getBoolean('isleaf', false)) {
+        return true
+      }
+
+      return false
+    },
+
+    _checkHasChildren(nodeData : UTSJSONObject) : boolean {
+      const children = nodeData.getArray('children') ?? ([] as Array<any>)
+      return children.length > 0
+    },
+
+    _pushSelectedNodes(nodes : Array<UTSJSONObject>) {
+      this.selectedNodes.push(DefaultSelectedNode)
+      this.selectedPages.push(nodes)
+      this.selectedIndex = this.selectedPages.length - 1
+    },
+
+    _trimSelectedNodes(nodeData : UTSJSONObject) {
+      this.selectedNodes.splice(this.selectedIndex)
+      this.selectedNodes.push(nodeData)
+
+      if (this.selectedPages.length > 0) {
+        this.selectedPages.splice(this.selectedIndex + 1)
+      }
+
+      const children = nodeData.getArray<UTSJSONObject>('children') ?? ([] as Array<UTSJSONObject>)
+      if (children.length > 0) {
+        this.selectedNodes.push(DefaultSelectedNode)
+        this.selectedPages.push(children)
+      }
+
+      this.selectedIndex = this.selectedPages.length - 1
+    },
+
+    _pushSelectedTreeNodes(paths : Array<UTSJSONObject>, nodes : Array<UTSJSONObject>) {
+      let children : Array<UTSJSONObject> = nodes
+      paths.forEach((node : UTSJSONObject) => {
+        const findNode = children.find((item : UTSJSONObject) : boolean => {
+          return (item.getString(this.mappingValueName) == node.getString(this.mappingValueName))
+        })
+        if (findNode != null) {
+          this.selectedPages.push(children)
+          this.selectedNodes.push(node)
+          children = findNode.getArray<UTSJSONObject>('children') ?? ([] as Array<UTSJSONObject>)
+        }
+      })
+      this.selectedIndex = this.selectedPages.length - 1
+    },
+
+    _extractTreePath(nodes : Array<UTSJSONObject>, result : Array<UTSJSONObject>) {
+      if (nodes.length == 0) {
+        return
+      }
+
+      const node = nodes[0]
+      result.push(node)
+
+      const children = node.getArray<UTSJSONObject>('children')
+      if (Array.isArray(children) && children!.length > 0) {
+        this._extractTreePath(children, result)
+      }
+    }
+  }
 })
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
index 1a9c12e1..39fe1c3a 100644
--- a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
@@ -1,76 +1,76 @@
-.uni-data-pickerview {
-  position: relative;
-  flex-direction: column;
-  overflow: hidden;
-}
-
-.loading-cover {
-  position: absolute;
-  left: 0;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  align-items: center;
-  justify-content: center;
-  background-color: rgba(150, 150, 150, .1);
-}
-
-.error {
-  background-color: #fff;
-  padding: 15px;
-}
-
-.error-text {
-  color: #DD524D;
-}
-
-.selected-node-list {
-  flex-direction: row;
-  flex-wrap: nowrap;
-}
-
-.selected-node-item {
-  margin-left: 10px;
-  margin-right: 10px;
-  padding: 8px 10px 8px 10px;
-  border-bottom: 2px solid transparent;
-}
-
-.selected-node-item-active {
-  color: #007aff;
-  border-bottom-color: #007aff;
-}
-
-.list-view {
-  flex: 1;
-}
-
-.list-item {
-  flex-direction: row;
-  justify-content: space-between;
-  padding: 12px 15px;
-  border-bottom: 1px solid #f0f0f0;
-}
-
-.item-text {
-  color: #333333;
-}
-
-.item-text-disabled {
-  opacity: .5;
-}
-
-.item-text-overflow {
-  overflow: hidden;
-}
-
-.check {
-  margin-right: 5px;
-  border: 2px solid #007aff;
-  border-left: 0;
-  border-top: 0;
-  height: 12px;
-  width: 6px;
-  transform-origin: center;
-  transform: rotate(45deg);
-}
+.uni-data-pickerview {
+  position: relative;
+  flex-direction: column;
+  overflow: hidden;
+}
+
+.loading-cover {
+  position: absolute;
+  left: 0;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  align-items: center;
+  justify-content: center;
+  background-color: rgba(150, 150, 150, .1);
+}
+
+.error {
+  background-color: #fff;
+  padding: 15px;
+}
+
+.error-text {
+  color: #DD524D;
+}
+
+.selected-node-list {
+  flex-direction: row;
+  flex-wrap: nowrap;
+}
+
+.selected-node-item {
+  margin-left: 10px;
+  margin-right: 10px;
+  padding: 8px 10px 8px 10px;
+  border-bottom: 2px solid transparent;
+}
+
+.selected-node-item-active {
+  color: #007aff;
+  border-bottom-color: #007aff;
+}
+
+.list-view {
+  flex: 1;
+}
+
+.list-item {
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 12px 15px;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.item-text {
+  color: #333333;
+}
+
+.item-text-disabled {
+  opacity: .5;
+}
+
+.item-text-overflow {
+  overflow: hidden;
+}
+
+.check {
+  margin-right: 5px;
+  border: 2px solid #007aff;
+  border-left: 0;
+  border-top: 0;
+  height: 12px;
+  width: 6px;
+  transform-origin: center;
+  transform: rotate(45deg);
+}
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
index 653f8ddc..f4780f36 100644
--- a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
@@ -1,69 +1,69 @@
-<template>
-  <view class="uni-data-pickerview">
-    <view v-if="error!=null" class="error">
-      <text class="error-text">{{error!.errMsg}}</text>
-    </view>
-    <scroll-view v-if="!isCloudDataList" :scroll-x="true">
-      <view class="selected-node-list">
-        <template v-for="(item, index) in selectedNodes">
-          <text class="selected-node-item" :class="{'selected-node-item-active':index==selectedIndex}"
-            @click="onTabSelect(index)">
-            {{item[mappingTextName]}}
-          </text>
-        </template>
-      </view>
-    </scroll-view>
-    <list-view class="list-view" :scroll-y="true">
-      <list-item class="list-item" v-for="(item, _) in currentDataList" @click="onNodeClick(item)">
-        <text class="item-text" :class="{'item-text-disabled': item['disable']}">{{item[mappingTextName]}}</text>
-        <text class="check" v-if="item[mappingValueName] == selectedNodes[selectedIndex][mappingValueName]"></text>
-      </list-item>
-    </list-view>
-    <view class="loading-cover" v-if="loading">
-      <slot name="pickerview-loading" :loading="loading"></slot>
-    </view>
-  </view>
-</template>
-
-<script>
-  import { dataPicker } from "./uni-data-picker.uts"
-
-  /**
-   * DataPickerview
-   * @description uni-data-pickerview
-   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
-   * @property {Array} localdata 本地数据，参考
-   * @property {Boolean} step-searh = [true|false] 是否分布查询
-   * @value true 启用分布查询，仅查询当前选中节点
-   * @value false 关闭分布查询，一次查询出所有数据
-   * @property {String|DBFieldString} self-field 分布查询当前字段名称
-   * @property {String|DBFieldString} parent-field 分布查询父字段名称
-   * @property {String|DBCollectionString} collection 表名
-   * @property {String|DBFieldString} field 查询字段，多个字段用 `,` 分割
-   * @property {String} orderby 排序字段及正序倒叙设置
-   * @property {String|JQLString} where 查询条件
-   */
-  export default {
-    name: 'UniDataPickerView',
-    emits: ['nodeclick', 'change', 'update:modelValue'],
-    mixins: [dataPicker],
-    props: {
-      ellipsis: {
-        type: Boolean,
-        default: true
-      }
-    },
-    created() {
-      this.loadData()
-    },
-    methods: {
-      onFinish() {
-        this.$emit('change', this.getChangeNodes())
-      }
-    }
-  }
-</script>
-
-<style>
-  @import url("uni-data-pickerview.css");
-</style>
+<template>
+  <view class="uni-data-pickerview">
+    <view v-if="error!=null" class="error">
+      <text class="error-text">{{error!.errMsg}}</text>
+    </view>
+    <scroll-view v-if="!isCloudDataList" :scroll-x="true">
+      <view class="selected-node-list">
+        <template v-for="(item, index) in selectedNodes">
+          <text class="selected-node-item" :class="{'selected-node-item-active':index==selectedIndex}"
+            @click="onTabSelect(index)">
+            {{item[mappingTextName]}}
+          </text>
+        </template>
+      </view>
+    </scroll-view>
+    <list-view class="list-view" :scroll-y="true">
+      <list-item class="list-item" v-for="(item, _) in currentDataList" @click="onNodeClick(item)">
+        <text class="item-text" :class="{'item-text-disabled': item['disable']}">{{item[mappingTextName]}}</text>
+        <text class="check" v-if="item[mappingValueName] == selectedNodes[selectedIndex][mappingValueName]"></text>
+      </list-item>
+    </list-view>
+    <view class="loading-cover" v-if="loading">
+      <slot name="pickerview-loading" :loading="loading"></slot>
+    </view>
+  </view>
+</template>
+
+<script>
+  import { dataPicker } from "./uni-data-picker.uts"
+
+  /**
+   * DataPickerview
+   * @description uni-data-pickerview
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+   * @property {Array} localdata 本地数据，参考
+   * @property {Boolean} step-searh = [true|false] 是否分布查询
+   * @value true 启用分布查询，仅查询当前选中节点
+   * @value false 关闭分布查询，一次查询出所有数据
+   * @property {String|DBFieldString} self-field 分布查询当前字段名称
+   * @property {String|DBFieldString} parent-field 分布查询父字段名称
+   * @property {String|DBCollectionString} collection 表名
+   * @property {String|DBFieldString} field 查询字段，多个字段用 `,` 分割
+   * @property {String} orderby 排序字段及正序倒叙设置
+   * @property {String|JQLString} where 查询条件
+   */
+  export default {
+    name: 'UniDataPickerView',
+    emits: ['nodeclick', 'change', 'update:modelValue'],
+    mixins: [dataPicker],
+    props: {
+      ellipsis: {
+        type: Boolean,
+        default: true
+      }
+    },
+    created() {
+      this.loadData()
+    },
+    methods: {
+      onFinish() {
+        this.$emit('change', this.getChangeNodes())
+      }
+    }
+  }
+</script>
+
+<style>
+  @import url("uni-data-pickerview.css");
+</style>
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
index d3acf921..6ebced92 100644
--- a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
@@ -1,323 +1,323 @@
-<template>
-  <view class="uni-data-pickerview">
-    <scroll-view v-if="!isCloudDataList" class="selected-area" scroll-x="true">
-      <view class="selected-list">
-          <view 
-            class="selected-item"
-            v-for="(item,index) in selected"
-            :key="index"
-            :class="{
-              'selected-item-active':index == selectedIndex
-            }"
-            @click="handleSelect(index)"
-          >
-            <text>{{item.text || ''}}</text>
-          </view>
-      </view>
-    </scroll-view>
-    <view class="tab-c">
-      <scroll-view class="list" :scroll-y="true">
-        <view class="item" :class="{'is-disabled': !!item.disable}" v-for="(item, j) in dataList[selectedIndex]" :key="j"
-          @click="handleNodeClick(item, selectedIndex, j)">
-          <text class="item-text">{{item[map.text]}}</text>
-          <view class="check" v-if="selected.length > selectedIndex && item[map.value] == selected[selectedIndex].value"></view>
-        </view>
-      </scroll-view>
-
-      <view class="loading-cover" v-if="loading">
-        <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
-      </view>
-      <view class="error-message" v-if="errorMessage">
-        <text class="error-text">{{errorMessage}}</text>
-      </view>
-    </view>
-  </view>
-</template>
-
-<script>
-  import dataPicker from "./uni-data-picker.js"
-
-  /**
-   * DataPickerview
-   * @description uni-data-pickerview
-   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
-   * @property {Array} localdata 本地数据，参考
-   * @property {Boolean} step-searh = [true|false] 是否分布查询
-   * @value true 启用分布查询，仅查询当前选中节点
-   * @value false 关闭分布查询，一次查询出所有数据
-   * @property {String|DBFieldString} self-field 分布查询当前字段名称
-   * @property {String|DBFieldString} parent-field 分布查询父字段名称
-   * @property {String|DBCollectionString} collection 表名
-   * @property {String|DBFieldString} field 查询字段，多个字段用 `,` 分割
-   * @property {String} orderby 排序字段及正序倒叙设置
-   * @property {String|JQLString} where 查询条件
-   */
-  export default {
-    name: 'UniDataPickerView',
-    emits: ['nodeclick', 'change', 'datachange', 'update:modelValue'],
-    mixins: [dataPicker],
-    props: {
-      managedMode: {
-        type: Boolean,
-        default: false
-      },
-      ellipsis: {
-        type: Boolean,
-        default: true
-      }
-    },
-    created() {
-      if (!this.managedMode) {
-        this.$nextTick(() => {
-          this.loadData();
-        })
-      }
-    },
-    methods: {
-      onPropsChange() {
-        this._treeData = [];
-        this.selectedIndex = 0;
-        this.$nextTick(() => {
-          this.loadData();
-        })
-      },
-      handleSelect(index) {
-        this.selectedIndex = index;
-      },
-      handleNodeClick(item, i, j) {
-        if (item.disable) {
-          return;
-        }
-
-        const node = this.dataList[i][j];
-        const text = node[this.map.text];
-        const value = node[this.map.value];
-
-        if (i < this.selected.length - 1) {
-          this.selected.splice(i, this.selected.length - i)
-          this.selected.push({
-            text,
-            value
-          })
-        } else if (i === this.selected.length - 1) {
-          this.selected.splice(i, 1, {
-            text,
-            value
-          })
-        }
-
-        if (node.isleaf) {
-          this.onSelectedChange(node, node.isleaf)
-          return
-        }
-
-        const {
-          isleaf,
-          hasNodes
-        } = this._updateBindData()
-
-        // 本地数据
-        if (this.isLocalData) {
-          this.onSelectedChange(node, (!hasNodes || isleaf))
-        } else if (this.isCloudDataList) { // Cloud 数据 (单列)
-          this.onSelectedChange(node, true)
-        } else if (this.isCloudDataTree) { // Cloud 数据 (树形)
-          if (isleaf) {
-            this.onSelectedChange(node, node.isleaf)
-          } else if (!hasNodes) { // 请求一次服务器以确定是否为叶子节点
-            this.loadCloudDataNode((data) => {
-              if (!data.length) {
-                node.isleaf = true
-              } else {
-                this._treeData.push(...data)
-                this._updateBindData(node)
-              }
-              this.onSelectedChange(node, node.isleaf)
-            })
-          }
-        }
-      },
-      updateData(data) {
-        this._treeData = data.treeData
-        this.selected = data.selected
-        if (!this._treeData.length) {
-          this.loadData()
-        } else {
-          //this.selected = data.selected
-          this._updateBindData()
-        }
-      },
-      onDataChange() {
-        this.$emit('datachange');
-      },
-      onSelectedChange(node, isleaf) {
-        if (isleaf) {
-          this._dispatchEvent()
-        }
-
-        if (node) {
-          this.$emit('nodeclick', node)
-        }
-      },
-      _dispatchEvent() {
-        this.$emit('change', this.selected.slice(0))
-      }
-    }
-  }
-</script>
-
-<style lang="scss">
-	$uni-primary: #007aff !default;
-
-	.uni-data-pickerview {
-		flex: 1;
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: column;
-		overflow: hidden;
-		height: 100%;
-	}
-
-  .error-text {
-    color: #DD524D;
-  }
-
-  .loading-cover {
-    position: absolute;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    background-color: rgba(255, 255, 255, .5);
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: column;
-    align-items: center;
-    z-index: 1001;
-  }
-
-  .load-more {
-    /* #ifndef APP-NVUE */
-    margin: auto;
-    /* #endif */
-  }
-
-  .error-message {
-    background-color: #fff;
-    position: absolute;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    padding: 15px;
-    opacity: .9;
-    z-index: 102;
-  }
-
-  /* #ifdef APP-NVUE */
-  .selected-area {
-    width: 750rpx;
-  }
-  /* #endif */
-
-  .selected-list {
-    /* #ifndef APP-NVUE */
-    display: flex;
-    flex-wrap: nowrap;
-    /* #endif */
-    flex-direction: row;
-    padding: 0 5px;
-    border-bottom: 1px solid #f8f8f8;
-  }
-
-  .selected-item {
-    margin-left: 10px;
-    margin-right: 10px;
-    padding: 12px 0;
-    text-align: center;
-    /* #ifndef APP-NVUE */
-    white-space: nowrap;
-    /* #endif */
-  }
-
-  .selected-item-text-overflow {
-    width: 168px;
-    /* fix nvue */
-    overflow: hidden;
-    /* #ifndef APP-NVUE */
-    width: 6em;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    -o-text-overflow: ellipsis;
-    /* #endif */
-  }
-
-	.selected-item-active {
-		border-bottom: 2px solid $uni-primary;
-	}
-
-	.selected-item-text {
-		color: $uni-primary;
-	}
-
-  .tab-c {
-    position: relative;
-    flex: 1;
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: row;
-    overflow: hidden;
-  }
-
-  .list {
-    flex: 1;
-  }
-
-  .item {
-    padding: 12px 15px;
-    /* border-bottom: 1px solid #f0f0f0; */
-    /* #ifndef APP-NVUE */
-    display: flex;
-    /* #endif */
-    flex-direction: row;
-    justify-content: space-between;
-  }
-
-  .is-disabled {
-    opacity: .5;
-  }
-
-  .item-text {
-    /* flex: 1; */
-    color: #333333;
-  }
-
-  .item-text-overflow {
-    width: 280px;
-    /* fix nvue */
-    overflow: hidden;
-    /* #ifndef APP-NVUE */
-    width: 20em;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    -o-text-overflow: ellipsis;
-    /* #endif */
-  }
-
-	.check {
-		margin-right: 5px;
-		border: 2px solid $uni-primary;
-		border-left: 0;
-		border-top: 0;
-		height: 12px;
-		width: 6px;
-		transform-origin: center;
-		/* #ifndef APP-NVUE */
-		transition: all 0.3s;
-		/* #endif */
-		transform: rotate(45deg);
-	}
-</style>
+<template>
+  <view class="uni-data-pickerview">
+    <scroll-view v-if="!isCloudDataList" class="selected-area" scroll-x="true">
+      <view class="selected-list">
+          <view 
+            class="selected-item"
+            v-for="(item,index) in selected"
+            :key="index"
+            :class="{
+              'selected-item-active':index == selectedIndex
+            }"
+            @click="handleSelect(index)"
+          >
+            <text>{{item.text || ''}}</text>
+          </view>
+      </view>
+    </scroll-view>
+    <view class="tab-c">
+      <scroll-view class="list" :scroll-y="true">
+        <view class="item" :class="{'is-disabled': !!item.disable}" v-for="(item, j) in dataList[selectedIndex]" :key="j"
+          @click="handleNodeClick(item, selectedIndex, j)">
+          <text class="item-text">{{item[map.text]}}</text>
+          <view class="check" v-if="selected.length > selectedIndex && item[map.value] == selected[selectedIndex].value"></view>
+        </view>
+      </scroll-view>
+
+      <view class="loading-cover" v-if="loading">
+        <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
+      </view>
+      <view class="error-message" v-if="errorMessage">
+        <text class="error-text">{{errorMessage}}</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+  import dataPicker from "./uni-data-picker.js"
+
+  /**
+   * DataPickerview
+   * @description uni-data-pickerview
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+   * @property {Array} localdata 本地数据，参考
+   * @property {Boolean} step-searh = [true|false] 是否分布查询
+   * @value true 启用分布查询，仅查询当前选中节点
+   * @value false 关闭分布查询，一次查询出所有数据
+   * @property {String|DBFieldString} self-field 分布查询当前字段名称
+   * @property {String|DBFieldString} parent-field 分布查询父字段名称
+   * @property {String|DBCollectionString} collection 表名
+   * @property {String|DBFieldString} field 查询字段，多个字段用 `,` 分割
+   * @property {String} orderby 排序字段及正序倒叙设置
+   * @property {String|JQLString} where 查询条件
+   */
+  export default {
+    name: 'UniDataPickerView',
+    emits: ['nodeclick', 'change', 'datachange', 'update:modelValue'],
+    mixins: [dataPicker],
+    props: {
+      managedMode: {
+        type: Boolean,
+        default: false
+      },
+      ellipsis: {
+        type: Boolean,
+        default: true
+      }
+    },
+    created() {
+      if (!this.managedMode) {
+        this.$nextTick(() => {
+          this.loadData();
+        })
+      }
+    },
+    methods: {
+      onPropsChange() {
+        this._treeData = [];
+        this.selectedIndex = 0;
+        this.$nextTick(() => {
+          this.loadData();
+        })
+      },
+      handleSelect(index) {
+        this.selectedIndex = index;
+      },
+      handleNodeClick(item, i, j) {
+        if (item.disable) {
+          return;
+        }
+
+        const node = this.dataList[i][j];
+        const text = node[this.map.text];
+        const value = node[this.map.value];
+
+        if (i < this.selected.length - 1) {
+          this.selected.splice(i, this.selected.length - i)
+          this.selected.push({
+            text,
+            value
+          })
+        } else if (i === this.selected.length - 1) {
+          this.selected.splice(i, 1, {
+            text,
+            value
+          })
+        }
+
+        if (node.isleaf) {
+          this.onSelectedChange(node, node.isleaf)
+          return
+        }
+
+        const {
+          isleaf,
+          hasNodes
+        } = this._updateBindData()
+
+        // 本地数据
+        if (this.isLocalData) {
+          this.onSelectedChange(node, (!hasNodes || isleaf))
+        } else if (this.isCloudDataList) { // Cloud 数据 (单列)
+          this.onSelectedChange(node, true)
+        } else if (this.isCloudDataTree) { // Cloud 数据 (树形)
+          if (isleaf) {
+            this.onSelectedChange(node, node.isleaf)
+          } else if (!hasNodes) { // 请求一次服务器以确定是否为叶子节点
+            this.loadCloudDataNode((data) => {
+              if (!data.length) {
+                node.isleaf = true
+              } else {
+                this._treeData.push(...data)
+                this._updateBindData(node)
+              }
+              this.onSelectedChange(node, node.isleaf)
+            })
+          }
+        }
+      },
+      updateData(data) {
+        this._treeData = data.treeData
+        this.selected = data.selected
+        if (!this._treeData.length) {
+          this.loadData()
+        } else {
+          //this.selected = data.selected
+          this._updateBindData()
+        }
+      },
+      onDataChange() {
+        this.$emit('datachange');
+      },
+      onSelectedChange(node, isleaf) {
+        if (isleaf) {
+          this._dispatchEvent()
+        }
+
+        if (node) {
+          this.$emit('nodeclick', node)
+        }
+      },
+      _dispatchEvent() {
+        this.$emit('change', this.selected.slice(0))
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+	$uni-primary: #007aff !default;
+
+	.uni-data-pickerview {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		overflow: hidden;
+		height: 100%;
+	}
+
+  .error-text {
+    color: #DD524D;
+  }
+
+  .loading-cover {
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(255, 255, 255, .5);
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    align-items: center;
+    z-index: 1001;
+  }
+
+  .load-more {
+    /* #ifndef APP-NVUE */
+    margin: auto;
+    /* #endif */
+  }
+
+  .error-message {
+    background-color: #fff;
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    padding: 15px;
+    opacity: .9;
+    z-index: 102;
+  }
+
+  /* #ifdef APP-NVUE */
+  .selected-area {
+    width: 750rpx;
+  }
+  /* #endif */
+
+  .selected-list {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    flex-wrap: nowrap;
+    /* #endif */
+    flex-direction: row;
+    padding: 0 5px;
+    border-bottom: 1px solid #f8f8f8;
+  }
+
+  .selected-item {
+    margin-left: 10px;
+    margin-right: 10px;
+    padding: 12px 0;
+    text-align: center;
+    /* #ifndef APP-NVUE */
+    white-space: nowrap;
+    /* #endif */
+  }
+
+  .selected-item-text-overflow {
+    width: 168px;
+    /* fix nvue */
+    overflow: hidden;
+    /* #ifndef APP-NVUE */
+    width: 6em;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    /* #endif */
+  }
+
+	.selected-item-active {
+		border-bottom: 2px solid $uni-primary;
+	}
+
+	.selected-item-text {
+		color: $uni-primary;
+	}
+
+  .tab-c {
+    position: relative;
+    flex: 1;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    overflow: hidden;
+  }
+
+  .list {
+    flex: 1;
+  }
+
+  .item {
+    padding: 12px 15px;
+    /* border-bottom: 1px solid #f0f0f0; */
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    justify-content: space-between;
+  }
+
+  .is-disabled {
+    opacity: .5;
+  }
+
+  .item-text {
+    /* flex: 1; */
+    color: #333333;
+  }
+
+  .item-text-overflow {
+    width: 280px;
+    /* fix nvue */
+    overflow: hidden;
+    /* #ifndef APP-NVUE */
+    width: 20em;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    /* #endif */
+  }
+
+	.check {
+		margin-right: 5px;
+		border: 2px solid $uni-primary;
+		border-left: 0;
+		border-top: 0;
+		height: 12px;
+		width: 6px;
+		transform-origin: center;
+		/* #ifndef APP-NVUE */
+		transition: all 0.3s;
+		/* #endif */
+		transform: rotate(45deg);
+	}
+</style>
diff --git a/uni_modules/uni-data-picker/package.json b/uni_modules/uni-data-picker/package.json
index cb895b10..efc60c23 100644
--- a/uni_modules/uni-data-picker/package.json
+++ b/uni_modules/uni-data-picker/package.json
@@ -1,91 +1,91 @@
-{
-  "id": "uni-data-picker",
-  "displayName": "uni-data-picker 数据驱动的picker选择器",
-  "version": "2.0.0",
-  "description": "单列、多列级联选择器，常用于省市区城市选择、公司部门选择、多级分类等场景",
-  "keywords": [
-    "uni-ui",
-    "uniui",
-    "picker",
-    "级联",
-    "省市区",
-    ""
-],
-  "repository": "https://github.com/dcloudio/uni-ui",
-  "engines": {
-    "HBuilderX": ""
-  },
-  "directories": {
-    "example": "../../temps/example_temps"
-  },
-"dcloudext": {
-    "sale": {
-      "regular": {
-        "price": "0.00"
-      },
-      "sourcecode": {
-        "price": "0.00"
-      }
-    },
-    "contact": {
-      "qq": ""
-    },
-    "declaration": {
-      "ads": "无",
-      "data": "无",
-      "permissions": "无"
-    },
-    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
-    "type": "component-vue"
-  },
-  "uni_modules": {
-    "dependencies": [
-      "uni-load-more",
-			"uni-icons",
-			"uni-scss"
-    ],
-    "encrypt": [],
-    "platforms": {
-      "cloud": {
-        "tcb": "y",
-        "aliyun": "y"
-      },
-      "client": {
-        "App": {
-          "app-vue": "y",
-          "app-nvue": "y",
-          "app-uvue": "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"
-        },
-        "Vue": {
-            "vue2": "y",
-            "vue3": "y"
-        }
-      }
-    }
-  }
-}
+{
+  "id": "uni-data-picker",
+  "displayName": "uni-data-picker 数据驱动的picker选择器",
+  "version": "2.0.1",
+  "description": "单列、多列级联选择器，常用于省市区城市选择、公司部门选择、多级分类等场景",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "picker",
+    "级联",
+    "省市区",
+    ""
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+      "uni-load-more",
+			"uni-icons",
+			"uni-scss"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "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"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-data-picker/readme.md b/uni_modules/uni-data-picker/readme.md
index 002227c0..19dd0e83 100644
--- a/uni_modules/uni-data-picker/readme.md
+++ b/uni_modules/uni-data-picker/readme.md
@@ -1,22 +1,22 @@
-## DataPicker 级联选择
-> **组件名：uni-data-picker**
-> 代码块： `uDataPicker`
-> 关联组件：`uni-data-pickerview`、`uni-load-more`。
-
-
-`<uni-data-picker>` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。
-
-支持单列、和多列级联选择。列数没有限制，如果屏幕显示不全，顶部tab区域会左右滚动。
-
-候选数据支持一次性加载完毕，也支持懒加载，比如示例图中，选择了“北京”后，动态加载北京的区县数据。
-
-`<uni-data-picker>` 组件尤其适用于地址选择、分类选择等选择类。
-
-`<uni-data-picker>` 支持本地数据、云端静态数据(json)，uniCloud云数据库数据。
-
-`<uni-data-picker>` 可以通过JQL直连uniCloud云数据库，配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema)，可在schema2code中自动生成前端页面，还支持服务器端校验。
-
-在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”，这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面，会自动生成地址管理的维护页面，自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。
-
-### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+## DataPicker 级联选择
+> **组件名：uni-data-picker**
+> 代码块： `uDataPicker`
+> 关联组件：`uni-data-pickerview`、`uni-load-more`。
+
+
+`<uni-data-picker>` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。
+
+支持单列、和多列级联选择。列数没有限制，如果屏幕显示不全，顶部tab区域会左右滚动。
+
+候选数据支持一次性加载完毕，也支持懒加载，比如示例图中，选择了“北京”后，动态加载北京的区县数据。
+
+`<uni-data-picker>` 组件尤其适用于地址选择、分类选择等选择类。
+
+`<uni-data-picker>` 支持本地数据、云端静态数据(json)，uniCloud云数据库数据。
+
+`<uni-data-picker>` 可以通过JQL直连uniCloud云数据库，配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema)，可在schema2code中自动生成前端页面，还支持服务器端校验。
+
+在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”，这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面，会自动生成地址管理的维护页面，自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
 #### 如使用过程中有任何问题，或者您对uni-ui有一些好的建议，欢迎加入 uni-ui 交流群：871950839
\ No newline at end of file
diff --git a/uni_modules/uni-datetime-picker/changelog.md b/uni_modules/uni-datetime-picker/changelog.md
index 8798e937..102ddb1f 100644
--- a/uni_modules/uni-datetime-picker/changelog.md
+++ b/uni_modules/uni-datetime-picker/changelog.md
@@ -1,3 +1,11 @@
+## 2.2.38（2024-10-15）
+- 修复 微信小程序中的getSystemInfo警告
+## 2.2.37（2024-10-12）
+- 修复 微信小程序中的getSystemInfo警告
+## 2.2.36（2024-10-12）
+- 修复 微信小程序中的getSystemInfo警告
+## 2.2.35（2024-09-21）
+- 修复 没有选中日期时点击确定直接报错的Bug [详情](https://ask.dcloud.net.cn/question/198168)
 ## 2.2.34（2024-04-24）
 - 新增 日期点击事件，在点击日期时会触发该事件。
 ## 2.2.33（2024-04-15）
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
index 11fc45a9..6843e807 100644
--- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
@@ -464,9 +464,16 @@
 					this.isPhone = navigator.userAgent.toLowerCase().indexOf('mobile') !== -1
 					return
 				}
+				// #ifdef MP-WEIXIN
+				const {
+					windowWidth
+				} = uni.getWindowInfo()
+				// #endif
+				// #ifndef MP-WEIXIN
 				const {
 					windowWidth
 				} = uni.getSystemInfoSync()
+				// #endif
 				this.isPhone = windowWidth <= 500
 				this.windowWidth = windowWidth
 			},
@@ -698,11 +705,11 @@
 						startString = getDateTime(this.start, this.hideSecond)
 					}
 					[startDate, startTime] = startString.split(' ')
-					if (this.start && !dateCompare(this.start, this.tempRange.startDate)) {
+					if (this.start && !dateCompare(this.start, `${this.tempRange.startDate} ${this.tempRange.startTime}`)) {
 						startDateLaterRangeStartDate = true
 						this.tempRange.startDate = startDate
 					}
-					if (this.start && !dateCompare(this.start, this.tempRange.endDate)) {
+					if (this.start && !dateCompare(this.start, `${this.tempRange.endDate} ${this.tempRange.endTime}`)) {
 						startDateLaterRangeEndDate = true
 						this.tempRange.endDate = startDate
 					}
@@ -717,11 +724,11 @@
 					}
 					[endDate, endTime] = endString.split(' ')
 
-					if (this.end && !dateCompare(this.tempRange.startDate, this.end)) {
+					if (this.end && !dateCompare(`${this.tempRange.startDate} ${this.tempRange.startTime}`, this.end)) {
 						endDateEarlierRangeStartDate = true
 						this.tempRange.startDate = endDate
 					}
-					if (this.end && !dateCompare(this.tempRange.endDate, this.end)) {
+					if (this.end && !dateCompare(`${this.tempRange.endDate} ${this.tempRange.endTime}`, this.end)) {
 						endDateEarlierRangeEndDate = true
 						this.tempRange.endDate = endDate
 					}
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
index acf7e4ba..bc9d481e 100644
--- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
@@ -182,8 +182,8 @@ class Calendar {
 		if (!date) {
 			date = new Date()
 		}
-
-		return this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate)
+		const res = this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate)
+		return res ? res : this.getDateObj(date)
 	}
 
 	/**
diff --git a/uni_modules/uni-datetime-picker/package.json b/uni_modules/uni-datetime-picker/package.json
index 4d1b05c5..a886f1b5 100644
--- a/uni_modules/uni-datetime-picker/package.json
+++ b/uni_modules/uni-datetime-picker/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-datetime-picker",
   "displayName": "uni-datetime-picker 日期选择器",
-  "version": "2.2.34",
+  "version": "2.2.38",
   "description": "uni-datetime-picker 日期时间选择器，支持日历，支持范围选择",
   "keywords": [
     "uni-datetime-picker",
diff --git a/uni_modules/uni-easyinput/changelog.md b/uni_modules/uni-easyinput/changelog.md
index 6677b079..84c72eb7 100644
--- a/uni_modules/uni-easyinput/changelog.md
+++ b/uni_modules/uni-easyinput/changelog.md
@@ -1,3 +1,5 @@
+## 1.1.19（2024-07-18）
+- 修复 初始值传入 null 导致input报错的bug
 ## 1.1.18（2024-04-11）
 - 修复 easyinput组件双向绑定问题
 ## 1.1.17（2024-03-28）
diff --git a/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue b/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
index d41411b0..05ae27d9 100644
--- a/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
+++ b/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
@@ -1,693 +1,676 @@
-<template>
-	<view class="uni-easyinput" :class="{ 'uni-easyinput-error': msg }" :style="boxStyle">
-		<view class="uni-easyinput__content" :class="inputContentClass" :style="inputContentStyle">
-			<uni-icons v-if="prefixIcon" class="content-clear-icon" :type="prefixIcon" color="#c0c4cc"
-				@click="onClickIcon('prefix')" size="22"></uni-icons>
-			<slot name="left">
-			</slot>
-			<!-- #ifdef MP-ALIPAY -->
-			<textarea :enableNative="enableNative" v-if="type === 'textarea'" class="uni-easyinput__content-textarea"
-				:class="{ 'input-padding': inputBorder }" :name="name" :value="val" :placeholder="placeholder"
-				:placeholderStyle="placeholderStyle" :disabled="disabled" placeholder-class="uni-easyinput__placeholder-class"
-				:maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" :cursor-spacing="cursorSpacing"
-				:adjust-position="adjustPosition" @input="onInput" @blur="_Blur" @focus="_Focus" @confirm="onConfirm"
-				@keyboardheightchange="onkeyboardheightchange"></textarea>
-			<input :enableNative="enableNative" v-else :type="type === 'password' ? 'text' : type"
-				class="uni-easyinput__content-input" :style="inputStyle" :name="name" :value="val"
-				:password="!showPassword && type === 'password'" :placeholder="placeholder" :placeholderStyle="placeholderStyle"
-				placeholder-class="uni-easyinput__placeholder-class" :disabled="disabled" :maxlength="inputMaxlength"
-				:focus="focused" :confirmType="confirmType" :cursor-spacing="cursorSpacing" :adjust-position="adjustPosition"
-				@focus="_Focus" @blur="_Blur" @input="onInput" @confirm="onConfirm"
-				@keyboardheightchange="onkeyboardheightchange" />
-			<!-- #endif -->
-			<!-- #ifndef MP-ALIPAY -->
-			<textarea v-if="type === 'textarea'" class="uni-easyinput__content-textarea"
-				:class="{ 'input-padding': inputBorder }" :name="name" :value="val" :placeholder="placeholder"
-				:placeholderStyle="placeholderStyle" :disabled="disabled" placeholder-class="uni-easyinput__placeholder-class"
-				:maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" :cursor-spacing="cursorSpacing"
-				:adjust-position="adjustPosition" @input="onInput" @blur="_Blur" @focus="_Focus" @confirm="onConfirm"
-				@keyboardheightchange="onkeyboardheightchange"></textarea>
-			<input v-else :type="type === 'password' ? 'text' : type" class="uni-easyinput__content-input" :style="inputStyle"
-				:name="name" :value="val" :password="!showPassword && type === 'password'" :placeholder="placeholder"
-				:placeholderStyle="placeholderStyle" placeholder-class="uni-easyinput__placeholder-class" :disabled="disabled"
-				:maxlength="inputMaxlength" :focus="focused" :confirmType="confirmType" :cursor-spacing="cursorSpacing"
-				:adjust-position="adjustPosition" @focus="_Focus" @blur="_Blur" @input="onInput" @confirm="onConfirm"
-				@keyboardheightchange="onkeyboardheightchange" />
-			<!-- #endif -->
-
-			<template v-if="type === 'password' && passwordIcon">
-				<!-- 开启密码时显示小眼睛 -->
-				<uni-icons v-if="isVal" class="content-clear-icon" :class="{ 'is-textarea-icon': type === 'textarea' }"
-					:type="showPassword ? 'eye-slash-filled' : 'eye-filled'" :size="22"
-					:color="focusShow ? primaryColor : '#c0c4cc'" @click="onEyes"></uni-icons>
-			</template>
-			<template v-if="suffixIcon">
-				<uni-icons v-if="suffixIcon" class="content-clear-icon" :type="suffixIcon" color="#c0c4cc"
-					@click="onClickIcon('suffix')" size="22"></uni-icons>
-			</template>
-			<template v-else>
-				<uni-icons v-if="clearable && isVal && !disabled && type !== 'textarea'" class="content-clear-icon"
-					:class="{ 'is-textarea-icon': type === 'textarea' }" type="clear" :size="clearSize"
-					:color="msg ? '#dd524d' : focusShow ? primaryColor : '#c0c4cc'" @click="onClear"></uni-icons>
-			</template>
-			<slot name="right"></slot>
-		</view>
-	</view>
-</template>
-
-<script>
-	/**
-	 * Easyinput 输入框
-	 * @description 此组件可以实现表单的输入与校验，包括 "text" 和 "textarea" 类型。
-	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3455
-	 * @property {String}	value	输入内容
-	 * @property {String }	type	输入框的类型（默认text） password/text/textarea/..
-	 * 	@value text			文本输入键盘
-	 * 	@value textarea	多行文本输入键盘
-	 * 	@value password	密码输入键盘
-	 * 	@value number		数字输入键盘，注意iOS上app-vue弹出的数字键盘并非9宫格方式
-	 * 	@value idcard		身份证输入键盘，信、支付宝、百度、QQ小程序
-	 * 	@value digit		带小数点的数字键盘	，App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持
-	 * @property {Boolean}	clearable	是否显示右侧清空内容的图标控件，点击可清空输入框内容（默认true）
-	 * @property {Boolean}	autoHeight	是否自动增高输入区域，type为textarea时有效（默认true）
-	 * @property {String }	placeholder	输入框的提示文字
-	 * @property {String }	placeholderStyle	placeholder的样式(内联样式，字符串)，如"color: #ddd"
-	 * @property {Boolean}	focus	是否自动获得焦点（默认false）
-	 * @property {Boolean}	disabled	是否禁用（默认false）
-	 * @property {Number }	maxlength	最大输入长度，设置为 -1 的时候不限制最大长度（默认140）
-	 * @property {String }	confirmType	设置键盘右下角按钮的文字，仅在type="text"时生效（默认done）
-	 * @property {Number }	clearSize	清除图标的大小，单位px（默认15）
-	 * @property {String}	prefixIcon	输入框头部图标
-	 * @property {String}	suffixIcon	输入框尾部图标
-	 * @property {String}	primaryColor	设置主题色（默认#2979ff）
-	 * @property {Boolean}	trim	是否自动去除两端的空格
-	 * @property {Boolean}	cursorSpacing	指定光标与键盘的距离，单位 px
-	 * @property {Boolean}  ajust-position 当键盘弹起时，是否上推内容，默认值：true
-	 * @value both	去除两端空格
-	 * @value left	去除左侧空格
-	 * @value right	去除右侧空格
-	 * @value start	去除左侧空格
-	 * @value end		去除右侧空格
-	 * @value all		去除全部空格
-	 * @value none	不去除空格
-	 * @property {Boolean}	inputBorder	是否显示input输入框的边框（默认true）
-	 * @property {Boolean}	passwordIcon	type=password时是否显示小眼睛图标
-	 * @property {Object}	styles	自定义颜色
-	 * @event {Function}	input	输入框内容发生变化时触发
-	 * @event {Function}	focus	输入框获得焦点时触发
-	 * @event {Function}	blur	输入框失去焦点时触发
-	 * @event {Function}	confirm	点击完成按钮时触发
-	 * @event {Function}	iconClick	点击图标时触发
-	 * @example <uni-easyinput v-model="mobile"></uni-easyinput>
-	 */
-	function obj2strClass(obj) {
-		let classess = '';
-		for (let key in obj) {
-			const val = obj[key];
-			if (val) {
-				classess += `${key} `;
-			}
-		}
-		return classess;
-	}
-
-	function obj2strStyle(obj) {
-		let style = '';
-		for (let key in obj) {
-			const val = obj[key];
-			style += `${key}:${val};`;
-		}
-		return style;
-	}
-	export default {
-		name: 'uni-easyinput',
-		emits: [
-			'click',
-			'iconClick',
-			'update:modelValue',
-			'input',
-			'focus',
-			'blur',
-			'confirm',
-			'clear',
-			'eyes',
-			'change',
-			'keyboardheightchange'
-		],
-		model: {
-			prop: 'modelValue',
-			event: 'update:modelValue'
-		},
-		options: {
-			// #ifdef MP-TOUTIAO
-			virtualHost: false,
-			// #endif
-			// #ifndef MP-TOUTIAO
-			virtualHost: true
-			// #endif
-		},
-		inject: {
-			form: {
-				from: 'uniForm',
-				default: null
-			},
-			formItem: {
-				from: 'uniFormItem',
-				default: null
-			}
-		},
-		props: {
-			name: String,
-			value: [Number, String],
-			modelValue: [Number, String],
-			type: {
-				type: String,
-				default: 'text'
-			},
-			clearable: {
-				type: Boolean,
-				default: true
-			},
-			autoHeight: {
-				type: Boolean,
-				default: false
-			},
-			placeholder: {
-				type: String,
-				default: ' '
-			},
-			placeholderStyle: String,
-			focus: {
-				type: Boolean,
-				default: false
-			},
-			disabled: {
-				type: Boolean,
-				default: false
-			},
-			maxlength: {
-				type: [Number, String],
-				default: 140
-			},
-			confirmType: {
-				type: String,
-				default: 'done'
-			},
-			clearSize: {
-				type: [Number, String],
-				default: 24
-			},
-			inputBorder: {
-				type: Boolean,
-				default: true
-			},
-			prefixIcon: {
-				type: String,
-				default: ''
-			},
-			suffixIcon: {
-				type: String,
-				default: ''
-			},
-			trim: {
-				type: [Boolean, String],
-				default: false
-			},
-			cursorSpacing: {
-				type: Number,
-				default: 0
-			},
-			passwordIcon: {
-				type: Boolean,
-				default: true
-			},
-			adjustPosition: {
-				type: Boolean,
-				default: true
-			},
-			primaryColor: {
-				type: String,
-				default: '#2979ff'
-			},
-			styles: {
-				type: Object,
-				default() {
-					return {
-						color: '#333',
-						backgroundColor: '#fff',
-						disableColor: '#F7F6F6',
-						borderColor: '#e5e5e5'
-					};
-				}
-			},
-			errorMessage: {
-				type: [String, Boolean],
-				default: ''
-			},
-			// #ifdef MP-ALIPAY
-			enableNative: {
-				type: Boolean,
-				default: false
-			}
-			// #endif
-		},
-		data() {
-			return {
-				focused: false,
-				val: '',
-				showMsg: '',
-				border: false,
-				isFirstBorder: false,
-				showClearIcon: false,
-				showPassword: false,
-				focusShow: false,
-				localMsg: '',
-				isEnter: false // 用于判断当前是否是使用回车操作
-			};
-		},
-		computed: {
-			// 输入框内是否有值
-			isVal() {
-				const val = this.val;
-				// fixed by mehaotian 处理值为0的情况，字符串0不在处理范围
-				if (val || val === 0) {
-					return true;
-				}
-				return false;
-			},
-
-			msg() {
-				// console.log('computed', this.form, this.formItem);
-				// if (this.form) {
-				// 	return this.errorMessage || this.formItem.errMsg;
-				// }
-				// TODO 处理头条 formItem 中 errMsg 不更新的问题
-				return this.localMsg || this.errorMessage;
-			},
-			// 因为uniapp的input组件的maxlength组件必须要数值，这里转为数值，用户可以传入字符串数值
-			inputMaxlength() {
-				return Number(this.maxlength);
-			},
-
-			// 处理外层样式的style
-			boxStyle() {
-				return `color:${
-					this.inputBorder && this.msg ? '#e43d33' : this.styles.color
-				};`;
-			},
-			// input 内容的类和样式处理
-			inputContentClass() {
-				return obj2strClass({
-					'is-input-border': this.inputBorder,
-					'is-input-error-border': this.inputBorder && this.msg,
-					'is-textarea': this.type === 'textarea',
-					'is-disabled': this.disabled,
-					'is-focused': this.focusShow
-				});
-			},
-			inputContentStyle() {
-				const focusColor = this.focusShow
-					? this.primaryColor
-					: this.styles.borderColor;
-				const borderColor =
-					this.inputBorder && this.msg ? '#dd524d' : focusColor;
-				return obj2strStyle({
-					'border-color': borderColor || '#e5e5e5',
-					'background-color': this.disabled
-						? this.styles.disableColor
-						: this.styles.backgroundColor
-				});
-			},
-			// input右侧样式
-			inputStyle() {
-				const paddingRight =
-					this.type === 'password' || this.clearable || this.prefixIcon
-						? ''
-						: '10px';
-				return obj2strStyle({
-					'padding-right': paddingRight,
-					'padding-left': this.prefixIcon ? '' : '10px'
-				});
-			}
-		},
-		watch: {
-			value(newVal) {
-				this.val = newVal;
-			},
-			modelValue(newVal) {
-				this.val = newVal;
-			},
-			focus(newVal) {
-				this.$nextTick(() => {
-					this.focused = this.focus;
-					this.focusShow = this.focus;
-				});
-			}
-		},
-		created() {
-			this.init();
-			// TODO 处理头条vue3 computed 不监听 inject 更改的问题（formItem.errMsg）
-			if (this.form && this.formItem) {
-				this.$watch('formItem.errMsg', newVal => {
-					this.localMsg = newVal;
-				});
-			}
-		},
-		mounted() {
-			this.$nextTick(() => {
-				this.focused = this.focus;
-				this.focusShow = this.focus;
-			});
-		},
-		methods: {
-			/**
-			 * 初始化变量值
-			 */
-			init() {
-				if (this.value || this.value === 0) {
-					this.val = this.value;
-				} else if (
-					this.modelValue ||
-					this.modelValue === 0 ||
-					this.modelValue === ''
-				) {
-					this.val = this.modelValue;
-				} else {
-					this.val = null;
-				}
-			},
-
-			/**
-			 * 点击图标时触发
-			 * @param {Object} type
-			 */
-			onClickIcon(type) {
-				this.$emit('iconClick', type);
-			},
-
-			/**
-			 * 显示隐藏内容，密码框时生效
-			 */
-			onEyes() {
-				this.showPassword = !this.showPassword;
-				this.$emit('eyes', this.showPassword);
-			},
-
-			/**
-			 * 输入时触发
-			 * @param {Object} event
-			 */
-			onInput(event) {
-				let value = event.detail.value;
-				// 判断是否去除空格
-				if (this.trim) {
-					if (typeof this.trim === 'boolean' && this.trim) {
-						value = this.trimStr(value);
-					}
-					if (typeof this.trim === 'string') {
-						value = this.trimStr(value, this.trim);
-					}
-				}
-				if (this.errMsg) this.errMsg = '';
-				this.val = value;
-				// TODO 兼容 vue2
-				this.$emit('input', value);
-				// TODO　兼容　vue3
-				this.$emit('update:modelValue', value);
-			},
-
-			/**
-			 * 外部调用方法
-			 * 获取焦点时触发
-			 * @param {Object} event
-			 */
-			onFocus() {
-				this.$nextTick(() => {
-					this.focused = true;
-				});
-				this.$emit('focus', null);
-			},
-
-			_Focus(event) {
-				this.focusShow = true;
-				this.$emit('focus', event);
-			},
-
-			/**
-			 * 外部调用方法
-			 * 失去焦点时触发
-			 * @param {Object} event
-			 */
-			onBlur() {
-				this.focused = false;
-				this.$emit('blur', null);
-			},
-			_Blur(event) {
-				let value = event.detail.value;
-				this.focusShow = false;
-				this.$emit('blur', event);
-				// 根据类型返回值，在event中获取的值理论上讲都是string
-				if (this.isEnter === false) {
-					this.$emit('change', this.val);
-				}
-				// 失去焦点时参与表单校验
-				if (this.form && this.formItem) {
-					const { validateTrigger } = this.form;
-					if (validateTrigger === 'blur') {
-						this.formItem.onFieldChange();
-					}
-				}
-			},
-
-			/**
-			 * 按下键盘的发送键
-			 * @param {Object} e
-			 */
-			onConfirm(e) {
-				this.$emit('confirm', this.val);
-				this.isEnter = true;
-				this.$emit('change', this.val);
-				this.$nextTick(() => {
-					this.isEnter = false;
-				});
-			},
-
-			/**
-			 * 清理内容
-			 * @param {Object} event
-			 */
-			onClear(event) {
-				this.val = '';
-				// TODO 兼容 vue2
-				this.$emit('input', '');
-				// TODO 兼容 vue2
-				// TODO　兼容　vue3
-				this.$emit('update:modelValue', '');
-				// 点击叉号触发
-				this.$emit('clear');
-			},
-
-			/**
-			 * 键盘高度发生变化的时候触发此事件
-			 * 兼容性：微信小程序2.7.0+、App 3.1.0+
-			 * @param {Object} event
-			 */
-			onkeyboardheightchange(event) {
-				this.$emit('keyboardheightchange', event);
-			},
-
-			/**
-			 * 去除空格
-			 */
-			trimStr(str, pos = 'both') {
-				if (pos === 'both') {
-					return str.trim();
-				} else if (pos === 'left') {
-					return str.trimLeft();
-				} else if (pos === 'right') {
-					return str.trimRight();
-				} else if (pos === 'start') {
-					return str.trimStart();
-				} else if (pos === 'end') {
-					return str.trimEnd();
-				} else if (pos === 'all') {
-					return str.replace(/\s+/g, '');
-				} else if (pos === 'none') {
-					return str;
-				}
-				return str;
-			}
-		}
-	};
-</script>
-
-<style lang="scss">
-	$uni-error: #e43d33;
-	$uni-border-1: #dcdfe6 !default;
-
-	.uni-easyinput {
-		/* #ifndef APP-NVUE */
-		width: 100%;
-		/* #endif */
-		flex: 1;
-		position: relative;
-		text-align: left;
-		color: #333;
-		font-size: 14px;
-	}
-
-	.uni-easyinput__content {
-		flex: 1;
-		/* #ifndef APP-NVUE */
-		width: 100%;
-		display: flex;
-		box-sizing: border-box;
-		// min-height: 36px;
-		/* #endif */
-		flex-direction: row;
-		align-items: center;
-		// 处理border动画刚开始显示黑色的问题
-		border-color: #fff;
-		transition-property: border-color;
-		transition-duration: 0.3s;
-	}
-
-	.uni-easyinput__content-input {
-		/* #ifndef APP-NVUE */
-		width: auto;
-		/* #endif */
-		position: relative;
-		overflow: hidden;
-		flex: 1;
-		line-height: 1;
-		font-size: 14px;
-		height: 35px;
-		// min-height: 36px;
-
-		/*ifdef H5*/
-		& ::-ms-reveal {
-			display: none;
-		}
-
-		& ::-ms-clear {
-			display: none;
-		}
-
-		& ::-o-clear {
-			display: none;
-		}
-		/*endif*/
-	}
-
-	.uni-easyinput__placeholder-class {
-		color: #999;
-		font-size: 12px;
-		// font-weight: 200;
-	}
-
-	.is-textarea {
-		align-items: flex-start;
-	}
-
-	.is-textarea-icon {
-		margin-top: 5px;
-	}
-
-	.uni-easyinput__content-textarea {
-		position: relative;
-		overflow: hidden;
-		flex: 1;
-		line-height: 1.5;
-		font-size: 14px;
-		margin: 6px;
-		margin-left: 0;
-		height: 80px;
-		min-height: 80px;
-		/* #ifndef APP-NVUE */
-		min-height: 80px;
-		width: auto;
-		/* #endif */
-	}
-
-	.input-padding {
-		padding-left: 10px;
-	}
-
-	.content-clear-icon {
-		padding: 0 5px;
-	}
-
-	.label-icon {
-		margin-right: 5px;
-		margin-top: -1px;
-	}
-
-	// 显示边框
-	.is-input-border {
-		/* #ifndef APP-NVUE */
-		display: flex;
-		box-sizing: border-box;
-		/* #endif */
-		flex-direction: row;
-		align-items: center;
-		border: 1px solid $uni-border-1;
-		border-radius: 4px;
-		/* #ifdef MP-ALIPAY */
-		overflow: hidden;
-		/* #endif */
-	}
-
-	.uni-error-message {
-		position: absolute;
-		bottom: -17px;
-		left: 0;
-		line-height: 12px;
-		color: $uni-error;
-		font-size: 12px;
-		text-align: left;
-	}
-
-	.uni-error-msg--boeder {
-		position: relative;
-		bottom: 0;
-		line-height: 22px;
-	}
-
-	.is-input-error-border {
-		border-color: $uni-error;
-
-		.uni-easyinput__placeholder-class {
-			color: mix(#fff, $uni-error, 50%);
-		}
-	}
-
-	.uni-easyinput--border {
-		margin-bottom: 0;
-		padding: 10px 15px;
-		// padding-bottom: 0;
-		border-top: 1px #eee solid;
-	}
-
-	.uni-easyinput-error {
-		padding-bottom: 0;
-	}
-
-	.is-first-border {
-		/* #ifndef APP-NVUE */
-		border: none;
-		/* #endif */
-		/* #ifdef APP-NVUE */
-		border-width: 0;
-		/* #endif */
-	}
-
-	.is-disabled {
-		background-color: #f7f6f6;
-		color: #d5d5d5;
-
-		.uni-easyinput__placeholder-class {
-			color: #d5d5d5;
-			font-size: 12px;
-		}
-	}
-</style>
+<template>
+	<view class="uni-easyinput" :class="{ 'uni-easyinput-error': msg }" :style="boxStyle">
+		<view class="uni-easyinput__content" :class="inputContentClass" :style="inputContentStyle">
+			<uni-icons v-if="prefixIcon" class="content-clear-icon" :type="prefixIcon" color="#c0c4cc" @click="onClickIcon('prefix')" size="22"></uni-icons>
+			<slot name="left">
+			</slot>
+			<!-- #ifdef MP-ALIPAY -->
+			<textarea :enableNative="enableNative" v-if="type === 'textarea'" class="uni-easyinput__content-textarea" :class="{ 'input-padding': inputBorder }" :name="name" :value="val" :placeholder="placeholder" :placeholderStyle="placeholderStyle" :disabled="disabled" placeholder-class="uni-easyinput__placeholder-class" :maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" :cursor-spacing="cursorSpacing" :adjust-position="adjustPosition" @input="onInput" @blur="_Blur" @focus="_Focus" @confirm="onConfirm" @keyboardheightchange="onkeyboardheightchange"></textarea>
+			<input :enableNative="enableNative" v-else :type="type === 'password' ? 'text' : type" class="uni-easyinput__content-input" :style="inputStyle" :name="name" :value="val" :password="!showPassword && type === 'password'" :placeholder="placeholder" :placeholderStyle="placeholderStyle" placeholder-class="uni-easyinput__placeholder-class" :disabled="disabled" :maxlength="inputMaxlength" :focus="focused" :confirmType="confirmType" :cursor-spacing="cursorSpacing" :adjust-position="adjustPosition" @focus="_Focus" @blur="_Blur" @input="onInput" @confirm="onConfirm" @keyboardheightchange="onkeyboardheightchange" />
+			<!-- #endif -->
+			<!-- #ifndef MP-ALIPAY -->
+			<textarea v-if="type === 'textarea'" class="uni-easyinput__content-textarea" :class="{ 'input-padding': inputBorder }" :name="name" :value="val" :placeholder="placeholder" :placeholderStyle="placeholderStyle" :disabled="disabled" placeholder-class="uni-easyinput__placeholder-class" :maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" :cursor-spacing="cursorSpacing" :adjust-position="adjustPosition" @input="onInput" @blur="_Blur" @focus="_Focus" @confirm="onConfirm" @keyboardheightchange="onkeyboardheightchange"></textarea>
+			<input v-else :type="type === 'password' ? 'text' : type" class="uni-easyinput__content-input" :style="inputStyle" :name="name" :value="val" :password="!showPassword && type === 'password'" :placeholder="placeholder" :placeholderStyle="placeholderStyle" placeholder-class="uni-easyinput__placeholder-class" :disabled="disabled" :maxlength="inputMaxlength" :focus="focused" :confirmType="confirmType" :cursor-spacing="cursorSpacing" :adjust-position="adjustPosition" @focus="_Focus" @blur="_Blur" @input="onInput" @confirm="onConfirm" @keyboardheightchange="onkeyboardheightchange" />
+			<!-- #endif -->
+
+			<template v-if="type === 'password' && passwordIcon">
+				<!-- 开启密码时显示小眼睛 -->
+				<uni-icons v-if="isVal" class="content-clear-icon" :class="{ 'is-textarea-icon': type === 'textarea' }" :type="showPassword ? 'eye-slash-filled' : 'eye-filled'" :size="22" :color="focusShow ? primaryColor : '#c0c4cc'" @click="onEyes"></uni-icons>
+			</template>
+			<template v-if="suffixIcon">
+				<uni-icons v-if="suffixIcon" class="content-clear-icon" :type="suffixIcon" color="#c0c4cc" @click="onClickIcon('suffix')" size="22"></uni-icons>
+			</template>
+			<template v-else>
+				<uni-icons v-if="clearable && isVal && !disabled && type !== 'textarea'" class="content-clear-icon" :class="{ 'is-textarea-icon': type === 'textarea' }" type="clear" :size="clearSize" :color="msg ? '#dd524d' : focusShow ? primaryColor : '#c0c4cc'" @click="onClear"></uni-icons>
+			</template>
+			<slot name="right"></slot>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * Easyinput 输入框
+	 * @description 此组件可以实现表单的输入与校验，包括 "text" 和 "textarea" 类型。
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3455
+	 * @property {String}	value	输入内容
+	 * @property {String }	type	输入框的类型（默认text） password/text/textarea/..
+	 * 	@value text			文本输入键盘
+	 * 	@value textarea	多行文本输入键盘
+	 * 	@value password	密码输入键盘
+	 * 	@value number		数字输入键盘，注意iOS上app-vue弹出的数字键盘并非9宫格方式
+	 * 	@value idcard		身份证输入键盘，信、支付宝、百度、QQ小程序
+	 * 	@value digit		带小数点的数字键盘	，App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持
+	 * @property {Boolean}	clearable	是否显示右侧清空内容的图标控件，点击可清空输入框内容（默认true）
+	 * @property {Boolean}	autoHeight	是否自动增高输入区域，type为textarea时有效（默认true）
+	 * @property {String }	placeholder	输入框的提示文字
+	 * @property {String }	placeholderStyle	placeholder的样式(内联样式，字符串)，如"color: #ddd"
+	 * @property {Boolean}	focus	是否自动获得焦点（默认false）
+	 * @property {Boolean}	disabled	是否禁用（默认false）
+	 * @property {Number }	maxlength	最大输入长度，设置为 -1 的时候不限制最大长度（默认140）
+	 * @property {String }	confirmType	设置键盘右下角按钮的文字，仅在type="text"时生效（默认done）
+	 * @property {Number }	clearSize	清除图标的大小，单位px（默认15）
+	 * @property {String}	prefixIcon	输入框头部图标
+	 * @property {String}	suffixIcon	输入框尾部图标
+	 * @property {String}	primaryColor	设置主题色（默认#2979ff）
+	 * @property {Boolean}	trim	是否自动去除两端的空格
+	 * @property {Boolean}	cursorSpacing	指定光标与键盘的距离，单位 px
+	 * @property {Boolean}  ajust-position 当键盘弹起时，是否上推内容，默认值：true
+	 * @value both	去除两端空格
+	 * @value left	去除左侧空格
+	 * @value right	去除右侧空格
+	 * @value start	去除左侧空格
+	 * @value end		去除右侧空格
+	 * @value all		去除全部空格
+	 * @value none	不去除空格
+	 * @property {Boolean}	inputBorder	是否显示input输入框的边框（默认true）
+	 * @property {Boolean}	passwordIcon	type=password时是否显示小眼睛图标
+	 * @property {Object}	styles	自定义颜色
+	 * @event {Function}	input	输入框内容发生变化时触发
+	 * @event {Function}	focus	输入框获得焦点时触发
+	 * @event {Function}	blur	输入框失去焦点时触发
+	 * @event {Function}	confirm	点击完成按钮时触发
+	 * @event {Function}	iconClick	点击图标时触发
+	 * @example <uni-easyinput v-model="mobile"></uni-easyinput>
+	 */
+	function obj2strClass(obj) {
+		let classess = '';
+		for (let key in obj) {
+			const val = obj[key];
+			if (val) {
+				classess += `${key} `;
+			}
+		}
+		return classess;
+	}
+
+	function obj2strStyle(obj) {
+		let style = '';
+		for (let key in obj) {
+			const val = obj[key];
+			style += `${key}:${val};`;
+		}
+		return style;
+	}
+	export default {
+		name: 'uni-easyinput',
+		emits: [
+			'click',
+			'iconClick',
+			'update:modelValue',
+			'input',
+			'focus',
+			'blur',
+			'confirm',
+			'clear',
+			'eyes',
+			'change',
+			'keyboardheightchange'
+		],
+		model: {
+			prop: 'modelValue',
+			event: 'update:modelValue'
+		},
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		inject: {
+			form: {
+				from: 'uniForm',
+				default: null
+			},
+			formItem: {
+				from: 'uniFormItem',
+				default: null
+			}
+		},
+		props: {
+			name: String,
+			value: [Number, String],
+			modelValue: [Number, String],
+			type: {
+				type: String,
+				default: 'text'
+			},
+			clearable: {
+				type: Boolean,
+				default: true
+			},
+			autoHeight: {
+				type: Boolean,
+				default: false
+			},
+			placeholder: {
+				type: String,
+				default: ' '
+			},
+			placeholderStyle: String,
+			focus: {
+				type: Boolean,
+				default: false
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			maxlength: {
+				type: [Number, String],
+				default: 140
+			},
+			confirmType: {
+				type: String,
+				default: 'done'
+			},
+			clearSize: {
+				type: [Number, String],
+				default: 24
+			},
+			inputBorder: {
+				type: Boolean,
+				default: true
+			},
+			prefixIcon: {
+				type: String,
+				default: ''
+			},
+			suffixIcon: {
+				type: String,
+				default: ''
+			},
+			trim: {
+				type: [Boolean, String],
+				default: false
+			},
+			cursorSpacing: {
+				type: Number,
+				default: 0
+			},
+			passwordIcon: {
+				type: Boolean,
+				default: true
+			},
+			adjustPosition: {
+				type: Boolean,
+				default: true
+			},
+			primaryColor: {
+				type: String,
+				default: '#2979ff'
+			},
+			styles: {
+				type: Object,
+				default () {
+					return {
+						color: '#333',
+						backgroundColor: '#fff',
+						disableColor: '#F7F6F6',
+						borderColor: '#e5e5e5'
+					};
+				}
+			},
+			errorMessage: {
+				type: [String, Boolean],
+				default: ''
+			},
+			// #ifdef MP-ALIPAY
+			enableNative: {
+				type: Boolean,
+				default: false
+			}
+			// #endif
+		},
+		data() {
+			return {
+				focused: false,
+				val: '',
+				showMsg: '',
+				border: false,
+				isFirstBorder: false,
+				showClearIcon: false,
+				showPassword: false,
+				focusShow: false,
+				localMsg: '',
+				isEnter: false // 用于判断当前是否是使用回车操作
+			};
+		},
+		computed: {
+			// 输入框内是否有值
+			isVal() {
+				const val = this.val;
+				// fixed by mehaotian 处理值为0的情况，字符串0不在处理范围
+				if (val || val === 0) {
+					return true;
+				}
+				return false;
+			},
+
+			msg() {
+				// console.log('computed', this.form, this.formItem);
+				// if (this.form) {
+				// 	return this.errorMessage || this.formItem.errMsg;
+				// }
+				// TODO 处理头条 formItem 中 errMsg 不更新的问题
+				return this.localMsg || this.errorMessage;
+			},
+			// 因为uniapp的input组件的maxlength组件必须要数值，这里转为数值，用户可以传入字符串数值
+			inputMaxlength() {
+				return Number(this.maxlength);
+			},
+
+			// 处理外层样式的style
+			boxStyle() {
+				return `color:${
+					this.inputBorder && this.msg ? '#e43d33' : this.styles.color
+				};`;
+			},
+			// input 内容的类和样式处理
+			inputContentClass() {
+				return obj2strClass({
+					'is-input-border': this.inputBorder,
+					'is-input-error-border': this.inputBorder && this.msg,
+					'is-textarea': this.type === 'textarea',
+					'is-disabled': this.disabled,
+					'is-focused': this.focusShow
+				});
+			},
+			inputContentStyle() {
+				const focusColor = this.focusShow ?
+					this.primaryColor :
+					this.styles.borderColor;
+				const borderColor =
+					this.inputBorder && this.msg ? '#dd524d' : focusColor;
+				return obj2strStyle({
+					'border-color': borderColor || '#e5e5e5',
+					'background-color': this.disabled ?
+						this.styles.disableColor : this.styles.backgroundColor
+				});
+			},
+			// input右侧样式
+			inputStyle() {
+				const paddingRight =
+					this.type === 'password' || this.clearable || this.prefixIcon ?
+					'' :
+					'10px';
+				return obj2strStyle({
+					'padding-right': paddingRight,
+					'padding-left': this.prefixIcon ? '' : '10px'
+				});
+			}
+		},
+		watch: {
+			value(newVal) {
+				// fix by mehaotian 解决 值为null的情况下，input报错的bug
+				if (newVal === null) {
+					this.val = '';
+					return
+				}
+				this.val = newVal;
+			},
+			modelValue(newVal) {
+				if (newVal === null) {
+					this.val = '';
+					return
+				}
+				this.val = newVal;
+			},
+			focus(newVal) {
+				this.$nextTick(() => {
+					this.focused = this.focus;
+					this.focusShow = this.focus;
+				});
+			}
+		},
+		created() {
+			this.init();
+			// TODO 处理头条vue3 computed 不监听 inject 更改的问题（formItem.errMsg）
+			if (this.form && this.formItem) {
+				this.$watch('formItem.errMsg', newVal => {
+					this.localMsg = newVal;
+				});
+			}
+		},
+		mounted() {
+			this.$nextTick(() => {
+				this.focused = this.focus;
+				this.focusShow = this.focus;
+			});
+		},
+		methods: {
+			/**
+			 * 初始化变量值
+			 */
+			init() {
+				if (this.value || this.value === 0) {
+					this.val = this.value;
+				} else if (
+					this.modelValue ||
+					this.modelValue === 0 ||
+					this.modelValue === ''
+				) {
+					this.val = this.modelValue; 
+				} else {
+					// fix by ht 如果初始值为null，则input报错，待框架修复
+					this.val = '';
+				}
+			},
+
+			/**
+			 * 点击图标时触发
+			 * @param {Object} type
+			 */
+			onClickIcon(type) {
+				this.$emit('iconClick', type);
+			},
+
+			/**
+			 * 显示隐藏内容，密码框时生效
+			 */
+			onEyes() {
+				this.showPassword = !this.showPassword;
+				this.$emit('eyes', this.showPassword);
+			},
+
+			/**
+			 * 输入时触发
+			 * @param {Object} event
+			 */
+			onInput(event) {
+				let value = event.detail.value;
+				// 判断是否去除空格
+				if (this.trim) {
+					if (typeof this.trim === 'boolean' && this.trim) {
+						value = this.trimStr(value);
+					}
+					if (typeof this.trim === 'string') {
+						value = this.trimStr(value, this.trim);
+					}
+				}
+				if (this.errMsg) this.errMsg = '';
+				this.val = value;
+				// TODO 兼容 vue2
+				this.$emit('input', value);
+				// TODO　兼容　vue3
+				this.$emit('update:modelValue', value);
+			},
+
+			/**
+			 * 外部调用方法
+			 * 获取焦点时触发
+			 * @param {Object} event
+			 */
+			onFocus() {
+				this.$nextTick(() => {
+					this.focused = true;
+				});
+				this.$emit('focus', null);
+			},
+
+			_Focus(event) {
+				this.focusShow = true;
+				this.$emit('focus', event);
+			},
+
+			/**
+			 * 外部调用方法
+			 * 失去焦点时触发
+			 * @param {Object} event
+			 */
+			onBlur() {
+				this.focused = false;
+				this.$emit('blur', null);
+			},
+			_Blur(event) {
+				let value = event.detail.value;
+				this.focusShow = false;
+				this.$emit('blur', event);
+				// 根据类型返回值，在event中获取的值理论上讲都是string
+				if (this.isEnter === false) {
+					this.$emit('change', this.val);
+				}
+				// 失去焦点时参与表单校验
+				if (this.form && this.formItem) {
+					const { validateTrigger } = this.form;
+					if (validateTrigger === 'blur') {
+						this.formItem.onFieldChange();
+					}
+				}
+			},
+
+			/**
+			 * 按下键盘的发送键
+			 * @param {Object} e
+			 */
+			onConfirm(e) {
+				this.$emit('confirm', this.val);
+				this.isEnter = true;
+				this.$emit('change', this.val);
+				this.$nextTick(() => {
+					this.isEnter = false;
+				});
+			},
+
+			/**
+			 * 清理内容
+			 * @param {Object} event
+			 */
+			onClear(event) {
+				this.val = '';
+				// TODO 兼容 vue2
+				this.$emit('input', '');
+				// TODO 兼容 vue2
+				// TODO　兼容　vue3
+				this.$emit('update:modelValue', '');
+				// 点击叉号触发
+				this.$emit('clear');
+			},
+
+			/**
+			 * 键盘高度发生变化的时候触发此事件
+			 * 兼容性：微信小程序2.7.0+、App 3.1.0+
+			 * @param {Object} event
+			 */
+			onkeyboardheightchange(event) {
+				this.$emit('keyboardheightchange', event);
+			},
+
+			/**
+			 * 去除空格
+			 */
+			trimStr(str, pos = 'both') {
+				if (pos === 'both') {
+					return str.trim();
+				} else if (pos === 'left') {
+					return str.trimLeft();
+				} else if (pos === 'right') {
+					return str.trimRight();
+				} else if (pos === 'start') {
+					return str.trimStart();
+				} else if (pos === 'end') {
+					return str.trimEnd();
+				} else if (pos === 'all') {
+					return str.replace(/\s+/g, '');
+				} else if (pos === 'none') {
+					return str;
+				}
+				return str;
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	$uni-error: #e43d33;
+	$uni-border-1: #dcdfe6 !default;
+
+	.uni-easyinput {
+		/* #ifndef APP-NVUE */
+		width: 100%;
+		/* #endif */
+		flex: 1;
+		position: relative;
+		text-align: left;
+		color: #333;
+		font-size: 14px;
+	}
+
+	.uni-easyinput__content {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		width: 100%;
+		display: flex;
+		box-sizing: border-box;
+		// min-height: 36px;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		// 处理border动画刚开始显示黑色的问题
+		border-color: #fff;
+		transition-property: border-color;
+		transition-duration: 0.3s;
+	}
+
+	.uni-easyinput__content-input {
+		/* #ifndef APP-NVUE */
+		width: auto;
+		/* #endif */
+		position: relative;
+		overflow: hidden;
+		flex: 1;
+		line-height: 1;
+		font-size: 14px;
+		height: 35px;
+		// min-height: 36px;
+
+		/*ifdef H5*/
+		& ::-ms-reveal {
+			display: none;
+		}
+
+		& ::-ms-clear {
+			display: none;
+		}
+
+		& ::-o-clear {
+			display: none;
+		}
+
+		/*endif*/
+	}
+
+	.uni-easyinput__placeholder-class {
+		color: #999;
+		font-size: 12px;
+		// font-weight: 200;
+	}
+
+	.is-textarea {
+		align-items: flex-start;
+	}
+
+	.is-textarea-icon {
+		margin-top: 5px;
+	}
+
+	.uni-easyinput__content-textarea {
+		position: relative;
+		overflow: hidden;
+		flex: 1;
+		line-height: 1.5;
+		font-size: 14px;
+		margin: 6px;
+		margin-left: 0;
+		height: 80px;
+		min-height: 80px;
+		/* #ifndef APP-NVUE */
+		min-height: 80px;
+		width: auto;
+		/* #endif */
+	}
+
+	.input-padding {
+		padding-left: 10px;
+	}
+
+	.content-clear-icon {
+		padding: 0 5px;
+	}
+
+	.label-icon {
+		margin-right: 5px;
+		margin-top: -1px;
+	}
+
+	// 显示边框
+	.is-input-border {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		border: 1px solid $uni-border-1;
+		border-radius: 4px;
+		/* #ifdef MP-ALIPAY */
+		overflow: hidden;
+		/* #endif */
+	}
+
+	.uni-error-message {
+		position: absolute;
+		bottom: -17px;
+		left: 0;
+		line-height: 12px;
+		color: $uni-error;
+		font-size: 12px;
+		text-align: left;
+	}
+
+	.uni-error-msg--boeder {
+		position: relative;
+		bottom: 0;
+		line-height: 22px;
+	}
+
+	.is-input-error-border {
+		border-color: $uni-error;
+
+		.uni-easyinput__placeholder-class {
+			color: mix(#fff, $uni-error, 50%);
+		}
+	}
+
+	.uni-easyinput--border {
+		margin-bottom: 0;
+		padding: 10px 15px;
+		// padding-bottom: 0;
+		border-top: 1px #eee solid;
+	}
+
+	.uni-easyinput-error {
+		padding-bottom: 0;
+	}
+
+	.is-first-border {
+		/* #ifndef APP-NVUE */
+		border: none;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		border-width: 0;
+		/* #endif */
+	}
+
+	.is-disabled {
+		background-color: #f7f6f6;
+		color: #d5d5d5;
+
+		.uni-easyinput__placeholder-class {
+			color: #d5d5d5;
+			font-size: 12px;
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/uni_modules/uni-easyinput/package.json b/uni_modules/uni-easyinput/package.json
index 62bbff56..2939256a 100644
--- a/uni_modules/uni-easyinput/package.json
+++ b/uni_modules/uni-easyinput/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-easyinput",
   "displayName": "uni-easyinput 增强输入框",
-  "version": "1.1.18",
+  "version": "1.1.19",
   "description": "Easyinput 组件是对原生input组件的增强",
   "keywords": [
     "uni-ui",
diff --git a/uni_modules/uni-fab/changelog.md b/uni_modules/uni-fab/changelog.md
index 9bd47292..8a228070 100644
--- a/uni_modules/uni-fab/changelog.md
+++ b/uni_modules/uni-fab/changelog.md
@@ -1,3 +1,5 @@
+## 1.2.6（2024-10-12）
+- 修复 微信小程序中的getSystemInfo警告
 ## 1.2.5（2023-03-29）
 - 新增 pattern.icon 属性，可自定义图标
 ## 1.2.4（2022-09-07）
diff --git a/uni_modules/uni-fab/components/uni-fab/uni-fab.vue b/uni_modules/uni-fab/components/uni-fab/uni-fab.vue
index 43b45314..0cc2ef3d 100644
--- a/uni_modules/uni-fab/components/uni-fab/uni-fab.vue
+++ b/uni_modules/uni-fab/components/uni-fab/uni-fab.vue
@@ -163,9 +163,9 @@
 				return this.getPosition(2, 'horizontal', 'right')
 			},
 			// 计算 nvue bottom
-			nvueBottom() {
-				const safeBottom = uni.getSystemInfoSync().windowBottom;
-				// #ifdef APP-NVUE
+			nvueBottom() {
+				// #ifdef APP-NVUE
+				const safeBottom = uni.getSystemInfoSync().windowBottom;
 				return 30 + safeBottom
 				// #endif
 				// #ifndef APP-NVUE
diff --git a/uni_modules/uni-fab/package.json b/uni_modules/uni-fab/package.json
index 18c08102..1b8543c4 100644
--- a/uni_modules/uni-fab/package.json
+++ b/uni_modules/uni-fab/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-fab",
   "displayName": "uni-fab 悬浮按钮",
-  "version": "1.2.5",
+  "version": "1.2.6",
   "description": "悬浮按钮 fab button ，点击可展开一个图标按钮菜单。",
   "keywords": [
     "uni-ui",
@@ -43,7 +43,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
diff --git a/uni_modules/uni-file-picker/changelog.md b/uni_modules/uni-file-picker/changelog.md
index 24fd817a..00a76cce 100644
--- a/uni_modules/uni-file-picker/changelog.md
+++ b/uni_modules/uni-file-picker/changelog.md
@@ -1,3 +1,9 @@
+## 1.0.11（2024-07-19）
+- 修复 vue3 使用value报错的bug
+## 1.0.10（2024-07-09）
+- 优化 vue3兼容性
+## 1.0.9（2024-07-09）
+- 修复 value 属性不兼容vue3的bug
 ## 1.0.8（2024-03-20）
 - 补充 删除文件时返回文件下标
 ## 1.0.7（2024-02-21）
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js b/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js
index dd60f18a..c4ff85dd 100644
--- a/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js
@@ -82,11 +82,11 @@ function chooseVideo(opts) {
 							name: item.name || '',
 							path: item.tempFilePath,
 							thumbTempFilePath: item.thumbTempFilePath,
-							size: item.size,
+							size:item.size,
 							type: (res.tempFile && res.tempFile.type) || '',
-							width: item.width,
-							height: item.height,
-							duration: item.duration,
+							width:item.width,
+							height:item.height,
+							duration:item.duration,
 							fileType: 'video',
 							cloudPath: '',
 						}
@@ -224,32 +224,6 @@ function uploadCloudFiles(files, max = 5, onUploadProgress) {
 				.then(res => {
 					fileItem.url = res.fileID
 					fileItem.index = index
-
-					// if (isPrivate) {
-					// 	if (!domain) {
-					// 		uni.showToast({
-					// 			title: "私有化上传开启时域名不能为空",
-					// 			icon: "error"
-					// 		})
-					// 		return;
-					// 	}
-					// 	const extStorageManager = uniCloud.getExtStorageManager({
-					// 		provider: "qiniu",
-					// 		domain, // 域名地址
-					// 	});
-					// 	extStorageManager.updateFileStatus({
-					// 		fileID: fileItem.cloudPath, // 待修改的文件
-					// 		isPrivate: true, // true 私有 false 公共
-					// 	}).then(res => {
-					// 		console.log(res);
-					// 		if (res.errCode !== 0) {
-					// 			uni.showToast({
-					// 				title: res.errMsg,
-					// 				icon: "error"
-					// 			})
-					// 		}
-					// 	})
-					// }
 					if (cur < len) {
 						next()
 					}
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue b/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue
index bd099c7e..95eaf304 100644
--- a/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue
@@ -89,24 +89,18 @@
 		},
 		emits: ['select', 'success', 'fail', 'progress', 'delete', 'update:modelValue', 'input'],
 		props: {
-			// #ifdef VUE3
 			modelValue: {
 				type: [Array, Object],
 				default () {
 					return []
 				}
 			},
-			// #endif
-
-			// #ifndef VUE3
 			value: {
 				type: [Array, Object],
 				default () {
 					return []
 				}
 			},
-			// #endif
-
 			disabled: {
 				type: Boolean,
 				default: false
@@ -204,22 +198,18 @@
 			}
 		},
 		watch: {
-			// #ifndef VUE3
 			value: {
 				handler(newVal, oldVal) {
 					this.setValue(newVal, oldVal)
 				},
 				immediate: true
 			},
-			// #endif
-			// #ifdef VUE3
 			modelValue: {
 				handler(newVal, oldVal) {
 					this.setValue(newVal, oldVal)
 				},
 				immediate: true
 			},
-			// #endif
 		},
 		computed: {
 			filesList() {
diff --git a/uni_modules/uni-file-picker/package.json b/uni_modules/uni-file-picker/package.json
index 9bcf4309..b3650748 100644
--- a/uni_modules/uni-file-picker/package.json
+++ b/uni_modules/uni-file-picker/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-file-picker",
   "displayName": "uni-file-picker 文件选择上传",
-  "version": "1.0.8",
+  "version": "1.0.11",
   "description": "文件选择上传组件，可以选择图片、视频等任意文件并上传到当前绑定的服务空间",
   "keywords": [
     "uni-ui",
@@ -42,7 +42,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
diff --git a/uni_modules/uni-forms/changelog.md b/uni_modules/uni-forms/changelog.md
index 3d998bcf..0b58ab86 100644
--- a/uni_modules/uni-forms/changelog.md
+++ b/uni_modules/uni-forms/changelog.md
@@ -1,3 +1,9 @@
+## 1.4.13（2024-10-08）
+- 修复 校验规则在抖音开发者工具上不生效的bug，详见：[https://ask.dcloud.net.cn/question/191933](https://ask.dcloud.net.cn/question/191933)
+## 1.4.12 (2024-9-21)
+- 修复 form上次修改的问题
+## 1.4.11 (2024-9-14)
+- 修复 binddata的兼容性问题
 ## 1.4.10（2023-11-03）
 - 优化 labelWidth 描述错误
 ## 1.4.9（2023-02-10）
diff --git a/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue b/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue
index 59b0528d..6af50aaa 100644
--- a/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue
+++ b/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue
@@ -56,8 +56,13 @@
 
 	export default {
 		name: 'uniFormsItem',
-		options: {
-			virtualHost: true
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
 		},
 		provide() {
 			return {
diff --git a/uni_modules/uni-forms/components/uni-forms/uni-forms.vue b/uni_modules/uni-forms/components/uni-forms/uni-forms.vue
index b484cc9d..64dde2a7 100644
--- a/uni_modules/uni-forms/components/uni-forms/uni-forms.vue
+++ b/uni_modules/uni-forms/components/uni-forms/uni-forms.vue
@@ -67,8 +67,13 @@
 	export default {
 		name: 'uniForms',
 		emits: ['validate', 'submit'],
-		options: {
-			virtualHost: true
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
 		},
 		props: {
 			// 即将弃用
@@ -180,15 +185,17 @@
 							}
 						}
 						if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
-						formVm.setValue(name, value);
+						if(formVm.model)formVm.model[name] = value
+						if(formVm.modelValue)formVm.modelValue[name] = value
+						if(formVm.value)formVm.value[name] = value
 					}
 				}
 			}
 			// #endif
 
 			// 子组件实例数组
-			this.childrens = []
-			// TODO 兼容旧版 uni-data-picker ,新版本中无效，只是避免报错
+			this.childrens = []
+			// TODO 兼容旧版 uni-data-picker ,新版本中无效，只是避免报错
 			this.inputChildrens = []
 			this.setRules(this.rules)
 		},
@@ -394,4 +401,4 @@
 
 <style lang="scss">
 	.uni-forms {}
-</style>
+</style>
diff --git a/uni_modules/uni-forms/package.json b/uni_modules/uni-forms/package.json
index 464b4e6c..0d72c632 100644
--- a/uni_modules/uni-forms/package.json
+++ b/uni_modules/uni-forms/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-forms",
   "displayName": "uni-forms 表单",
-  "version": "1.4.10",
+  "version": "1.4.13",
   "description": "由输入框、选择器、单选框、多选框等控件组成，用以收集、校验、提交数据",
   "keywords": [
     "uni-ui",
@@ -46,7 +46,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
diff --git a/uni_modules/uni-icons/changelog.md b/uni_modules/uni-icons/changelog.md
index 620ab027..02611315 100644
--- a/uni_modules/uni-icons/changelog.md
+++ b/uni_modules/uni-icons/changelog.md
@@ -1,3 +1,5 @@
+## 2.0.10（2024-06-07）
+- 优化 uni-app x 中，size 属性的类型
 ## 2.0.9（2024-01-12）
 fix: 修复图标大小默认值错误的问题
 ## 2.0.8（2023-12-14）
diff --git a/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
index a975b4a9..ce307c17 100644
--- a/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
+++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
@@ -1,91 +1,91 @@
 <template>
-	<text class="uni-icons" :style="styleObj">
-		<slot>{{unicode}}</slot>
-	</text>
+  <text class="uni-icons" :style="styleObj">
+    <slot>{{unicode}}</slot>
+  </text>
 </template>
 
 <script>
-	import { fontData, IconsDataItem } from './uniicons_file'
+  import { fontData, IconsDataItem } from './uniicons_file'
 
-	/**
-	 * Icons 图标
-	 * @description 用于展示 icon 图标
-	 * @tutorial https://ext.dcloud.net.cn/plugin?id=28
-	 * @property {Number} size 图标大小
-	 * @property {String} type 图标图案，参考示例
-	 * @property {String} color 图标颜色
-	 * @property {String} customPrefix 自定义图标
-	 * @event {Function} click 点击 Icon 触发事件
-	 */
-	export default {
-		name: "uni-icons",
-		props: {
-			type: {
-				type: String,
-				default: ''
-			},
-			color: {
-				type: String,
-				default: '#333333'
-			},
-			size: {
-				type: Object,
-				default: 16
-			},
-			fontFamily: {
-				type: String,
-				default: ''
-			}
-		},
-		data() {
-			return {};
-		},
-		computed: {
-			unicode() : string {
-				let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
-				if (codes !== null) {
-					return codes.unicode
-				}
-				return ''
-			},
-			iconSize() : string {
-				const size = this.size
-				if (typeof size == 'string') {
-					const reg = /^[0-9]*$/g
-					return reg.test(size as string) ? '' + size + 'px' : '' + size;
-					// return '' + this.size
-				}
-				return this.getFontSize(size as number)
-			},
-			styleObj() : UTSJSONObject {
-				if (this.fontFamily !== '') {
-					return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
-				}
-				return { color: this.color, fontSize: this.iconSize }
-			}
-		},
-		created() { },
-		methods: {
-			/**
-			 * 字体大小
-			 */
-			getFontSize(size : number) : string {
-				return size + 'px';
-			},
-		},
-	}
+  /**
+   * Icons 图标
+   * @description 用于展示 icon 图标
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=28
+   * @property {Number,String} size 图标大小
+   * @property {String} type 图标图案，参考示例
+   * @property {String} color 图标颜色
+   * @property {String} customPrefix 自定义图标
+   * @event {Function} click 点击 Icon 触发事件
+   */
+  export default {
+    name: "uni-icons",
+    props: {
+      type: {
+        type: String,
+        default: ''
+      },
+      color: {
+        type: String,
+        default: '#333333'
+      },
+      size: {
+        type: [Number, String],
+        default: 16
+      },
+      fontFamily: {
+        type: String,
+        default: ''
+      }
+    },
+    data() {
+      return {};
+    },
+    computed: {
+      unicode() : string {
+        let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
+        if (codes !== null) {
+          return codes.unicode
+        }
+        return ''
+      },
+      iconSize() : string {
+        const size = this.size
+        if (typeof size == 'string') {
+          const reg = /^[0-9]*$/g
+          return reg.test(size as string) ? '' + size + 'px' : '' + size;
+          // return '' + this.size
+        }
+        return this.getFontSize(size as number)
+      },
+      styleObj() : UTSJSONObject {
+        if (this.fontFamily !== '') {
+          return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
+        }
+        return { color: this.color, fontSize: this.iconSize }
+      }
+    },
+    created() { },
+    methods: {
+      /**
+       * 字体大小
+       */
+      getFontSize(size : number) : string {
+        return size + 'px';
+      },
+    },
+  }
 </script>
 
 <style scoped>
-	@font-face {
-		font-family: UniIconsFontFamily;
-		src: url('./uniicons.ttf');
-	}
+  @font-face {
+    font-family: UniIconsFontFamily;
+    src: url('./uniicons.ttf');
+  }
 
-	.uni-icons {
-		font-family: UniIconsFontFamily;
-		font-size: 18px;
-		font-style: normal;
-		color: #333;
-	}
+  .uni-icons {
+    font-family: UniIconsFontFamily;
+    font-size: 18px;
+    font-style: normal;
+    color: #333;
+  }
 </style>
diff --git a/uni_modules/uni-icons/package.json b/uni_modules/uni-icons/package.json
index 397be839..6b681b42 100644
--- a/uni_modules/uni-icons/package.json
+++ b/uni_modules/uni-icons/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-icons",
   "displayName": "uni-icons 图标",
-  "version": "2.0.9",
+  "version": "2.0.10",
   "description": "图标组件，用于展示移动端常见的图标，可自定义颜色、大小。",
   "keywords": [
     "uni-ui",
@@ -42,7 +42,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
diff --git a/uni_modules/uni-id/changelog.md b/uni_modules/uni-id/changelog.md
index 8761e543..5c0274de 100644
--- a/uni_modules/uni-id/changelog.md
+++ b/uni_modules/uni-id/changelog.md
@@ -1,3 +1,7 @@
+## 3.3.33（2025-01-08）
+- 修改文档图片链接
+## 3.3.32（2024-04-26）
+- 兼容uni-app-x对客户端uniPlatform的调整（uni-app-x内uniPlatform区分app-android、app-ios）
 ## 3.3.31（2023-12-13）
 - 移除无用文件
 ## 3.3.30（2023-12-13）
@@ -63,55 +67,55 @@
 - 移除部分接口的废弃提示
 ## 3.3.6（2021-09-08）
 - 修复 邀请码可能重复的Bug
-## 3.3.5（2021-08-10）
-- 修复版本号错误
-## 3.3.4（2021-08-10）
-- 微信、QQ、支付宝登录新增type参数用于指定当前是登录还是注册
-## 3.3.3（2021-08-04）
-- 修复使用数组形式的配置文件报错的Bug
-## 3.3.2（2021-08-03）
-- 修复上3.3.0版本引出的createInstance接口传入配置不生效的Bug 感谢[hmh](https://gitee.com/hmh)
-## 3.3.1（2021-07-30）
-- 修复 将设置用户允许登录的应用列表时传入空数组报错的Bug
-## 3.3.0（2021-07-30）
-- 新增 不同端应用配置隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-config)
-- 新增 不同端用户隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-user)
-  + 此版本升级需要开发者处理一下用户数据，请参考 [补齐用户dcloud_appid字段](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=makeup-dcloud-appid)
-- 新增 QQ登录、注册相关功能 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=qq)
-- 调整 不再支持绑定手机、邮箱时不填验证码直接绑定
-## 3.2.1（2021-07-09）
-- 撤销3.2.0版本所做的调整
-## 3.2.0（2021-07-09）
-- 【重要】支持不同端（管理端、用户端等）用户隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-user)
-- 支持不同端（管理端、用户端等）配置文件隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-config)
-## 3.1.3（2021-07-08）
-- 移除插件内误传的node_modules
-## 3.1.2（2021-07-08）
-- 修复 微信小程序绑定微信账号时报错的Bug
-## 3.1.1（2021-07-01）
-- 使用新的错误码规范，兼容旧版 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=errcode)
-- 修复微信登录、绑定时未返回用户accessToken的Bug
-## 3.1.0（2021-04-19）
-- 增加对用户名、邮箱、密码字段的两端去空格
-- 默认忽略用户名、邮箱的大小写 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=case-sensitive)
-- 修复 customToken导出async方法报错的Bug
-## 3.0.12（2021-04-13）
-- 调整bindTokenToDevice默认值为false
-## 3.0.11（2021-04-12）
-- 修复3.0.7版本引出的多个用户访问时可能出现30201报错的Bug
-## 3.0.10（2021-04-08）
-- 优化错误提示
-## 3.0.9（2021-04-08）
-- bindMobile接口支持通过一键登录的方式绑定
-- 优化错误提示
-## 3.0.8（2021-03-19）
-- 修复 3.0.7版本某些情况下生成token报错的Bug
-## 3.0.7（2021-03-19）
-- 新增 支持uni-config-center，更新uni-id无须再担心配置被覆盖 [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=uni-config-center)
-- 新增 自定义token内容，可以缓存角色权限之外的更多信息到客户端 [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=custom-token)
-- 新增 支持传入context获取uni-id实例，防止单实例多并发时全局context混乱 [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=create-instance)
-## 3.0.6（2021-03-05）
-- 新增[uniID.wxBizDataCrypt](https://uniapp.dcloud.io/uniCloud/uni-id?id=%e5%be%ae%e4%bf%a1%e6%95%b0%e6%8d%ae%e8%a7%a3%e5%af%86)方法
-- 优化loginByApple方法，提高接口响应速度
-## 3.0.5（2021-02-03）
-- 调整为uni_modules目录规范
+## 3.3.5（2021-08-10）
+- 修复版本号错误
+## 3.3.4（2021-08-10）
+- 微信、QQ、支付宝登录新增type参数用于指定当前是登录还是注册
+## 3.3.3（2021-08-04）
+- 修复使用数组形式的配置文件报错的Bug
+## 3.3.2（2021-08-03）
+- 修复上3.3.0版本引出的createInstance接口传入配置不生效的Bug 感谢[hmh](https://gitee.com/hmh)
+## 3.3.1（2021-07-30）
+- 修复 将设置用户允许登录的应用列表时传入空数组报错的Bug
+## 3.3.0（2021-07-30）
+- 新增 不同端应用配置隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-config)
+- 新增 不同端用户隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-user)
+  + 此版本升级需要开发者处理一下用户数据，请参考 [补齐用户dcloud_appid字段](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=makeup-dcloud-appid)
+- 新增 QQ登录、注册相关功能 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=qq)
+- 调整 不再支持绑定手机、邮箱时不填验证码直接绑定
+## 3.2.1（2021-07-09）
+- 撤销3.2.0版本所做的调整
+## 3.2.0（2021-07-09）
+- 【重要】支持不同端（管理端、用户端等）用户隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-user)
+- 支持不同端（管理端、用户端等）配置文件隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-config)
+## 3.1.3（2021-07-08）
+- 移除插件内误传的node_modules
+## 3.1.2（2021-07-08）
+- 修复 微信小程序绑定微信账号时报错的Bug
+## 3.1.1（2021-07-01）
+- 使用新的错误码规范，兼容旧版 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=errcode)
+- 修复微信登录、绑定时未返回用户accessToken的Bug
+## 3.1.0（2021-04-19）
+- 增加对用户名、邮箱、密码字段的两端去空格
+- 默认忽略用户名、邮箱的大小写 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=case-sensitive)
+- 修复 customToken导出async方法报错的Bug
+## 3.0.12（2021-04-13）
+- 调整bindTokenToDevice默认值为false
+## 3.0.11（2021-04-12）
+- 修复3.0.7版本引出的多个用户访问时可能出现30201报错的Bug
+## 3.0.10（2021-04-08）
+- 优化错误提示
+## 3.0.9（2021-04-08）
+- bindMobile接口支持通过一键登录的方式绑定
+- 优化错误提示
+## 3.0.8（2021-03-19）
+- 修复 3.0.7版本某些情况下生成token报错的Bug
+## 3.0.7（2021-03-19）
+- 新增 支持uni-config-center，更新uni-id无须再担心配置被覆盖 [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=uni-config-center)
+- 新增 自定义token内容，可以缓存角色权限之外的更多信息到客户端 [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=custom-token)
+- 新增 支持传入context获取uni-id实例，防止单实例多并发时全局context混乱 [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=create-instance)
+## 3.0.6（2021-03-05）
+- 新增[uniID.wxBizDataCrypt](https://uniapp.dcloud.io/uniCloud/uni-id?id=%e5%be%ae%e4%bf%a1%e6%95%b0%e6%8d%ae%e8%a7%a3%e5%af%86)方法
+- 优化loginByApple方法，提高接口响应速度
+## 3.0.5（2021-02-03）
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-id/package.json b/uni_modules/uni-id/package.json
index 11882b6d..7f999213 100644
--- a/uni_modules/uni-id/package.json
+++ b/uni_modules/uni-id/package.json
@@ -1,85 +1,88 @@
-{
-  "id": "uni-id",
-  "displayName": "uni-id",
-  "version": "3.3.31",
-  "description": "简单、统一、可扩展的用户中心",
-  "keywords": [
-    "uniid",
-    "uni-id",
-    "用户管理",
-    "用户中心",
-    "短信验证码"
-],
-  "repository": "https://gitee.com/dcloud/uni-id.git",
-  "engines": {
-    "HBuilderX": "^3.1.0"
-  },
-  "dcloudext": {
-    "sale": {
-      "regular": {
-        "price": "0.00"
-      },
-      "sourcecode": {
-        "price": "0.00"
-      }
-    },
-    "contact": {
-      "qq": ""
-    },
-    "declaration": {
-      "ads": "无",
-      "data": "无",
-      "permissions": "无"
-    },
-    "npmurl": "",
-    "type": "unicloud-template-function"
-  },
-  "uni_modules": {
-    "dependencies": ["uni-config-center", "uni-open-bridge-common"],
-    "encrypt": [],
-    "platforms": {
-      "cloud": {
-        "tcb": "y",
-        "aliyun": "y"
-      },
-      "client": {
-        "App": {
-          "app-vue": "u",
-          "app-nvue": "u"
-        },
-        "H5-mobile": {
-          "Safari": "u",
-          "Android Browser": "u",
-          "微信浏览器(Android)": "u",
-          "QQ浏览器(Android)": "u"
-        },
-        "H5-pc": {
-          "Chrome": "u",
-          "IE": "u",
-          "Edge": "u",
-          "Firefox": "u",
-          "Safari": "u"
-        },
-        "小程序": {
-          "微信": "u",
-          "阿里": "u",
-          "百度": "u",
-          "字节跳动": "u",
-          "QQ": "u",
-          "钉钉": "u",
-          "快手": "u",
-          "飞书": "u",
-          "京东": "u"
-        },
-        "快应用": {
-          "华为": "u",
-          "联盟": "u"
-        },
-        "Vue": {
-          "vue2": "y",
-          "vue3": "u"
-        }
-      }
-    }
-  }
+{
+  "id": "uni-id",
+  "displayName": "uni-id",
+  "version": "3.3.33",
+  "description": "简单、统一、可扩展的用户中心",
+  "keywords": [
+    "uniid",
+    "uni-id",
+    "用户管理",
+    "用户中心",
+    "短信验证码"
+],
+  "repository": "https://gitee.com/dcloud/uni-id.git",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "",
+    "type": "unicloud-template-function"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-config-center", "uni-open-bridge-common"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "y"
+      },
+      "client": {
+        "App": {
+            "app-vue": "u",
+            "app-nvue": "u",
+            "app-harmony": "u",
+            "app-uvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "u",
+          "Android Browser": "u",
+          "微信浏览器(Android)": "u",
+          "QQ浏览器(Android)": "u"
+        },
+        "H5-pc": {
+          "Chrome": "u",
+          "IE": "u",
+          "Edge": "u",
+          "Firefox": "u",
+          "Safari": "u"
+        },
+        "小程序": {
+          "微信": "u",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+          "QQ": "u",
+          "钉钉": "u",
+          "快手": "u",
+          "飞书": "u",
+          "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+          "vue2": "y",
+          "vue3": "u"
+        }
+      }
+    }
+  }
 }
diff --git a/uni_modules/uni-id/readme.md b/uni_modules/uni-id/readme.md
index 68901213..5bcfd098 100644
--- a/uni_modules/uni-id/readme.md
+++ b/uni_modules/uni-id/readme.md
@@ -1,33 +1,33 @@
-**文档已移至[uni-id文档](https://uniapp.dcloud.net.cn/uniCloud/uni-id)**
-
-> 一般uni-id升级大版本时为不兼容更新，从低版本迁移到高版本请参考：[uni-id迁移指南](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=migration)
-
-## 重要升级说明
-
-**uni-id 3.x版本，搭配的uniCloud admin版本需大于1.2.10。**
-
-### 缓存角色权限
-
-自`uni-id 3.0.0`起，支持在token内缓存用户的角色权限，默认开启此功能，各登录接口的needPermission参数不再生效。如需关闭请在config内配置`"removePermissionAndRoleFromToken": true`。
-
-为什么要缓存角色权限？要知道云数据库是按照读写次数来收取费用的，并且读写数据库会拖慢接口响应速度。未配置`"removePermissionAndRoleFromToken": true`的情况下，可以在调用checkToken接口时不查询数据库获取用户角色权限。
-
-详细checkToken流程如下：
-
-![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/ed45d350-5a4d-11eb-b997-9918a5dda011.jpg)
-
-可以看出，旧版token（removePermissionAndRoleFromToken为true时生成的）在checkToken时如需返回权限需要进行两次数据库查询。新版token不需要查库即可返回权限信息。
-
-**注意**
-
-- 由于角色权限缓存在token内，可能会存在权限已经更新但是用户token未过期之前依然是旧版角色权限的情况。可以调短一些token过期时间来减少这种情况的影响。
-- admin角色token内不包含permission，如需自行判断用户是否有某个权限，要注意admin角色需要额外判断一下，写法如下
-  ```js
-  const {
-    role,
-    permission
-  } = await uniID.checkToken(event.uniIdToken)
-  if(role.includes('admin') || permission.includes('your permission id')) {
-    // 当前角色拥有'your permission id'对应的权限
-  }
+**文档已移至[uni-id文档](https://doc.dcloud.net.cn/uniCloud/uni-id/old.html)**
+
+> 一般uni-id升级大版本时为不兼容更新，从低版本迁移到高版本请参考：[uni-id迁移指南](https://doc.dcloud.net.cn/uniCloud/uni-id/old.html#m1to2)
+
+## 重要升级说明
+
+**uni-id 3.x版本，搭配的uniCloud admin版本需大于1.2.10。**
+
+### 缓存角色权限
+
+自`uni-id 3.0.0`起，支持在token内缓存用户的角色权限，默认开启此功能，各登录接口的needPermission参数不再生效。如需关闭请在config内配置`"removePermissionAndRoleFromToken": true`。
+
+为什么要缓存角色权限？要知道云数据库是按照读写次数来收取费用的，并且读写数据库会拖慢接口响应速度。未配置`"removePermissionAndRoleFromToken": true`的情况下，可以在调用checkToken接口时不查询数据库获取用户角色权限。
+
+详细checkToken流程如下：
+
+![](https://web-ext-storage.dcloud.net.cn/ext/uni-id/uni-id-flow.jpg)
+
+可以看出，旧版token（removePermissionAndRoleFromToken为true时生成的）在checkToken时如需返回权限需要进行两次数据库查询。新版token不需要查库即可返回权限信息。
+
+**注意**
+
+- 由于角色权限缓存在token内，可能会存在权限已经更新但是用户token未过期之前依然是旧版角色权限的情况。可以调短一些token过期时间来减少这种情况的影响。
+- admin角色token内不包含permission，如需自行判断用户是否有某个权限，要注意admin角色需要额外判断一下，写法如下
+  ```js
+  const {
+    role,
+    permission
+  } = await uniID.checkToken(event.uniIdToken)
+  if(role.includes('admin') || permission.includes('your permission id')) {
+    // 当前角色拥有'your permission id'对应的权限
+  }
   ```
\ No newline at end of file
diff --git a/uni_modules/uni-id/uni-id.zip b/uni_modules/uni-id/uni-id.zip
deleted file mode 100644
index 82cc8993..00000000
Binary files a/uni_modules/uni-id/uni-id.zip and /dev/null differ
diff --git a/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/LICENSE.md b/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/LICENSE.md
index 29f81d81..261eeb9e 100644
--- a/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/LICENSE.md
+++ b/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/LICENSE.md
@@ -1,201 +1,201 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js b/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js
index a8534bf2..c9b8e483 100644
--- a/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js
+++ b/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js
@@ -1 +1 @@
-"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var t=e(require("crypto")),r=e(require("buffer")),n=e(require("stream")),i=e(require("util"));const o={PARAM_ERROR:{errCode:"param-error"},PARAM_REQUIRED:{errCode:"param-required"},USER_NOT_EXIST:{errCode:"user-not-exist"},ROLE_NOT_EXIST:{errCode:"role-not-exist"},PERMISSION_NOT_EXIST:{errCode:"permission-not-exist"},MULTI_USER_MATCHED:{errCode:"multi-user-matched"},USER_INFO_ERROR:{errCode:"user-info-error"},USER_ACCOUNT_CONFLICT:{errCode:"user-account-conflict"},USER_ACCOUNT_CLOSED:{errCode:"user-account-closed"},ACCOUNT_EXISTS:{errCode:"account-exists"},ACCOUNT_NOT_EXISTS:{errCode:"account-not-exists"},ACCOUNT_BOUND:{errCode:"account-bound"},UNBIND_FAILED:{errCode:"unbind-failed"},INVALID_INVITE_CODE:{errCode:"invalid-invite-code"},SET_INVITE_CODE_FAILED:{errCode:"set-invite-code-failed"},GET_THIRD_PARTY_ACCOUNT_FAILED:{errCode:"get-third-party-account-failed"},GET_THIRD_PARTY_USER_INFO_FAILED:{errCode:"get-third-party-user-info-failed"}},s={0:{errCode:0,errMsg:""},10001:{errCode:"account-banned"},10002:o.USER_NOT_EXIST,10003:o.MULTI_USER_MATCHED,10004:o.USER_INFO_ERROR,10005:o.USER_ACCOUNT_CONFLICT,10006:o.USER_ACCOUNT_CLOSED,10102:{errCode:"password-error"},10103:{errCode:"password-error-exceed-limit"},10201:o.ACCOUNT_EXISTS,10202:o.ACCOUNT_NOT_EXISTS,10203:o.INVALID_INVITE_CODE,10301:o.ACCOUNT_EXISTS,10302:o.ACCOUNT_NOT_EXISTS,10401:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10402:o.ACCOUNT_EXISTS,10403:o.ACCOUNT_NOT_EXISTS,10501:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10502:o.ACCOUNT_EXISTS,10503:o.ACCOUNT_NOT_EXISTS,10601:o.ACCOUNT_EXISTS,10602:o.ACCOUNT_NOT_EXISTS,10701:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10702:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10703:o.ACCOUNT_EXISTS,10704:o.ACCOUNT_NOT_EXISTS,10705:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10706:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10801:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10802:o.ACCOUNT_EXISTS,10803:o.ACCOUNT_NOT_EXISTS,20101:o.PARAM_REQUIRED,20102:o.ACCOUNT_EXISTS,30101:o.PARAM_REQUIRED,30201:{errCode:"check-device-feature-failed"},30202:{errCode:"token-not-exist"},30203:{errCode:"token-expired"},30204:{errCode:"check-token-failed"},40201:o.USER_NOT_EXIST,40202:{errCode:"invalid-old-password"},50101:o.PARAM_REQUIRED,50102:o.PARAM_ERROR,50201:o.PARAM_REQUIRED,50203:o.PARAM_ERROR,50202:{errCode:"invalid-verify-code"},50301:{errCode:"send-sms-code-failed"},60101:o.ACCOUNT_BOUND,60201:o.ACCOUNT_BOUND,60301:o.GET_THIRD_PARTY_ACCOUNT_FAILED,60302:o.ACCOUNT_BOUND,60401:o.GET_THIRD_PARTY_ACCOUNT_FAILED,60402:o.ACCOUNT_BOUND,60501:o.GET_THIRD_PARTY_ACCOUNT_FAILED,60502:o.ACCOUNT_BOUND,70101:o.UNBIND_FAILED,70201:o.UNBIND_FAILED,70301:o.UNBIND_FAILED,70401:o.UNBIND_FAILED,70501:o.UNBIND_FAILED,80301:o.USER_NOT_EXIST,80401:o.SET_INVITE_CODE_FAILED,80402:o.SET_INVITE_CODE_FAILED,80501:o.INVALID_INVITE_CODE,80502:o.USER_NOT_EXIST,80503:{errCode:"modify-invite-code-is-not-allowed"},80601:o.GET_THIRD_PARTY_ACCOUNT_FAILED,80602:o.GET_THIRD_PARTY_ACCOUNT_FAILED,80701:o.GET_THIRD_PARTY_ACCOUNT_FAILED,80702:o.GET_THIRD_PARTY_ACCOUNT_FAILED,80801:{errCode:"decrypt-weixin-data-failed"},80802:{errCode:"decrypt-weixin-data-failed"},80803:{errCode:"invalid-weixin-appid"},80804:o.PARAM_REQUIRED,80805:o.PARAM_REQUIRED,80806:o.PARAM_REQUIRED,80901:o.GET_THIRD_PARTY_USER_INFO_FAILED,90001:{errCode:"database-operation-failed"},90002:o.PARAM_REQUIRED,90003:o.PARAM_ERROR,90004:o.USER_NOT_EXIST,90005:o.ROLE_NOT_EXIST,90006:o.PERMISSION_NOT_EXIST};class a extends Error{constructor(e){super(e.message),this.errMsg=e.message||"",Object.defineProperties(this,{message:{get(){return`errCode: ${e.code||""} | errMsg: `+this.errMsg},set(e){this.errMsg=e}}})}}const c=Object.prototype.toString,u=Object.prototype.hasOwnProperty;function d(e,t){return u.call(e,t)}function p(e){return"[object Object]"===c.call(e)}function l(e){return"function"==typeof e}function f(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof e.then}function m(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}const h=/_(\w)/g,g=/[A-Z]/g;function y(e){return e.replace(h,(e,t)=>t?t.toUpperCase():"")}function w(e){return e.replace(g,e=>"_"+e.toLowerCase())}function _(e,t){let r,n;switch(t){case"snake2camel":n=y,r=h;break;case"camel2snake":n=w,r=g}for(const i in e)if(d(e,i)&&r.test(i)){const r=n(i);e[r]=e[i],delete e[i],p(e[r])?e[r]=_(e[r],t):Array.isArray(e[r])&&(e[r]=e[r].map(e=>_(e,t)))}return e}function v(e){return _(e,"snake2camel")}function b(e){return _(e,"camel2snake")}function T(e){return function(e,t="-"){e=e||new Date;const r=[];return r.push(e.getFullYear()),r.push(("00"+(e.getMonth()+1)).substr(-2)),r.push(("00"+e.getDate()).substr(-2)),r.join(t)}(e=e||new Date)+" "+function(e,t=":"){e=e||new Date;const r=[];return r.push(("00"+e.getHours()).substr(-2)),r.push(("00"+e.getMinutes()).substr(-2)),r.push(("00"+e.getSeconds()).substr(-2)),r.join(t)}(e)}function E(){"development"===process.env.NODE_ENV&&console.log(...arguments)}function C(e=6){let t="";for(let r=0;r<e;r++)t+=Math.floor(10*Math.random());return t}function A(e){return Array.from(new Set(e))}function x(e={},t){if(!t||!e)return e;const r=["_pre","_purify","_post"];t._pre&&(e=t._pre(e));let n={shouldDelete:new Set([])};if(t._purify){const e=t._purify;for(const t in e)e[t]=new Set(e[t]);n=Object.assign(n,e)}if(p(t))for(const i in t){const o=t[i];l(o)&&-1===r.indexOf(i)?e[i]=o(e):"string"==typeof o&&-1===r.indexOf(i)&&(e[i]=e[o],n.shouldDelete.add(o))}else l(t)&&(e=t(e));if(n.shouldDelete)for(const t of n.shouldDelete)delete e[t];return t._post&&(e=t._post(e)),e}function I(e,t){const r=new e(t);return new Proxy(r,{get:function(e,t){if("function"==typeof e[t]&&0!==t.indexOf("_")&&e._protocols&&e._protocols[t]){const r=e._protocols[t];return async function(n){n=x(n,r.args);let i=await e[t](n);return i=x(i,r.returnValue),i}}return e[t]}})}function S(e){if(p(e))if(0===e.code)e.errCode=e.code,e.message=e.errMsg=e.msg,delete e.messageValues;else if(d(s,e.code)){const t=s[e.code];e.errCode="uni-id-"+t.errCode,e.errMsg=this.t(t.errCode,e.messageValues||{})||e.msg,e.message=e.msg=e.errMsg,delete e.messageValues}else e.code&&console.warn(`error code not found, error code: ${e.code}, please contact us`)}var k={"zh-Hans":{alipay:"支付宝",wechat:"微信",user:"用户","user-id":"用户ID","dcloud-appid":"应用Appid","dcloud-appid-list":"应用列表",account:"账号",username:"用户名",email:"邮箱",mobile:"手机号",sms:"短信","wechat-openid":"微信openid","wechat-account":"微信账号","alipay-account":"支付宝账号","qq-openid":"QQ openid","qq-account":"QQ账号","apple-account":"苹果账号",password:"密码","verify-code":"验证码","verify-code-type":"验证码类型","user-unique-param":"用户名、邮箱或手机号","role-id":"角色ID","permission-id":"权限ID",login:"登录","verify-mobile":"验证手机","context-param-required":"context内缺少{param}，请使用uniID.createInstance传入客户端信息","config-param-require":"uni-id的配置内缺少{param}","uni-verify-config-required":"请在config.json中配置service.univerify下一键登录相关参数","login-with-invite-type-required":"强制使用邀请码注册时，需指明type为register还是login","type-array-required":"{param}应为数组形式","query-field-warning":"检测到当前使用queryField匹配多字段进行登录操作，需要注意：uni-id并未限制用户名不能是手机号或邮箱，需要开发者自行限制。否则可能出现用户输入abc@xx.com会同时匹配到邮箱为此值的用户和用户名为此值的用户，导致登录失败","add-role-admin-is-not-allowed":"不可新增roleID为admin的角色","password-secret-type-error":"config内passwordSecret类型错误，只可设置string类型和array类型","token-expires-config-warning":"tokenExpiresIn不可小于或等于tokenExpiresThreshold","type-function-required":"{param}应为function类型","dev-warning":"当前正在使用uniID.dev属性，注意此属性仅可用于开发调试","config-file-invalid":"请确保公用模块uni-id对应的配置文件（common/uni-config-center/uni-id/config.json）格式正确（不可包含注释）","config-file-not-found":"请在common/uni-config-center/uni-id/config.json内添加uni-id相关配置信息","hx-version-warning":"当前使用的HBuilderX版本过低，请升级HBuilderX到最新版本","account-banned":"账号已禁用","user-not-exist":"用户不存在","multi-user-matched":"匹配到多个账号","user-info-error":"用户信息不正确","user-account-conflict":"用户账号冲突","user-account-closed":"此账号已注销","password-error":"密码错误","password-error-exceed-limit":"密码错误次数过多，请稍后再试","account-exists":"此账号已注册","account-not-exists":"此账号尚未注册","invalid-invite-code":"邀请码无效","get-third-party-account-failed":"获取{account}失败","get-third-party-user-info-failed":"获取用户信息失败","param-required":"{param}不可为空","check-device-feature-failed":"设备特征校验未通过","token-not-exist":"登录状态无效，云端已不包含此token","token-expired":"token已过期","check-token-failed":"token校验未通过","invalid-old-password":"旧密码错误","param-error":"{param}参数错误，{reason}","invalid-verify-code":"{type}验证码错误或已失效","send-sms-code-failed":"短信验证码发送失败","account-bound":"此账号已被绑定","unbind-failed":"解绑失败","set-invite-code-failed":"邀请码设置失败","modify-invite-code-is-not-allowed":"邀请码不可修改","decrypt-weixin-data-failed":"解密失败","invalid-weixin-appid":"appid不匹配","database-operation-failed":"数据库读写异常","role-not-exist":"角色不存在","permission-not-exist":"权限不存在","context-required":"uni-id无法获取context.{key}，请使用uniID.createInstance方法传入","limit-client-platform":"当前客户端平台不支持此接口"},en:{alipay:"alipay",wechat:"wechat",user:"user","user-id":"user id","dcloud-appid":"DCloud appid","dcloud-appid-list":"DCloud appid list",account:"account",username:"username",email:"email",mobile:"phone number",sms:"sms","wechat-openid":"wechat openid","wechat-account":"wechat account","alipay-account":"alipay account","qq-openid":"QQ openid","qq-account":"QQ account","apple-account":"apple account",password:"password","verify-code":"verify code","verify-code-type":"verify code type","user-unique-param":"username, email or mobile phone number","role-id":"role id","permission-id":"permission id",login:"login","verify-mobile":"verify mobile phone number","context-param-required":"You should pass {param} in context using uniID.createInstance","config-param-require":"{param} is required in uni-id's config","uni-verify-config-required":"Univerify config required: service.univerify","login-with-invite-type-required":"Parameter type is required when forceInviteCode set to true","type-array-required":"Type of {param} must be array","query-field-warning":"You are using multi query field to login, be aware that uni-id will not check username's fromat, eg: abc@xx.com is a valid username for uni-id. You should check username in your code.","add-role-admin-is-not-allowed":'Add role with an id of "admin" is not allowed',"password-secret-type-error":'"passwordSecret" in config must be string or array',"token-expires-config-warning":'"tokenExpiresIn" must be greater than "tokenExpiresThreshold"',"type-function-required":"{param} must be a function","dev-warning":"warning: uniID.dev is only for development","config-file-invalid":"Invalid config file (common/uni-config-center/uni-id/config.json), please note that comment is not allowed","config-file-not-found":"Config file (common/uni-config-center/uni-id/config.json) not found","hx-version-warning":"The HBuilderX you are using is too old, please upgrade to the latest version of HBuilderX","account-banned":"Account is banned","user-not-exist":"User does not exist","multi-user-matched":"Multiple users are matched","user-info-error":"User info error","user-account-conflict":"User account conflict","user-account-closed":"User account has been closed","password-error":"The password is incorrect","password-error-exceed-limit":"The number of password errors exceeded the limit","account-exists":"Account exists","account-not-exists":"Account does not exists","invalid-invite-code":"Invalid invite code","get-third-party-account-failed":"Get {account} failed","get-third-party-user-info-failed":"Get user info failed","param-required":"{param} is required","check-device-feature-failed":"Check device feature failed","token-not-exist":"The login status is invalid, token does not exist","token-expired":"The login status is invalid, token has expired","check-token-failed":"Check token failed","invalid-old-password":"Invalid old password","param-error":"{param} error, {reason}","invalid-verify-code":"Invalid {type} verify code","send-sms-code-failed":"Send sms code failed","account-bound":"Account has been bound","unbind-failed":"Unbind failed","set-invite-code-failed":"Set invite code failed","modify-invite-code-is-not-allowed":"Modifying the invitation code is prohibited","decrypt-weixin-data-failed":"Decrypt weixin data failed","invalid-weixin-appid":"Invalid weixin appid","database-operation-failed":"Database operation failed","role-not-exist":"Role does not exist","permission-not-exist":"Permission does not exist","context-required":'"context.{key}" is required, you should pass context using uniID.createInstance',"limit-client-platform":"Unsupported client platform"}};const O=uniCloud.database(),P=O.collection("uni-id-users"),R=O.collection("opendb-verify-codes"),j=O.collection("uni-id-roles"),D=O.collection("uni-id-permissions"),q={username:"username",mobile:"mobile",email:"email",wx_unionid:"wechat-account","wx_openid.app-plus":"wechat-account","wx_openid.app":"wechat-account","wx_openid.mp-weixin":"wechat-account",qq_unionid:"qq-account","qq_openid.app-plus":"qq-account","qq_openid.app":"qq-account","qq_openid.mp-weixin":"qq-account",ali_openid:"alipay-account",apple_openid:"alipay-account"},N=90002,U=90003,L=90004,V=90005,M=0,B=1,F=4;async function $({uid:e,status:t}={}){return e?(await P.doc(e).update({status:t,status_update_date:Date.now()}),{code:0}):{code:N,messageValues:{param:this.t("user-id")}}}async function H({name:e,url:t,data:r,options:n,defaultOptions:i}){let o={};const s=b(Object.assign({},r));s&&s.access_token&&delete s.access_token;try{n=Object.assign({},i,n,{data:s}),o=await uniCloud.httpclient.request(t,n)}catch(t){return function(e,t){throw new a({code:t.code||-2,message:t.message||e+" fail"})}(e,t)}let c=o.data;const u=o.headers["content-type"];if(!Buffer.isBuffer(c)||0!==u.indexOf("text/plain")&&0!==u.indexOf("application/json"))Buffer.isBuffer(c)&&(c={buffer:c,contentType:u});else try{c=JSON.parse(c.toString())}catch(e){c=c.toString()}return v(function(e,t){if(t.errcode)throw new a({code:t.errcode||-2,message:t.errmsg||e+" fail"});return delete t.errcode,delete t.errmsg,{...t,errMsg:e+" ok",errCode:0}}(e,c||{errCode:-2,errMsg:"Request failed"}))}function K(e,t){let r="";if(t&&t.accessToken){r=`${e.indexOf("?")>-1?"&":"?"}access_token=${t.accessToken}`}return`${e}${r}`}class G{constructor(e){this.options=Object.assign({baseUrl:"https://api.weixin.qq.com",timeout:5e3},e)}async _requestWxOpenapi({name:e,url:t,data:r,options:n}){const i={method:"GET",dataType:"json",dataAsQueryString:!0,timeout:this.options.timeout};return await H({name:"auth."+e,url:`${this.options.baseUrl}${K(t,r)}`,data:r,options:n,defaultOptions:i})}async code2Session(e){return await this._requestWxOpenapi({name:"code2Session",url:"/sns/jscode2session",data:{grant_type:"authorization_code",appid:this.options.appId,secret:this.options.secret,js_code:e}})}async getOauthAccessToken(e){const t=await this._requestWxOpenapi({name:"getOauthAccessToken",url:"/sns/oauth2/access_token",data:{grant_type:"authorization_code",appid:this.options.appId,secret:this.options.secret,code:e}});return t.expiresIn&&(t.expired=Date.now()+1e3*t.expiresIn),t}async getUserInfo({accessToken:e,openid:t}={}){const{nickname:r,headimgurl:n}=await this._requestWxOpenapi({name:"getUserInfo",url:"/sns/userinfo",data:{accessToken:e,openid:t,appid:this.options.appId,secret:this.options.secret,scope:"snsapi_userinfo"}});return{nickname:r,avatar:n}}}async function Q({name:e,url:t,data:r,options:n,defaultOptions:i}){let o;n=Object.assign({},i,n,{data:b(Object.assign({},r))});try{o=await uniCloud.httpclient.request(t,n)}catch(t){return function(e,t){throw new a({code:t.code||-2,message:t.message||e+" fail"})}(e,t)}let s=o.data;const c=o.headers["content-type"];if(!Buffer.isBuffer(s)||0!==c.indexOf("text/plain")&&0!==c.indexOf("application/json"))Buffer.isBuffer(s)&&(s={buffer:s,contentType:c});else try{s=JSON.parse(s.toString())}catch(e){s=s.toString()}return v(function(e,t){if(t.ret||t.error){const r=t.ret||t.error||t.errcode||-2,n=t.msg||t.error_description||t.errmsg||e+" fail";throw new a({code:r,message:n})}return delete t.ret,delete t.msg,delete t.error,delete t.error_description,delete t.errcode,delete t.errmsg,{...t,errMsg:e+" ok",errCode:0}}(e,s||{errCode:-2,errMsg:"Request failed"}))}class X{constructor(e){this.options=Object.assign({baseUrl:"https://graph.qq.com",timeout:5e3},e)}async _requestQQOpenapi({name:e,url:t,data:r,options:n}){const i={method:"GET",dataType:"json",dataAsQueryString:!0,timeout:this.options.timeout};var o,s;return await Q({name:"auth."+e,url:(o=this.options.baseUrl,s=t,/^https?:/.test(s)?s:o+s),data:r,options:n,defaultOptions:i})}async getOpenidByToken({accessToken:e}={}){const t=await this._requestQQOpenapi({name:"getOpenidByToken",url:"/oauth2.0/me",data:{accessToken:e,unionid:1,fmt:"json"}});if(t.clientId!==this.options.appId)throw new a({code:"APPID_NOT_MATCH",message:"appid not match"});return{openid:t.openid,unionid:t.unionid}}async code2Session({code:e}={}){return await this._requestQQOpenapi({name:"getOpenidByToken",url:"https://api.q.qq.com/sns/jscode2session",data:{grant_type:"authorization_code",appid:this.options.appId,secret:this.options.secret,js_code:e}})}}const Y={RSA:"RSA-SHA1",RSA2:"RSA-SHA256"};var z={code2Session:{returnValue:{openid:"userId"}}};class W extends class{constructor(e={}){if(!e.appId)throw new Error("appId required");if(!e.privateKey)throw new Error("privateKey required");const t={gateway:"https://openapi.alipay.com/gateway.do",timeout:5e3,charset:"utf-8",version:"1.0",signType:"RSA2",timeOffset:-(new Date).getTimezoneOffset()/60,keyType:"PKCS8"};e.sandbox&&(e.gateway="https://openapi.alipaydev.com/gateway.do"),this.options=Object.assign({},t,e);const r="PKCS8"===this.options.keyType?"PRIVATE KEY":"RSA PRIVATE KEY";this.options.privateKey=this._formatKey(this.options.privateKey,r),this.options.alipayPublicKey&&(this.options.alipayPublicKey=this._formatKey(this.options.alipayPublicKey,"PUBLIC KEY"))}_formatKey(e,t){return`-----BEGIN ${t}-----\n${e}\n-----END ${t}-----`}_formatUrl(e,t){let r=e;const n=["app_id","method","format","charset","sign_type","sign","timestamp","version","notify_url","return_url","auth_token","app_auth_token"];for(const e in t)if(n.indexOf(e)>-1){const n=encodeURIComponent(t[e]);r=`${r}${r.includes("?")?"&":"?"}${e}=${n}`,delete t[e]}return{execParams:t,url:r}}_getSign(e,r){const n=r.bizContent||null;delete r.bizContent;const i=Object.assign({method:e,appId:this.options.appId,charset:this.options.charset,version:this.options.version,signType:this.options.signType,timestamp:T((o=this.options.timeOffset,new Date(Date.now()+6e4*((new Date).getTimezoneOffset()+60*(o||0)))))},r);var o;n&&(i.bizContent=JSON.stringify(b(n)));const s=b(i),a=Object.keys(s).sort().map(e=>{let t=s[e];return"[object String]"!==Array.prototype.toString.call(t)&&(t=JSON.stringify(t)),`${e}=${t}`}).join("&"),c=t.createSign(Y[this.options.signType]).update(a,"utf8").sign(this.options.privateKey,"base64");return Object.assign(s,{sign:c})}async _exec(e,t={},r={}){const n=this._getSign(e,t),{url:i,execParams:o}=this._formatUrl(this.options.gateway,n),{status:s,data:a}=await uniCloud.httpclient.request(i,{method:"POST",data:o,dataType:"text",timeout:this.options.timeout});if(200!==s)throw new Error("request fail");const c=JSON.parse(a),u=e.replace(/\./g,"_")+"_response",d=c[u],p=c.error_response;if(d){if(!r.validateSign||this._checkResponseSign(a,u)){if(!d.code||"10000"===d.code){return{errCode:0,errMsg:d.msg||"",...v(d)}}const e=d.sub_code?`${d.sub_code} ${d.sub_msg}`:""+(d.msg||"unkonwn error");throw new Error(e)}throw new Error("check sign error")}if(p)throw new Error(p.sub_msg||p.msg||"request fail");throw new Error("request fail")}_checkResponseSign(e,r){if(!this.options.alipayPublicKey||""===this.options.alipayPublicKey)return console.warn("options.alipayPublicKey is empty"),!0;if(!e)return!1;const n=this._getSignStr(e,r),i=JSON.parse(e).sign,o=t.createVerify(Y[this.options.signType]);return o.update(n,"utf8"),o.verify(this.options.alipayPublicKey,i,"base64")}_getSignStr(e,t){let r=e.trim();const n=e.indexOf(t+'"'),i=e.lastIndexOf('"sign"');return r=r.substr(n+t.length+1),r=r.substr(0,i),r=r.replace(/^[^{]*{/g,"{"),r=r.replace(/\}([^}]*)$/g,"}"),r}}{constructor(e){super(e),this._protocols=z}async code2Session(e){return await this._exec("alipay.system.oauth.token",{grantType:"authorization_code",code:e})}}function J(e){var t=e[0];return t<"0"||t>"7"?"00"+e:e}function Z(e){var t=e.toString(16);return t.length%2?"0"+t:t}function ee(e){if(e<=127)return Z(e);var t=Z(e);return Z(128+t.length/2)+t}function te(e,t){return e(t={exports:{}},t.exports),t.exports}var re=te((function(e,t){var n=r.Buffer;function i(e,t){for(var r in e)t[r]=e[r]}function o(e,t,r){return n(e,t,r)}n.from&&n.alloc&&n.allocUnsafe&&n.allocUnsafeSlow?e.exports=r:(i(r,t),t.Buffer=o),o.prototype=Object.create(n.prototype),i(n,o),o.from=function(e,t,r){if("number"==typeof e)throw new TypeError("Argument must not be a number");return n(e,t,r)},o.alloc=function(e,t,r){if("number"!=typeof e)throw new TypeError("Argument must be a number");var i=n(e);return void 0!==t?"string"==typeof r?i.fill(t,r):i.fill(t):i.fill(0),i},o.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return n(e)},o.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return r.SlowBuffer(e)}})),ne=(re.Buffer,re.Buffer);function ie(e){if(this.buffer=null,this.writable=!0,this.readable=!0,!e)return this.buffer=ne.alloc(0),this;if("function"==typeof e.pipe)return this.buffer=ne.alloc(0),e.pipe(this),this;if(e.length||"object"==typeof e)return this.buffer=e,this.writable=!1,process.nextTick(function(){this.emit("end",e),this.readable=!1,this.emit("close")}.bind(this)),this;throw new TypeError("Unexpected data type ("+typeof e+")")}i.inherits(ie,n),ie.prototype.write=function(e){this.buffer=ne.concat([this.buffer,ne.from(e)]),this.emit("data",e)},ie.prototype.end=function(e){e&&this.write(e),this.emit("end",e),this.emit("close"),this.writable=!1,this.readable=!1};var oe=ie,se=r.Buffer,ae=r.SlowBuffer,ce=ue;function ue(e,t){if(!se.isBuffer(e)||!se.isBuffer(t))return!1;if(e.length!==t.length)return!1;for(var r=0,n=0;n<e.length;n++)r|=e[n]^t[n];return 0===r}ue.install=function(){se.prototype.equal=ae.prototype.equal=function(e){return ue(this,e)}};var de=se.prototype.equal,pe=ae.prototype.equal;function le(e){return(e/8|0)+(e%8==0?0:1)}ue.restore=function(){se.prototype.equal=de,ae.prototype.equal=pe};var fe={ES256:le(256),ES384:le(384),ES512:le(521)};var me=function(e){var t=fe[e];if(t)return t;throw new Error('Unknown algorithm "'+e+'"')},he=re.Buffer;function ge(e){if(he.isBuffer(e))return e;if("string"==typeof e)return he.from(e,"base64");throw new TypeError("ECDSA signature must be a Base64 string or a Buffer")}function ye(e,t,r){for(var n=0;t+n<r&&0===e[t+n];)++n;return e[t+n]>=128&&--n,n}var we={derToJose:function(e,t){e=ge(e);var r=me(t),n=r+1,i=e.length,o=0;if(48!==e[o++])throw new Error('Could not find expected "seq"');var s=e[o++];if(129===s&&(s=e[o++]),i-o<s)throw new Error('"seq" specified length of "'+s+'", only "'+(i-o)+'" remaining');if(2!==e[o++])throw new Error('Could not find expected "int" for "r"');var a=e[o++];if(i-o-2<a)throw new Error('"r" specified length of "'+a+'", only "'+(i-o-2)+'" available');if(n<a)throw new Error('"r" specified length of "'+a+'", max of "'+n+'" is acceptable');var c=o;if(o+=a,2!==e[o++])throw new Error('Could not find expected "int" for "s"');var u=e[o++];if(i-o!==u)throw new Error('"s" specified length of "'+u+'", expected "'+(i-o)+'"');if(n<u)throw new Error('"s" specified length of "'+u+'", max of "'+n+'" is acceptable');var d=o;if((o+=u)!==i)throw new Error('Expected to consume entire buffer, but "'+(i-o)+'" bytes remain');var p=r-a,l=r-u,f=he.allocUnsafe(p+a+l+u);for(o=0;o<p;++o)f[o]=0;e.copy(f,o,c+Math.max(-p,0),c+a);for(var m=o=r;o<m+l;++o)f[o]=0;return e.copy(f,o,d+Math.max(-l,0),d+u),f=(f=f.toString("base64")).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")},joseToDer:function(e,t){e=ge(e);var r=me(t),n=e.length;if(n!==2*r)throw new TypeError('"'+t+'" signatures must be "'+2*r+'" bytes, saw "'+n+'"');var i=ye(e,0,r),o=ye(e,r,e.length),s=r-i,a=r-o,c=2+s+1+1+a,u=c<128,d=he.allocUnsafe((u?2:3)+c),p=0;return d[p++]=48,u?d[p++]=c:(d[p++]=129,d[p++]=255&c),d[p++]=2,d[p++]=s,i<0?(d[p++]=0,p+=e.copy(d,p,0,r)):p+=e.copy(d,p,i,r),d[p++]=2,d[p++]=a,o<0?(d[p++]=0,e.copy(d,p,r)):e.copy(d,p,r+o),d}},_e=re.Buffer,ve="secret must be a string or buffer",be="key must be a string or a buffer",Te="function"==typeof t.createPublicKey;function Ee(e){if(!_e.isBuffer(e)&&"string"!=typeof e){if(!Te)throw Ie(be);if("object"!=typeof e)throw Ie(be);if("string"!=typeof e.type)throw Ie(be);if("string"!=typeof e.asymmetricKeyType)throw Ie(be);if("function"!=typeof e.export)throw Ie(be)}}function Ce(e){if(!_e.isBuffer(e)&&"string"!=typeof e&&"object"!=typeof e)throw Ie("key must be a string, a buffer or an object")}function Ae(e){return e.replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function xe(e){var t=4-(e=e.toString()).length%4;if(4!==t)for(var r=0;r<t;++r)e+="=";return e.replace(/\-/g,"+").replace(/_/g,"/")}function Ie(e){var t=[].slice.call(arguments,1),r=i.format.bind(i,e).apply(null,t);return new TypeError(r)}function Se(e){var t;return t=e,_e.isBuffer(t)||"string"==typeof t||(e=JSON.stringify(e)),e}function ke(e){return function(r,n){!function(e){if(!_e.isBuffer(e)){if("string"==typeof e)return e;if(!Te)throw Ie(ve);if("object"!=typeof e)throw Ie(ve);if("secret"!==e.type)throw Ie(ve);if("function"!=typeof e.export)throw Ie(ve)}}(n),r=Se(r);var i=t.createHmac("sha"+e,n);return Ae((i.update(r),i.digest("base64")))}}function Oe(e){return function(t,r,n){var i=ke(e)(t,n);return ce(_e.from(r),_e.from(i))}}function Pe(e){return function(r,n){Ce(n),r=Se(r);var i=t.createSign("RSA-SHA"+e);return Ae((i.update(r),i.sign(n,"base64")))}}function Re(e){return function(r,n,i){Ee(i),r=Se(r),n=xe(n);var o=t.createVerify("RSA-SHA"+e);return o.update(r),o.verify(i,n,"base64")}}function je(e){return function(r,n){Ce(n),r=Se(r);var i=t.createSign("RSA-SHA"+e);return Ae((i.update(r),i.sign({key:n,padding:t.constants.RSA_PKCS1_PSS_PADDING,saltLength:t.constants.RSA_PSS_SALTLEN_DIGEST},"base64")))}}function De(e){return function(r,n,i){Ee(i),r=Se(r),n=xe(n);var o=t.createVerify("RSA-SHA"+e);return o.update(r),o.verify({key:i,padding:t.constants.RSA_PKCS1_PSS_PADDING,saltLength:t.constants.RSA_PSS_SALTLEN_DIGEST},n,"base64")}}function qe(e){var t=Pe(e);return function(){var r=t.apply(null,arguments);return r=we.derToJose(r,"ES"+e)}}function Ne(e){var t=Re(e);return function(r,n,i){return n=we.joseToDer(n,"ES"+e).toString("base64"),t(r,n,i)}}function Ue(){return function(){return""}}function Le(){return function(e,t){return""===t}}Te&&(be+=" or a KeyObject",ve+="or a KeyObject");var Ve=function(e){var t={hs:ke,rs:Pe,ps:je,es:qe,none:Ue},r={hs:Oe,rs:Re,ps:De,es:Ne,none:Le},n=e.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/i);if(!n)throw Ie('"%s" is not a valid algorithm.\n  Supported algorithms are:\n  "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" and "none".',e);var i=(n[1]||n[3]).toLowerCase(),o=n[2];return{sign:t[i](o),verify:r[i](o)}},Me=r.Buffer,Be=function(e){return"string"==typeof e?e:"number"==typeof e||Me.isBuffer(e)?e.toString():JSON.stringify(e)},Fe=re.Buffer;function $e(e,t){return Fe.from(e,t).toString("base64").replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function He(e){var t=e.header,r=e.payload,n=e.secret||e.privateKey,o=e.encoding,s=Ve(t.alg),a=function(e,t,r){r=r||"utf8";var n=$e(Be(e),"binary"),o=$e(Be(t),r);return i.format("%s.%s",n,o)}(t,r,o),c=s.sign(a,n);return i.format("%s.%s",a,c)}function Ke(e){var t=e.secret||e.privateKey||e.key,r=new oe(t);this.readable=!0,this.header=e.header,this.encoding=e.encoding,this.secret=this.privateKey=this.key=r,this.payload=new oe(e.payload),this.secret.once("close",function(){!this.payload.writable&&this.readable&&this.sign()}.bind(this)),this.payload.once("close",function(){!this.secret.writable&&this.readable&&this.sign()}.bind(this))}i.inherits(Ke,n),Ke.prototype.sign=function(){try{var e=He({header:this.header,payload:this.payload.buffer,secret:this.secret.buffer,encoding:this.encoding});return this.emit("done",e),this.emit("data",e),this.emit("end"),this.readable=!1,e}catch(e){this.readable=!1,this.emit("error",e),this.emit("close")}},Ke.sign=He;var Ge=Ke,Qe=re.Buffer,Xe=/^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.([a-zA-Z0-9\-_]+)?$/;function Ye(e){if(function(e){return"[object Object]"===Object.prototype.toString.call(e)}(e))return e;try{return JSON.parse(e)}catch(e){return}}function ze(e){var t=e.split(".",1)[0];return Ye(Qe.from(t,"base64").toString("binary"))}function We(e){return e.split(".")[2]}function Je(e){return Xe.test(e)&&!!ze(e)}function Ze(e,t,r){if(!t){var n=new Error("Missing algorithm parameter for jws.verify");throw n.code="MISSING_ALGORITHM",n}var i=We(e=Be(e)),o=function(e){return e.split(".",2).join(".")}(e);return Ve(t).verify(o,i,r)}function et(e,t){if(t=t||{},!Je(e=Be(e)))return null;var r=ze(e);if(!r)return null;var n=function(e,t){t=t||"utf8";var r=e.split(".")[1];return Qe.from(r,"base64").toString(t)}(e);return("JWT"===r.typ||t.json)&&(n=JSON.parse(n,t.encoding)),{header:r,payload:n,signature:We(e)}}function tt(e){var t=(e=e||{}).secret||e.publicKey||e.key,r=new oe(t);this.readable=!0,this.algorithm=e.algorithm,this.encoding=e.encoding,this.secret=this.publicKey=this.key=r,this.signature=new oe(e.signature),this.secret.once("close",function(){!this.signature.writable&&this.readable&&this.verify()}.bind(this)),this.signature.once("close",function(){!this.secret.writable&&this.readable&&this.verify()}.bind(this))}i.inherits(tt,n),tt.prototype.verify=function(){try{var e=Ze(this.signature.buffer,this.algorithm,this.key.buffer),t=et(this.signature.buffer,this.encoding);return this.emit("done",e,t),this.emit("data",e),this.emit("end"),this.readable=!1,e}catch(e){this.readable=!1,this.emit("error",e),this.emit("close")}},tt.decode=et,tt.isValid=Je,tt.verify=Ze;var rt=tt,nt={ALGORITHMS:["HS256","HS384","HS512","RS256","RS384","RS512","PS256","PS384","PS512","ES256","ES384","ES512"],sign:Ge.sign,verify:rt.verify,decode:rt.decode,isValid:rt.isValid,createSign:function(e){return new Ge(e)},createVerify:function(e){return new rt(e)}},it=function(e,t){t=t||{};var r=nt.decode(e,t);if(!r)return null;var n=r.payload;if("string"==typeof n)try{var i=JSON.parse(n);null!==i&&"object"==typeof i&&(n=i)}catch(e){}return!0===t.complete?{header:r.header,payload:n,signature:r.signature}:n},ot=function(e,t){Error.call(this,e),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name="JsonWebTokenError",this.message=e,t&&(this.inner=t)};(ot.prototype=Object.create(Error.prototype)).constructor=ot;var st=ot,at=function(e,t){st.call(this,e),this.name="NotBeforeError",this.date=t};(at.prototype=Object.create(st.prototype)).constructor=at;var ct=at,ut=function(e,t){st.call(this,e),this.name="TokenExpiredError",this.expiredAt=t};(ut.prototype=Object.create(st.prototype)).constructor=ut;var dt=ut,pt=1e3,lt=60*pt,ft=60*lt,mt=24*ft,ht=function(e,t){t=t||{};var r=typeof e;if("string"===r&&e.length>0)return function(e){if((e=String(e)).length>100)return;var t=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);if(!t)return;var r=parseFloat(t[1]);switch((t[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return 315576e5*r;case"weeks":case"week":case"w":return 6048e5*r;case"days":case"day":case"d":return r*mt;case"hours":case"hour":case"hrs":case"hr":case"h":return r*ft;case"minutes":case"minute":case"mins":case"min":case"m":return r*lt;case"seconds":case"second":case"secs":case"sec":case"s":return r*pt;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}(e);if("number"===r&&isFinite(e))return t.long?function(e){var t=Math.abs(e);if(t>=mt)return gt(e,t,mt,"day");if(t>=ft)return gt(e,t,ft,"hour");if(t>=lt)return gt(e,t,lt,"minute");if(t>=pt)return gt(e,t,pt,"second");return e+" ms"}(e):function(e){var t=Math.abs(e);if(t>=mt)return Math.round(e/mt)+"d";if(t>=ft)return Math.round(e/ft)+"h";if(t>=lt)return Math.round(e/lt)+"m";if(t>=pt)return Math.round(e/pt)+"s";return e+"ms"}(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))};function gt(e,t,r,n){var i=t>=1.5*r;return Math.round(e/r)+" "+n+(i?"s":"")}var yt=function(e,t){var r=t||Math.floor(Date.now()/1e3);if("string"==typeof e){var n=ht(e);if(void 0===n)return;return Math.floor(r+n/1e3)}return"number"==typeof e?r+e:void 0},wt=te((function(e,t){var r;t=e.exports=G,r="object"==typeof process&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?function(){var e=Array.prototype.slice.call(arguments,0);e.unshift("SEMVER"),console.log.apply(console,e)}:function(){},t.SEMVER_SPEC_VERSION="2.0.0";var n=Number.MAX_SAFE_INTEGER||9007199254740991,i=t.re=[],o=t.src=[],s=0,a=s++;o[a]="0|[1-9]\\d*";var c=s++;o[c]="[0-9]+";var u=s++;o[u]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var d=s++;o[d]="("+o[a]+")\\.("+o[a]+")\\.("+o[a]+")";var p=s++;o[p]="("+o[c]+")\\.("+o[c]+")\\.("+o[c]+")";var l=s++;o[l]="(?:"+o[a]+"|"+o[u]+")";var f=s++;o[f]="(?:"+o[c]+"|"+o[u]+")";var m=s++;o[m]="(?:-("+o[l]+"(?:\\."+o[l]+")*))";var h=s++;o[h]="(?:-?("+o[f]+"(?:\\."+o[f]+")*))";var g=s++;o[g]="[0-9A-Za-z-]+";var y=s++;o[y]="(?:\\+("+o[g]+"(?:\\."+o[g]+")*))";var w=s++,_="v?"+o[d]+o[m]+"?"+o[y]+"?";o[w]="^"+_+"$";var v="[v=\\s]*"+o[p]+o[h]+"?"+o[y]+"?",b=s++;o[b]="^"+v+"$";var T=s++;o[T]="((?:<|>)?=?)";var E=s++;o[E]=o[c]+"|x|X|\\*";var C=s++;o[C]=o[a]+"|x|X|\\*";var A=s++;o[A]="[v=\\s]*("+o[C]+")(?:\\.("+o[C]+")(?:\\.("+o[C]+")(?:"+o[m]+")?"+o[y]+"?)?)?";var x=s++;o[x]="[v=\\s]*("+o[E]+")(?:\\.("+o[E]+")(?:\\.("+o[E]+")(?:"+o[h]+")?"+o[y]+"?)?)?";var I=s++;o[I]="^"+o[T]+"\\s*"+o[A]+"$";var S=s++;o[S]="^"+o[T]+"\\s*"+o[x]+"$";var k=s++;o[k]="(?:^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])";var O=s++;o[O]="(?:~>?)";var P=s++;o[P]="(\\s*)"+o[O]+"\\s+",i[P]=new RegExp(o[P],"g");var R=s++;o[R]="^"+o[O]+o[A]+"$";var j=s++;o[j]="^"+o[O]+o[x]+"$";var D=s++;o[D]="(?:\\^)";var q=s++;o[q]="(\\s*)"+o[D]+"\\s+",i[q]=new RegExp(o[q],"g");var N=s++;o[N]="^"+o[D]+o[A]+"$";var U=s++;o[U]="^"+o[D]+o[x]+"$";var L=s++;o[L]="^"+o[T]+"\\s*("+v+")$|^$";var V=s++;o[V]="^"+o[T]+"\\s*("+_+")$|^$";var M=s++;o[M]="(\\s*)"+o[T]+"\\s*("+v+"|"+o[A]+")",i[M]=new RegExp(o[M],"g");var B=s++;o[B]="^\\s*("+o[A]+")\\s+-\\s+("+o[A]+")\\s*$";var F=s++;o[F]="^\\s*("+o[x]+")\\s+-\\s+("+o[x]+")\\s*$";var $=s++;o[$]="(<|>)?=?\\s*\\*";for(var H=0;H<35;H++)r(H,o[H]),i[H]||(i[H]=new RegExp(o[H]));function K(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof G)return e;if("string"!=typeof e)return null;if(e.length>256)return null;if(!(t.loose?i[b]:i[w]).test(e))return null;try{return new G(e,t)}catch(e){return null}}function G(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof G){if(e.loose===t.loose)return e;e=e.version}else if("string"!=typeof e)throw new TypeError("Invalid Version: "+e);if(e.length>256)throw new TypeError("version is longer than 256 characters");if(!(this instanceof G))return new G(e,t);r("SemVer",e,t),this.options=t,this.loose=!!t.loose;var o=e.trim().match(t.loose?i[b]:i[w]);if(!o)throw new TypeError("Invalid Version: "+e);if(this.raw=e,this.major=+o[1],this.minor=+o[2],this.patch=+o[3],this.major>n||this.major<0)throw new TypeError("Invalid major version");if(this.minor>n||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>n||this.patch<0)throw new TypeError("Invalid patch version");o[4]?this.prerelease=o[4].split(".").map((function(e){if(/^[0-9]+$/.test(e)){var t=+e;if(t>=0&&t<n)return t}return e})):this.prerelease=[],this.build=o[5]?o[5].split("."):[],this.format()}t.parse=K,t.valid=function(e,t){var r=K(e,t);return r?r.version:null},t.clean=function(e,t){var r=K(e.trim().replace(/^[=v]+/,""),t);return r?r.version:null},t.SemVer=G,G.prototype.format=function(){return this.version=this.major+"."+this.minor+"."+this.patch,this.prerelease.length&&(this.version+="-"+this.prerelease.join(".")),this.version},G.prototype.toString=function(){return this.version},G.prototype.compare=function(e){return r("SemVer.compare",this.version,this.options,e),e instanceof G||(e=new G(e,this.options)),this.compareMain(e)||this.comparePre(e)},G.prototype.compareMain=function(e){return e instanceof G||(e=new G(e,this.options)),X(this.major,e.major)||X(this.minor,e.minor)||X(this.patch,e.patch)},G.prototype.comparePre=function(e){if(e instanceof G||(e=new G(e,this.options)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;var t=0;do{var n=this.prerelease[t],i=e.prerelease[t];if(r("prerelease compare",t,n,i),void 0===n&&void 0===i)return 0;if(void 0===i)return 1;if(void 0===n)return-1;if(n!==i)return X(n,i)}while(++t)},G.prototype.inc=function(e,t){switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",t);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",t);break;case"prepatch":this.prerelease.length=0,this.inc("patch",t),this.inc("pre",t);break;case"prerelease":0===this.prerelease.length&&this.inc("patch",t),this.inc("pre",t);break;case"major":0===this.minor&&0===this.patch&&0!==this.prerelease.length||this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":0===this.patch&&0!==this.prerelease.length||this.minor++,this.patch=0,this.prerelease=[];break;case"patch":0===this.prerelease.length&&this.patch++,this.prerelease=[];break;case"pre":if(0===this.prerelease.length)this.prerelease=[0];else{for(var r=this.prerelease.length;--r>=0;)"number"==typeof this.prerelease[r]&&(this.prerelease[r]++,r=-2);-1===r&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error("invalid increment argument: "+e)}return this.format(),this.raw=this.version,this},t.inc=function(e,t,r,n){"string"==typeof r&&(n=r,r=void 0);try{return new G(e,r).inc(t,n).version}catch(e){return null}},t.diff=function(e,t){if(J(e,t))return null;var r=K(e),n=K(t),i="";if(r.prerelease.length||n.prerelease.length){i="pre";var o="prerelease"}for(var s in r)if(("major"===s||"minor"===s||"patch"===s)&&r[s]!==n[s])return i+s;return o},t.compareIdentifiers=X;var Q=/^[0-9]+$/;function X(e,t){var r=Q.test(e),n=Q.test(t);return r&&n&&(e=+e,t=+t),e===t?0:r&&!n?-1:n&&!r?1:e<t?-1:1}function Y(e,t,r){return new G(e,r).compare(new G(t,r))}function z(e,t,r){return Y(e,t,r)>0}function W(e,t,r){return Y(e,t,r)<0}function J(e,t,r){return 0===Y(e,t,r)}function Z(e,t,r){return 0!==Y(e,t,r)}function ee(e,t,r){return Y(e,t,r)>=0}function te(e,t,r){return Y(e,t,r)<=0}function re(e,t,r,n){switch(t){case"===":return"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),e===r;case"!==":return"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),e!==r;case"":case"=":case"==":return J(e,r,n);case"!=":return Z(e,r,n);case">":return z(e,r,n);case">=":return ee(e,r,n);case"<":return W(e,r,n);case"<=":return te(e,r,n);default:throw new TypeError("Invalid operator: "+t)}}function ne(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof ne){if(e.loose===!!t.loose)return e;e=e.value}if(!(this instanceof ne))return new ne(e,t);r("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===ie?this.value="":this.value=this.operator+this.semver.version,r("comp",this)}t.rcompareIdentifiers=function(e,t){return X(t,e)},t.major=function(e,t){return new G(e,t).major},t.minor=function(e,t){return new G(e,t).minor},t.patch=function(e,t){return new G(e,t).patch},t.compare=Y,t.compareLoose=function(e,t){return Y(e,t,!0)},t.rcompare=function(e,t,r){return Y(t,e,r)},t.sort=function(e,r){return e.sort((function(e,n){return t.compare(e,n,r)}))},t.rsort=function(e,r){return e.sort((function(e,n){return t.rcompare(e,n,r)}))},t.gt=z,t.lt=W,t.eq=J,t.neq=Z,t.gte=ee,t.lte=te,t.cmp=re,t.Comparator=ne;var ie={};function oe(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof oe)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new oe(e.raw,t);if(e instanceof ne)return new oe(e.value,t);if(!(this instanceof oe))return new oe(e,t);if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map((function(e){return this.parseRange(e.trim())}),this).filter((function(e){return e.length})),!this.set.length)throw new TypeError("Invalid SemVer Range: "+e);this.format()}function se(e){return!e||"x"===e.toLowerCase()||"*"===e}function ae(e,t,r,n,i,o,s,a,c,u,d,p,l){return((t=se(r)?"":se(n)?">="+r+".0.0":se(i)?">="+r+"."+n+".0":">="+t)+" "+(a=se(c)?"":se(u)?"<"+(+c+1)+".0.0":se(d)?"<"+c+"."+(+u+1)+".0":p?"<="+c+"."+u+"."+d+"-"+p:"<="+a)).trim()}function ce(e,t,n){for(var i=0;i<e.length;i++)if(!e[i].test(t))return!1;if(t.prerelease.length&&!n.includePrerelease){for(i=0;i<e.length;i++)if(r(e[i].semver),e[i].semver!==ie&&e[i].semver.prerelease.length>0){var o=e[i].semver;if(o.major===t.major&&o.minor===t.minor&&o.patch===t.patch)return!0}return!1}return!0}function ue(e,t,r){try{t=new oe(t,r)}catch(e){return!1}return t.test(e)}function de(e,t,r,n){var i,o,s,a,c;switch(e=new G(e,n),t=new oe(t,n),r){case">":i=z,o=te,s=W,a=">",c=">=";break;case"<":i=W,o=ee,s=z,a="<",c="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(ue(e,t,n))return!1;for(var u=0;u<t.set.length;++u){var d=t.set[u],p=null,l=null;if(d.forEach((function(e){e.semver===ie&&(e=new ne(">=0.0.0")),p=p||e,l=l||e,i(e.semver,p.semver,n)?p=e:s(e.semver,l.semver,n)&&(l=e)})),p.operator===a||p.operator===c)return!1;if((!l.operator||l.operator===a)&&o(e,l.semver))return!1;if(l.operator===c&&s(e,l.semver))return!1}return!0}ne.prototype.parse=function(e){var t=this.options.loose?i[L]:i[V],r=e.match(t);if(!r)throw new TypeError("Invalid comparator: "+e);this.operator=r[1],"="===this.operator&&(this.operator=""),r[2]?this.semver=new G(r[2],this.options.loose):this.semver=ie},ne.prototype.toString=function(){return this.value},ne.prototype.test=function(e){return r("Comparator.test",e,this.options.loose),this.semver===ie||("string"==typeof e&&(e=new G(e,this.options)),re(e,this.operator,this.semver,this.options))},ne.prototype.intersects=function(e,t){if(!(e instanceof ne))throw new TypeError("a Comparator is required");var r;if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),""===this.operator)return r=new oe(e.value,t),ue(this.value,r,t);if(""===e.operator)return r=new oe(this.value,t),ue(e.semver,r,t);var n=!(">="!==this.operator&&">"!==this.operator||">="!==e.operator&&">"!==e.operator),i=!("<="!==this.operator&&"<"!==this.operator||"<="!==e.operator&&"<"!==e.operator),o=this.semver.version===e.semver.version,s=!(">="!==this.operator&&"<="!==this.operator||">="!==e.operator&&"<="!==e.operator),a=re(this.semver,"<",e.semver,t)&&(">="===this.operator||">"===this.operator)&&("<="===e.operator||"<"===e.operator),c=re(this.semver,">",e.semver,t)&&("<="===this.operator||"<"===this.operator)&&(">="===e.operator||">"===e.operator);return n||i||o&&s||a||c},t.Range=oe,oe.prototype.format=function(){return this.range=this.set.map((function(e){return e.join(" ").trim()})).join("||").trim(),this.range},oe.prototype.toString=function(){return this.range},oe.prototype.parseRange=function(e){var t=this.options.loose;e=e.trim();var n=t?i[F]:i[B];e=e.replace(n,ae),r("hyphen replace",e),e=e.replace(i[M],"$1$2$3"),r("comparator trim",e,i[M]),e=(e=(e=e.replace(i[P],"$1~")).replace(i[q],"$1^")).split(/\s+/).join(" ");var o=t?i[L]:i[V],s=e.split(" ").map((function(e){return function(e,t){return r("comp",e,t),e=function(e,t){return e.trim().split(/\s+/).map((function(e){return function(e,t){r("caret",e,t);var n=t.loose?i[U]:i[N];return e.replace(n,(function(t,n,i,o,s){var a;return r("caret",e,t,n,i,o,s),se(n)?a="":se(i)?a=">="+n+".0.0 <"+(+n+1)+".0.0":se(o)?a="0"===n?">="+n+"."+i+".0 <"+n+"."+(+i+1)+".0":">="+n+"."+i+".0 <"+(+n+1)+".0.0":s?(r("replaceCaret pr",s),a="0"===n?"0"===i?">="+n+"."+i+"."+o+"-"+s+" <"+n+"."+i+"."+(+o+1):">="+n+"."+i+"."+o+"-"+s+" <"+n+"."+(+i+1)+".0":">="+n+"."+i+"."+o+"-"+s+" <"+(+n+1)+".0.0"):(r("no pr"),a="0"===n?"0"===i?">="+n+"."+i+"."+o+" <"+n+"."+i+"."+(+o+1):">="+n+"."+i+"."+o+" <"+n+"."+(+i+1)+".0":">="+n+"."+i+"."+o+" <"+(+n+1)+".0.0"),r("caret return",a),a}))}(e,t)})).join(" ")}(e,t),r("caret",e),e=function(e,t){return e.trim().split(/\s+/).map((function(e){return function(e,t){var n=t.loose?i[j]:i[R];return e.replace(n,(function(t,n,i,o,s){var a;return r("tilde",e,t,n,i,o,s),se(n)?a="":se(i)?a=">="+n+".0.0 <"+(+n+1)+".0.0":se(o)?a=">="+n+"."+i+".0 <"+n+"."+(+i+1)+".0":s?(r("replaceTilde pr",s),a=">="+n+"."+i+"."+o+"-"+s+" <"+n+"."+(+i+1)+".0"):a=">="+n+"."+i+"."+o+" <"+n+"."+(+i+1)+".0",r("tilde return",a),a}))}(e,t)})).join(" ")}(e,t),r("tildes",e),e=function(e,t){return r("replaceXRanges",e,t),e.split(/\s+/).map((function(e){return function(e,t){e=e.trim();var n=t.loose?i[S]:i[I];return e.replace(n,(function(t,n,i,o,s,a){r("xRange",e,t,n,i,o,s,a);var c=se(i),u=c||se(o),d=u||se(s);return"="===n&&d&&(n=""),c?t=">"===n||"<"===n?"<0.0.0":"*":n&&d?(u&&(o=0),s=0,">"===n?(n=">=",u?(i=+i+1,o=0,s=0):(o=+o+1,s=0)):"<="===n&&(n="<",u?i=+i+1:o=+o+1),t=n+i+"."+o+"."+s):u?t=">="+i+".0.0 <"+(+i+1)+".0.0":d&&(t=">="+i+"."+o+".0 <"+i+"."+(+o+1)+".0"),r("xRange return",t),t}))}(e,t)})).join(" ")}(e,t),r("xrange",e),e=function(e,t){return r("replaceStars",e,t),e.trim().replace(i[$],"")}(e,t),r("stars",e),e}(e,this.options)}),this).join(" ").split(/\s+/);return this.options.loose&&(s=s.filter((function(e){return!!e.match(o)}))),s=s.map((function(e){return new ne(e,this.options)}),this)},oe.prototype.intersects=function(e,t){if(!(e instanceof oe))throw new TypeError("a Range is required");return this.set.some((function(r){return r.every((function(r){return e.set.some((function(e){return e.every((function(e){return r.intersects(e,t)}))}))}))}))},t.toComparators=function(e,t){return new oe(e,t).set.map((function(e){return e.map((function(e){return e.value})).join(" ").trim().split(" ")}))},oe.prototype.test=function(e){if(!e)return!1;"string"==typeof e&&(e=new G(e,this.options));for(var t=0;t<this.set.length;t++)if(ce(this.set[t],e,this.options))return!0;return!1},t.satisfies=ue,t.maxSatisfying=function(e,t,r){var n=null,i=null;try{var o=new oe(t,r)}catch(e){return null}return e.forEach((function(e){o.test(e)&&(n&&-1!==i.compare(e)||(i=new G(n=e,r)))})),n},t.minSatisfying=function(e,t,r){var n=null,i=null;try{var o=new oe(t,r)}catch(e){return null}return e.forEach((function(e){o.test(e)&&(n&&1!==i.compare(e)||(i=new G(n=e,r)))})),n},t.minVersion=function(e,t){e=new oe(e,t);var r=new G("0.0.0");if(e.test(r))return r;if(r=new G("0.0.0-0"),e.test(r))return r;r=null;for(var n=0;n<e.set.length;++n){e.set[n].forEach((function(e){var t=new G(e.semver.version);switch(e.operator){case">":0===t.prerelease.length?t.patch++:t.prerelease.push(0),t.raw=t.format();case"":case">=":r&&!z(r,t)||(r=t);break;case"<":case"<=":break;default:throw new Error("Unexpected operation: "+e.operator)}}))}if(r&&e.test(r))return r;return null},t.validRange=function(e,t){try{return new oe(e,t).range||"*"}catch(e){return null}},t.ltr=function(e,t,r){return de(e,t,"<",r)},t.gtr=function(e,t,r){return de(e,t,">",r)},t.outside=de,t.prerelease=function(e,t){var r=K(e,t);return r&&r.prerelease.length?r.prerelease:null},t.intersects=function(e,t,r){return e=new oe(e,r),t=new oe(t,r),e.intersects(t)},t.coerce=function(e){if(e instanceof G)return e;if("string"!=typeof e)return null;var t=e.match(i[k]);if(null==t)return null;return K(t[1]+"."+(t[2]||"0")+"."+(t[3]||"0"))}})),_t=(wt.SEMVER_SPEC_VERSION,wt.re,wt.src,wt.parse,wt.valid,wt.clean,wt.SemVer,wt.inc,wt.diff,wt.compareIdentifiers,wt.rcompareIdentifiers,wt.major,wt.minor,wt.patch,wt.compare,wt.compareLoose,wt.rcompare,wt.sort,wt.rsort,wt.gt,wt.lt,wt.eq,wt.neq,wt.gte,wt.lte,wt.cmp,wt.Comparator,wt.Range,wt.toComparators,wt.satisfies,wt.maxSatisfying,wt.minSatisfying,wt.minVersion,wt.validRange,wt.ltr,wt.gtr,wt.outside,wt.prerelease,wt.intersects,wt.coerce,wt.satisfies(process.version,"^6.12.0 || >=8.0.0")),vt=["RS256","RS384","RS512","ES256","ES384","ES512"],bt=["RS256","RS384","RS512"],Tt=["HS256","HS384","HS512"];_t&&(vt.splice(3,0,"PS256","PS384","PS512"),bt.splice(3,0,"PS256","PS384","PS512"));var Et=/^\s+|\s+$/g,Ct=/^[-+]0x[0-9a-f]+$/i,At=/^0b[01]+$/i,xt=/^0o[0-7]+$/i,It=/^(?:0|[1-9]\d*)$/,St=parseInt;function kt(e){return e!=e}function Ot(e,t){return function(e,t){for(var r=-1,n=e?e.length:0,i=Array(n);++r<n;)i[r]=t(e[r],r,e);return i}(t,(function(t){return e[t]}))}var Pt,Rt,jt=Object.prototype,Dt=jt.hasOwnProperty,qt=jt.toString,Nt=jt.propertyIsEnumerable,Ut=(Pt=Object.keys,Rt=Object,function(e){return Pt(Rt(e))}),Lt=Math.max;function Vt(e,t){var r=Ft(e)||function(e){return function(e){return Kt(e)&&$t(e)}(e)&&Dt.call(e,"callee")&&(!Nt.call(e,"callee")||"[object Arguments]"==qt.call(e))}(e)?function(e,t){for(var r=-1,n=Array(e);++r<e;)n[r]=t(r);return n}(e.length,String):[],n=r.length,i=!!n;for(var o in e)!t&&!Dt.call(e,o)||i&&("length"==o||Bt(o,n))||r.push(o);return r}function Mt(e){if(r=(t=e)&&t.constructor,n="function"==typeof r&&r.prototype||jt,t!==n)return Ut(e);var t,r,n,i=[];for(var o in Object(e))Dt.call(e,o)&&"constructor"!=o&&i.push(o);return i}function Bt(e,t){return!!(t=null==t?9007199254740991:t)&&("number"==typeof e||It.test(e))&&e>-1&&e%1==0&&e<t}var Ft=Array.isArray;function $t(e){return null!=e&&function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}(e.length)&&!function(e){var t=Ht(e)?qt.call(e):"";return"[object Function]"==t||"[object GeneratorFunction]"==t}(e)}function Ht(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function Kt(e){return!!e&&"object"==typeof e}var Gt=function(e,t,r,n){var i;e=$t(e)?e:(i=e)?Ot(i,function(e){return $t(e)?Vt(e):Mt(e)}(i)):[],r=r&&!n?function(e){var t=function(e){if(!e)return 0===e?e:0;if((e=function(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||Kt(e)&&"[object Symbol]"==qt.call(e)}(e))return NaN;if(Ht(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=Ht(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(Et,"");var r=At.test(e);return r||xt.test(e)?St(e.slice(2),r?2:8):Ct.test(e)?NaN:+e}(e))===1/0||e===-1/0){return 17976931348623157e292*(e<0?-1:1)}return e==e?e:0}(e),r=t%1;return t==t?r?t-r:t:0}(r):0;var o=e.length;return r<0&&(r=Lt(o+r,0)),function(e){return"string"==typeof e||!Ft(e)&&Kt(e)&&"[object String]"==qt.call(e)}(e)?r<=o&&e.indexOf(t,r)>-1:!!o&&function(e,t,r){if(t!=t)return function(e,t,r,n){for(var i=e.length,o=r+(n?1:-1);n?o--:++o<i;)if(t(e[o],o,e))return o;return-1}(e,kt,r);for(var n=r-1,i=e.length;++n<i;)if(e[n]===t)return n;return-1}(e,t,r)>-1},Qt=Object.prototype.toString;var Xt=function(e){return!0===e||!1===e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Boolean]"==Qt.call(e)},Yt=/^\s+|\s+$/g,zt=/^[-+]0x[0-9a-f]+$/i,Wt=/^0b[01]+$/i,Jt=/^0o[0-7]+$/i,Zt=parseInt,er=Object.prototype.toString;function tr(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var rr=function(e){return"number"==typeof e&&e==function(e){var t=function(e){if(!e)return 0===e?e:0;if((e=function(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==er.call(e)}(e))return NaN;if(tr(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=tr(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(Yt,"");var r=Wt.test(e);return r||Jt.test(e)?Zt(e.slice(2),r?2:8):zt.test(e)?NaN:+e}(e))===1/0||e===-1/0){return 17976931348623157e292*(e<0?-1:1)}return e==e?e:0}(e),r=t%1;return t==t?r?t-r:t:0}(e)},nr=Object.prototype.toString;var ir=function(e){return"number"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Number]"==nr.call(e)};var or=Function.prototype,sr=Object.prototype,ar=or.toString,cr=sr.hasOwnProperty,ur=ar.call(Object),dr=sr.toString,pr=function(e,t){return function(r){return e(t(r))}}(Object.getPrototypeOf,Object);var lr=function(e){if(!function(e){return!!e&&"object"==typeof e}(e)||"[object Object]"!=dr.call(e)||function(e){var t=!1;if(null!=e&&"function"!=typeof e.toString)try{t=!!(e+"")}catch(e){}return t}(e))return!1;var t=pr(e);if(null===t)return!0;var r=cr.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&&ar.call(r)==ur},fr=Object.prototype.toString,mr=Array.isArray;var hr=function(e){return"string"==typeof e||!mr(e)&&function(e){return!!e&&"object"==typeof e}(e)&&"[object String]"==fr.call(e)},gr=/^\s+|\s+$/g,yr=/^[-+]0x[0-9a-f]+$/i,wr=/^0b[01]+$/i,_r=/^0o[0-7]+$/i,vr=parseInt,br=Object.prototype.toString;function Tr(e,t){var r;if("function"!=typeof t)throw new TypeError("Expected a function");return e=function(e){var t=function(e){if(!e)return 0===e?e:0;if((e=function(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==br.call(e)}(e))return NaN;if(Er(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=Er(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(gr,"");var r=wr.test(e);return r||_r.test(e)?vr(e.slice(2),r?2:8):yr.test(e)?NaN:+e}(e))===1/0||e===-1/0){return 17976931348623157e292*(e<0?-1:1)}return e==e?e:0}(e),r=t%1;return t==t?r?t-r:t:0}(e),function(){return--e>0&&(r=t.apply(this,arguments)),e<=1&&(t=void 0),r}}function Er(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var Cr=function(e){return Tr(2,e)},Ar=["RS256","RS384","RS512","ES256","ES384","ES512","HS256","HS384","HS512","none"];_t&&Ar.splice(3,0,"PS256","PS384","PS512");var xr={expiresIn:{isValid:function(e){return rr(e)||hr(e)&&e},message:'"expiresIn" should be a number of seconds or string representing a timespan'},notBefore:{isValid:function(e){return rr(e)||hr(e)&&e},message:'"notBefore" should be a number of seconds or string representing a timespan'},audience:{isValid:function(e){return hr(e)||Array.isArray(e)},message:'"audience" must be a string or array'},algorithm:{isValid:Gt.bind(null,Ar),message:'"algorithm" must be a valid string enum value'},header:{isValid:lr,message:'"header" must be an object'},encoding:{isValid:hr,message:'"encoding" must be a string'},issuer:{isValid:hr,message:'"issuer" must be a string'},subject:{isValid:hr,message:'"subject" must be a string'},jwtid:{isValid:hr,message:'"jwtid" must be a string'},noTimestamp:{isValid:Xt,message:'"noTimestamp" must be a boolean'},keyid:{isValid:hr,message:'"keyid" must be a string'},mutatePayload:{isValid:Xt,message:'"mutatePayload" must be a boolean'}},Ir={iat:{isValid:ir,message:'"iat" should be a number of seconds'},exp:{isValid:ir,message:'"exp" should be a number of seconds'},nbf:{isValid:ir,message:'"nbf" should be a number of seconds'}};function Sr(e,t,r,n){if(!lr(r))throw new Error('Expected "'+n+'" to be a plain object.');Object.keys(r).forEach((function(i){var o=e[i];if(o){if(!o.isValid(r[i]))throw new Error(o.message)}else if(!t)throw new Error('"'+i+'" is not allowed in "'+n+'"')}))}var kr={audience:"aud",issuer:"iss",subject:"sub",jwtid:"jti"},Or=["expiresIn","notBefore","noTimestamp","audience","issuer","subject","jwtid"],Pr=function(e,t,r,n){var i;if("function"!=typeof r||n||(n=r,r={}),r||(r={}),r=Object.assign({},r),i=n||function(e,t){if(e)throw e;return t},r.clockTimestamp&&"number"!=typeof r.clockTimestamp)return i(new st("clockTimestamp must be a number"));if(void 0!==r.nonce&&("string"!=typeof r.nonce||""===r.nonce.trim()))return i(new st("nonce must be a non-empty string"));var o=r.clockTimestamp||Math.floor(Date.now()/1e3);if(!e)return i(new st("jwt must be provided"));if("string"!=typeof e)return i(new st("jwt must be a string"));var s,a=e.split(".");if(3!==a.length)return i(new st("jwt malformed"));try{s=it(e,{complete:!0})}catch(e){return i(e)}if(!s)return i(new st("invalid token"));var c,u=s.header;if("function"==typeof t){if(!n)return i(new st("verify must be called asynchronous if secret or public key is provided as a callback"));c=t}else c=function(e,r){return r(null,t)};return c(u,(function(t,n){if(t)return i(new st("error in secret or public key callback: "+t.message));var c,d=""!==a[2].trim();if(!d&&n)return i(new st("jwt signature is required"));if(d&&!n)return i(new st("secret or public key must be provided"));if(d||r.algorithms||(r.algorithms=["none"]),r.algorithms||(r.algorithms=~n.toString().indexOf("BEGIN CERTIFICATE")||~n.toString().indexOf("BEGIN PUBLIC KEY")?vt:~n.toString().indexOf("BEGIN RSA PUBLIC KEY")?bt:Tt),!~r.algorithms.indexOf(s.header.alg))return i(new st("invalid algorithm"));try{c=nt.verify(e,s.header.alg,n)}catch(e){return i(e)}if(!c)return i(new st("invalid signature"));var p=s.payload;if(void 0!==p.nbf&&!r.ignoreNotBefore){if("number"!=typeof p.nbf)return i(new st("invalid nbf value"));if(p.nbf>o+(r.clockTolerance||0))return i(new ct("jwt not active",new Date(1e3*p.nbf)))}if(void 0!==p.exp&&!r.ignoreExpiration){if("number"!=typeof p.exp)return i(new st("invalid exp value"));if(o>=p.exp+(r.clockTolerance||0))return i(new dt("jwt expired",new Date(1e3*p.exp)))}if(r.audience){var l=Array.isArray(r.audience)?r.audience:[r.audience];if(!(Array.isArray(p.aud)?p.aud:[p.aud]).some((function(e){return l.some((function(t){return t instanceof RegExp?t.test(e):t===e}))})))return i(new st("jwt audience invalid. expected: "+l.join(" or ")))}if(r.issuer&&("string"==typeof r.issuer&&p.iss!==r.issuer||Array.isArray(r.issuer)&&-1===r.issuer.indexOf(p.iss)))return i(new st("jwt issuer invalid. expected: "+r.issuer));if(r.subject&&p.sub!==r.subject)return i(new st("jwt subject invalid. expected: "+r.subject));if(r.jwtid&&p.jti!==r.jwtid)return i(new st("jwt jwtid invalid. expected: "+r.jwtid));if(r.nonce&&p.nonce!==r.nonce)return i(new st("jwt nonce invalid. expected: "+r.nonce));if(r.maxAge){if("number"!=typeof p.iat)return i(new st("iat required when maxAge is specified"));var f=yt(r.maxAge,p.iat);if(void 0===f)return i(new st('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));if(o>=f+(r.clockTolerance||0))return i(new dt("maxAge exceeded",new Date(1e3*f)))}if(!0===r.complete){var m=s.signature;return i(null,{header:u,payload:p,signature:m})}return i(null,p)}))},Rr=function(e,t,r,n){"function"==typeof r?(n=r,r={}):r=r||{};var i="object"==typeof e&&!Buffer.isBuffer(e),o=Object.assign({alg:r.algorithm||"HS256",typ:i?"JWT":void 0,kid:r.keyid},r.header);function s(e){if(n)return n(e);throw e}if(!t&&"none"!==r.algorithm)return s(new Error("secretOrPrivateKey must have a value"));if(void 0===e)return s(new Error("payload is required"));if(i){try{!function(e){Sr(Ir,!0,e,"payload")}(e)}catch(e){return s(e)}r.mutatePayload||(e=Object.assign({},e))}else{var a=Or.filter((function(e){return void 0!==r[e]}));if(a.length>0)return s(new Error("invalid "+a.join(",")+" option for "+typeof e+" payload"))}if(void 0!==e.exp&&void 0!==r.expiresIn)return s(new Error('Bad "options.expiresIn" option the payload already has an "exp" property.'));if(void 0!==e.nbf&&void 0!==r.notBefore)return s(new Error('Bad "options.notBefore" option the payload already has an "nbf" property.'));try{!function(e){Sr(xr,!1,e,"options")}(r)}catch(e){return s(e)}var c=e.iat||Math.floor(Date.now()/1e3);if(r.noTimestamp?delete e.iat:i&&(e.iat=c),void 0!==r.notBefore){try{e.nbf=yt(r.notBefore,c)}catch(e){return s(e)}if(void 0===e.nbf)return s(new Error('"notBefore" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'))}if(void 0!==r.expiresIn&&"object"==typeof e){try{e.exp=yt(r.expiresIn,c)}catch(e){return s(e)}if(void 0===e.exp)return s(new Error('"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'))}Object.keys(kr).forEach((function(t){var n=kr[t];if(void 0!==r[t]){if(void 0!==e[n])return s(new Error('Bad "options.'+t+'" option. The payload already has an "'+n+'" property.'));e[n]=r[t]}}));var u=r.encoding||"utf8";if("function"!=typeof n)return nt.sign({header:o,payload:e,secret:t,encoding:u});n=n&&Cr(n),nt.createSign({header:o,privateKey:t,payload:e,encoding:u}).once("error",n).once("done",(function(e){n(null,e)}))};let jr=[];class Dr{constructor(e){this.options=Object.assign({baseUrl:"https://appleid.apple.com",timeout:1e4},e)}async _fetch(e,t){const{baseUrl:r}=this.options;return uniCloud.httpclient.request(r+e,t)}async verifyIdentityToken(e){const t=e.split(".")[0],{kid:r}=JSON.parse(Buffer.from(t,"base64").toString());if(!jr.length)try{jr=await this.getAuthKeys()}catch(e){return{code:10705,msg:e.message}}const n=this.getUsedKey(jr,r);if(!Object.keys(n).length&&!this.fetched)try{jr=await this.getAuthKeys()}catch(e){return{code:10705,msg:e.message}}let i=null;try{i=Pr(e,function(e,t){var r=Buffer.from(e,"base64"),n=Buffer.from(t,"base64"),i=r.toString("hex"),o=n.toString("hex");i=J(i),o=J(o);var s=i.length/2,a=o.length/2,c=ee(s),u=ee(a),d="30"+ee(s+a+c.length/2+u.length/2+2)+"02"+c+i+"02"+u+o;return"-----BEGIN RSA PUBLIC KEY-----\n"+Buffer.from(d,"hex").toString("base64").match(/.{1,64}/g).join("\n")+"\n-----END RSA PUBLIC KEY-----\n"}(n.n,n.e),{algorithms:n.alg})}catch(e){return{code:10705,msg:e.message}}return{code:0,msg:i}}async getAuthKeys(){const{status:e,data:t}=await this._fetch("/auth/keys",{method:"GET",dataType:"json",timeout:this.options.timeout});if(200!==e)throw new Error("request https://appleid.apple.com/auth/keys fail");return t.keys}getUsedKey(e,t){let r={};for(let n=0;n<e.length;n++){const i=e[n];if(i.kid===t){r=i;break}}return r}}var qr=function(e={}){return e.appId=e.appid,e.secret=e.appsecret,I(G,e)},Nr=function(e={}){return e.appId=e.appid,e.secret=e.appsecret,I(X,e)},Ur=function(e={}){return e.appId=e.appid,I(W,e)},Lr=function(e={}){return I(Dr,e)};function Vr(e=6){const t=["2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z"];let r="";for(let n=0;n<e;n++)r+=t[Math.floor(Math.random()*t.length)];return r}async function Mr(e){return 0===(await P.where({my_invite_code:e}).get()).data.length}const Br=O.command;async function Fr({uid:e,dcloudAppidList:t}={}){if(!e)return{code:N,messageValues:{param:this.t("user-id")}};if(!t||0===t.length||t.some(e=>void 0===e))return{code:N,messageValues:{param:this.t("dcloud-appid")}};const r=await P.doc(e).get(),n=r&&r.data&&r.data[0];if(!n)return{code:10002};const i=Object.keys(q).reduce((e,t)=>{const r=t,i=function(e,t){return t.split(".").reduce((e,t)=>e&&e[t],e)}(n,t);return i&&e.push({[r]:i}),e},[]);let o;const s={dcloud_appid:Br.in(t),_id:Br.neq(n._id)},a={dcloud_appid:Br.exists(!1),_id:Br.neq(n._id)};switch(i.length){case 0:return{code:10004};case 1:o=Br.or([Br.and([i[0],s]),Br.and([i[0],a])]);break;default:o=Br.or([Br.and([Br.or(i),s]),Br.and([Br.or(i),a])])}const c=await P.where(o).limit(1).get();return c&&c.data&&c.data[0]?{code:10005}:{code:0}}const $r=uniCloud.database().command;const Hr=uniCloud.database();const Kr=uniCloud.database().command;const Gr=uniCloud.database();const Qr=uniCloud.database();async function Xr(e){if(!e.openid||!e.access_token)throw new Error(this.t("config-param-required",{param:"openid, access_token"}));return function(e,t){const r={0:"",4e3:"缺失参数",4001:"apiKey不存在",4002:"sign校验不通过",4003:"appid不存在",4004:"应用未开通一键登录服务",4005:"应用开通的一键登录服务正在审核中",4006:"服务空间不在白名单中",4100:"账户余额不足",5e3:"获取手机号失败，请稍后重试(或其他未知错误)"};return{...e,msg:r[e.code]?"[getPhoneNumber] 获取手机号: "+r[e.code]:e.errMsg}}(await uniCloud.getPhoneNumber({provider:"univerify",...e}))}const Yr=uniCloud.database();const zr=uniCloud.database();const Wr=uniCloud.database();const Jr=uniCloud.database().command;const Zr=uniCloud.database();const en=uniCloud.database();const tn=uniCloud.database();const rn=uniCloud.database();const nn=uniCloud.database();const on=uniCloud.database();const sn=uniCloud.database();const an={"mobile-code":function(e){return!(!e.service||!e.service.sms)},univerify:function(e){return!(!e.service||!e.service.univerify)},weixin:function(e){return!!(e.oauth&&e.oauth.weixin&&e.oauth.weixin.appsecret)},qq:function(e){return!!(e.oauth&&e.oauth.qq&&e.oauth.qq.appsecret)},apple:function(e){return!!(e.oauth&&e.oauth.apple&&e.oauth.apple.bundleId)},alipay:function(e){return!!(e.oauth&&e.oauth.alipay&&e.oauth.alipay.privateKey)}};const cn=uniCloud.database();var un=Object.freeze({__proto__:null,addUser:async function({username:e,nickname:t,password:r,mobile:n,email:i,role:o=[],authorizedApp:s=[]}={}){const a=O.command,c=[];if(!e&&!n&&!i)throw new Error("username, mobile or email required");let u;if(e&&c.push({username:e}),n&&c.push({mobile:n,mobile_confirmed:1}),i&&c.push({email:i,email_confirmed:1}),s.length>0){u=a.and(a.or(c),a.or({dcloud_appid:a.in(s)},{dcloud_appid:a.exists(!1)}));if((await P.where(u).limit(1).get()).data.length>0)return{code:10201,messageValues:{type:this.t("username")}}}const d={role:o,nickname:t,dcloud_appid:s,register_date:Date.now()};if(e&&(d.username=e),r){const{passwordHash:e,version:t}=this.encryptPwd(r);d.password=e,t&&(d.password_secret_version=t)}return n&&(d.mobile=n,d.mobile_confirmed=1),i&&(d.email=i,d.email_confirmed=1),{code:0,uid:(await P.add(d)).id}},getUserInfo:async function({uid:e,field:t}){if(!e)return{code:N,messageValues:{param:this.t("user-id")}};let r;if(t&&t.length){const n={};for(let e=0;e<t.length;e++)n[t[e]]=!0;r=await P.doc(e).field(n).get()}else r=await P.doc(e).get();return 0===r.data.length?{code:80301}:{code:0,msg:"",userInfo:r.data[0]}},getUserInfoByToken:async function(e){const t=this._verifyToken(e);return t.code||(delete t.iat,delete t.exp),t},resetPwd:async function({uid:e,password:t}){const{passwordHash:r,version:n}=this.encryptPwd(t),i={password:r,token:[]};return n&&(i.password_secret_version=n),E("upRes",await P.doc(e).update(i)),{code:0,msg:""}},resetPwdBySms:async function({mobile:e,code:t,password:r}){const n=await this.verifyCode({mobile:e,code:t,type:"reset-pwd"});if(0!==n.code)return n;const i=(await P.where({mobile:e}).get()).data.filter(e=>void 0===e.dcloud_appid||e.dcloud_appid.includes(this.context.APPID));if(0===i.length)return{code:10002};if(i.length>1)return{code:10005};const o=i[0]._id;return this.resetPwd({uid:o,password:r})},setAvatar:async function(e){return await P.doc(e.uid).update({avatar:e.avatar}),{code:0,msg:""}},updatePwd:async function(e){const t=await P.doc(e.uid).get();if(t&&t.data&&t.data.length>0){if(0===this._checkPwd(t.data[0],e.oldPassword).code){const{passwordHash:r,version:n}=this.encryptPwd(e.newPassword),i={password:r,token:[]};n&&(i.password_secret_version=n);return E("upRes",await P.doc(t.data[0]._id).update(i)),{code:0,msg:""}}return{code:40202}}return{code:40201}},updateUser:async function(e){const t=e.uid;if(!t)return{code:N,messageValues:{param:this.t("user-id")}};delete e.uid;const{username:r,email:n}=e,{usernameToLowerCase:i,emailToLowerCase:o}=this._getConfig();let s=r&&r.trim(),a=n&&n.trim();return s&&(i&&(s=s.toLowerCase()),e.username=s),a&&(o&&(a=a.toLowerCase()),e.email=a),E("update -> upRes",await P.doc(t).update(e)),{code:0,msg:""}},banAccount:async function({uid:e}={}){return $.call(this,{uid:e,status:B})},unbanAccount:async function({uid:e}={}){return $.call(this,{uid:e,status:M})},closeAccount:async function({uid:e}={}){return $.call(this,{uid:e,status:F})},openAccount:async function({uid:e}={}){return $.call(this,{uid:e,status:M})},_getAlipayApi:function(){const e=this.context.PLATFORM,t=this._getConfig();if(!t.oauth||!t.oauth.alipay)throw new Error(this.t("config-param-require",{param:e+".alipay"}));return["appid","privateKey"].forEach(r=>{if(!t.oauth.alipay[r])throw new Error(this.t("config-param-require",{param:`${e}.alipay.${r}`}))}),Ur({...t.oauth.alipay})},_getValidInviteCode:async function({inviteCode:e}={}){if(e){return await Mr(e)?{code:0,inviteCode:e}:{code:80401}}return async function(){let e,t=10,r=!1;for(;t>0&&!r;){t--,e=Vr();if(await Mr(e)){r=!0;break}}return r?{code:0,inviteCode:e}:{code:80402}}()},_addUser:async function(e,{needPermission:t,autoSetDcloudAppid:r=!0}={}){const n=this._getConfig(),i={...e,dcloud_appid:r?[this.context.APPID]:[],register_date:Date.now()},o=(await P.add(i)).id;let s;if(n.removePermissionAndRoleFromToken)s=await this.createToken({uid:o,needPermission:t});else{const t=e.role||[];let r;r=0===t.length||t.includes("admin")?[]:await this._getPermissionListByRoleList(t),s=await this.createToken({uid:o,role:t,permission:r})}const{token:a,tokenExpired:c}=s;return await P.doc(o).update({token:[a]}),{token:a,tokenExpired:c,uid:o,type:"register",userInfo:Object.assign({},i,{token:[a]})}},_loginExec:async function(e,t={}){if(e.status===B)return{code:10001};if(e.status===F)return{code:10006};const r=this._getConfig();let n=e.token||[];"string"==typeof n&&(n=[n]);const i=this._getExpiredToken(n);let o;if(n=n.filter(e=>-1===i.indexOf(e)),r.removePermissionAndRoleFromToken){const r=t.needPermission;o=await this.createToken({uid:e._id,needPermission:r})}else{const t=e.role||[];let r;r=0===t.length||t.includes("admin")?[]:await this._getPermissionListByRoleList(t),o=await this.createToken({uid:e._id,role:t,permission:r})}const{token:s,tokenExpired:a}=o;n.push(s),e.token=n;const c={last_login_date:Date.now(),last_login_ip:this.context.CLIENTIP,token:n,...t.extraData};await P.doc(e._id).update(c);const u=Object.assign({},e,c);return{code:0,msg:"",token:s,uid:u._id,username:u.username,type:"login",userInfo:u,tokenExpired:a}},_registerExec:async function(e,{needPermission:t,autoSetDcloudAppid:r=!0}={}){const{my_invite_code:n}=e;if(this._getConfig().autoSetInviteCode||n){const t=await this._getValidInviteCode({inviteCode:n});if(t.code)return t;e.my_invite_code=t.inviteCode}const{PLATFORM:i,appId:o,appid:s,APPID:a,uniPlatform:c,appName:u,appVersion:d,appVersionCode:p,channel:l,clientIP:f,CLIENTIP:m,OS:h,osName:g}=this.context;return e.register_env={appid:o||s||a||"",uni_platform:c||i||"",os_name:g||h||"",app_name:u||"",app_version:d||"",app_version_code:p||"",channel:l?l+"":"",client_ip:f||m||""},{code:0,msg:"",...await this._addUser(e,{needPermission:t,autoSetDcloudAppid:r})}},_getWeixinApi:function(){const e=this.context.PLATFORM,t=this._getConfig();if(!t.oauth||!t.oauth.weixin)throw new Error(this.t("config-param-require",{param:e+".weixin"}));return["appid","appsecret"].forEach(r=>{if(!t.oauth.weixin[r])throw new Error(this.t("config-param-require",{param:`${e}.weixin.${r}`}))}),qr({...t.oauth.weixin})},_getQQApi:function(){const e=this.context.PLATFORM,t=this._getConfig();if(!t.oauth||!t.oauth.qq)throw new Error(this.t("config-param-require",{param:e+".qq"}));return["appid","appsecret"].forEach(r=>{if(!t.oauth.qq[r])throw new Error(this.t("config-param-require",{param:`${e}.qq.${r}`}))}),Nr({...t.oauth.qq})},_getMatchedUser:function(e,t){if(0===e.length)return{code:10002};let r;const n={},i={};for(let r=e.length-1;r>=0;r--){const o=e[r];for(let s=0;s<t.length;s++){const{field:a,value:c,fallbackValue:u}=t[s];c&&o[a]===c?(n[a]=o,e.splice(r,1)):u&&o[a]===u&&(n[a]||(n[a]=o),i[a]=!0,e.splice(r,1))}}const o=Object.keys(n);let s;switch(o.length){case 0:r=e[0],e.splice(0,1);break;case 1:s=o[0],r=n[s];break;default:return{code:10003,messageValues:{target:"用户"}}}return e.length>0?{code:10003,messageValues:{target:"用户"}}:{code:0,msg:"",userMatched:r,fieldMatched:s,isFallbackValueMatched:!!s&&i[s]}},_getCurrentAppUser:function(e){const t=this.context.APPID;return e.filter(e=>void 0===e.dcloud_appid||null===e.dcloud_appid||e.dcloud_appid.indexOf(t)>-1||e.dcloud_appid.indexOf(null)>-1)},_checkLoginUserList:function(e){if(e&&1!==e.length)return e[0].status===F?{code:10006}:{code:10005}},setAuthorizedAppLogin:async function({uid:e,dcloudAppidList:t}={}){if("array"!==m(t))return{code:U,messageValues:{param:"dcloudAppidList",reason:this.t("type-array-required",{param:this.t("dcloud-appid-list")})}};if(t&&0!==t.length){const r=await Fr.bind(this)({uid:e,dcloudAppidList:t});if(r.code)return r}return await P.doc(e).update({dcloud_appid:Br.set(t)}),{code:0}},authorizeAppLogin:async function({uid:e,dcloudAppid:t}={}){const r=await Fr.bind(this)({uid:e,dcloudAppidList:[t]});return r.code?r:(await P.doc(e).update({dcloud_appid:Br.push(t)}),{code:0})},forbidAppLogin:async function({uid:e,dcloudAppid:t}={}){return e?(await P.doc(e).update({dcloud_appid:Br.pull(t)}),{code:0}):{code:N,messageValues:{param:this.t("user-id")}}},acceptInvite:async function({uid:e,inviteCode:t}){const r=await P.where({_id:$r.neq(e),inviter_uid:$r.not($r.all([e])),my_invite_code:t}).get();if(1!==r.data.length)return{code:80501,msg:"邀请码无效"};const n=[r.data[0]._id].concat(r.data[0].inviter_uid||[]),i=await P.doc(e).field({my_invite_code:!0,inviter_uid:!0}).get();if(0===i.data.length)return{code:80502};if(i.data[0].inviter_uid&&i.data[0].inviter_uid.length>0)return{code:80503,msg:"邀请码不可修改"};const o=Date.now();return await P.doc(e).update({inviter_uid:n,invite_time:o}),await P.where({inviter_uid:e}).update({inviter_uid:$r.push(n)}),{code:0,msg:""}},getInvitedUser:async function({uid:e,level:t=1,limit:r=20,offset:n=0,needTotal:i=!1}){const o={code:0,msg:"",invitedUser:(await P.where({["inviter_uid."+(t-1)]:e}).field({_id:!0,username:!0,mobile:!0,invite_time:!0}).orderBy("invite_time","desc").skip(n).limit(r).get()).data};if(i){const r=await P.where({["inviter_uid."+(t-1)]:e}).count();o.total=r.total}return o},setUserInviteCode:async function({uid:e,myInviteCode:t}){const r=await this._getValidInviteCode({inviteCode:t});return r.code?r:(await P.doc(e).update({my_invite_code:r.inviteCode}),{code:0,msg:"",myInviteCode:r.inviteCode})},loginByAlipay:async function(e){"string"==typeof e&&(e={code:e});const{needPermission:t,code:r,myInviteCode:n,role:i,type:o}=e,{openid:s}=await this._getAlipayApi().code2Session(r);if(!s)return{code:10501,messageValues:{account:this.t("alipay-account")}};let a=await P.where({ali_openid:s}).get();if(a=this._getCurrentAppUser(a.data),a&&a.length>0){if("register"===o)return{code:10502,messageValues:{type:this.t("alipay-account")}};if(1!==a.length)return{code:10005};const e=a[0],r=await this._loginExec(e,{needPermission:t});if(0!==r.code)return r;const{userInfo:n}=r;return{...r,openid:s,mobileConfirmed:1===n.mobile_confirmed,emailConfirmed:1===n.email_confirmed}}{if("login"===o)return{code:10503,messageValues:{type:this.t("alipay-account")}};const e={ali_openid:s};e.my_invite_code=n,e.role=i;const r=await this._registerExec(e,{needPermission:t});return 0!==r.code?r:{...r,openid:s,mobileConfirmed:!1,emailConfirmed:!1}}},loginByEmail:async function(e){let{email:t,code:r,password:n,myInviteCode:i,type:o,needPermission:s,role:a}=e||{};if(t=t&&t.trim(),!t)return{code:N,messageValues:{param:"邮箱"}};const{emailToLowerCase:c}=this._getConfig();let u=t;c&&(u=t.toLowerCase());const d=await this.verifyCode({email:u,code:r,type:o||"login"});if(0!==d.code)return d;let p={email:t,email_confirmed:1};const l={field:"email",value:t},f=Hr.command;u!==t&&(p=f.or(p,{email:u,email_confirmed:1}),l.fallbackValue=u);let m=await P.where(p).get();if(m=this._getCurrentAppUser(m.data),m&&m.length>0){if("register"===o)return{code:10301,messageValues:{type:"邮箱"}};const e=this._getMatchedUser(m,[l]);if(e.code)return e;const{userMatched:t}=e,r=await this._loginExec(t,{needPermission:s});return 0!==r.code?r:{...r,email:u}}{if("login"===o)return{code:10302,messageValues:{type:"邮箱"}};const e={email:u,email_confirmed:1},t=n&&n.trim();if(t){const{passwordHash:r,version:n}=this.encryptPwd(t);e.password=r,n&&(e.password_secret_version=n)}e.my_invite_code=i,e.role=a;const r=await this._registerExec(e,{needPermission:s});return 0!==r.code?r:{...r,email:u}}},loginBySms:async function({mobile:e,code:t,password:r,inviteCode:n,myInviteCode:i,type:o,needPermission:s,role:a}){if(!(e=e&&e.trim()))return{code:N,messageValues:{param:this.t("mobile")}};const c=this._getConfig();if(c.forceInviteCode&&!o)throw new Error(this.t("login-with-invite-type-required"));const u=await this.verifyCode({mobile:e,code:t,type:o||"login"});if(0!==u.code)return u;const d={mobile:e,mobile_confirmed:1};let p=await P.where(d).get();if(p=this._getCurrentAppUser(p.data),p&&p.length>0){if("register"===o)return{code:10201,messageValues:{type:this.t("mobile")}};if(1!==p.length)return{code:10005};const t=p[0],r=await this._loginExec(t,{needPermission:s});return 0!==r.code?r:{...r,mobile:e}}{const t=Date.now();if("login"===o)return{code:10202,messageValues:{type:this.t("mobile")}};const u={mobile:e,mobile_confirmed:1,register_ip:this.context.CLIENTIP,register_date:t},d=r&&r.trim();if(d){const{passwordHash:e,version:t}=this.encryptPwd(d);u.password=e,t&&(u.password_secret_version=t)}if(n){const e=await P.where({my_invite_code:n}).get();if(1!==e.data.length)return{code:10203};u.inviter_uid=[e.data[0]._id].concat(e.data[0].inviter_uid||[]),u.invite_time=t}else if(c.forceInviteCode)return{code:10203};u.my_invite_code=i,u.role=a;const p=await this._registerExec(u,{needPermission:s});return 0!==p.code?p:{...p,mobile:e}}},loginByWeixin:async function(e){"string"==typeof e&&(e={code:e});const{needPermission:t,platform:r,code:n,myInviteCode:i,role:o,type:s}=e,a=r||this.context.PLATFORM,c=function({clientPlatform:e,userAgent:t}={}){switch(e){case"app":case"app-plus":return"app";case"mp-weixin":return"mp";case"h5":case"web":return t.indexOf("MicroMessenger")>-1?"h5":"web";default:throw new Error("Unsupported weixin platform")}}({clientPlatform:a,userAgent:this.context.CLIENTUA}),u="mp-weixin"===a,{openid:d,unionid:p,sessionKey:l,accessToken:f,refreshToken:m,expired:h}=await this._getWeixinApi()[u?"code2Session":"getOauthAccessToken"](n);if(!d)return{code:10401,messageValues:{account:"微信openid"}};const g={dcloudAppid:this.context.APPID,openid:d,platform:"weixin-"+c},y=require("uni-open-bridge-common");let w;u?(w={sessionKey:l},await y.setSessionKey(g,{session_key:l},2592e3)):(w={accessToken:f,refreshToken:m,accessTokenExpired:h},await y.setUserAccessToken(g,{access_token:f,refresh_token:m,access_token_expired:h},2592e3));const _=Gr.command,v=[{wx_openid:{[a]:d}}];p&&v.push({wx_unionid:p});let b=await P.where(_.or(...v)).get();if(b=this._getCurrentAppUser(b.data),b&&b.length>0){if("register"===s)return{code:10402,messageValues:{type:this.t("wechat-account")}};if(1!==b.length)return{code:10005};const e=b[0],r={wx_openid:{[a]:d}};p&&(r.wx_unionid=p);const n=await this._loginExec(e,{needPermission:t,extraData:r});if(0!==n.code)return n;const{userInfo:i}=n;return{...n,openid:d,unionid:p,...w,mobileConfirmed:1===i.mobile_confirmed,emailConfirmed:1===i.email_confirmed}}{if("login"===s)return{code:10403,messageValues:{type:this.t("wechat-account")}};const e={wx_openid:{[a]:d},wx_unionid:p};e.my_invite_code=i,e.role=o;const r=await this._registerExec(e,{needPermission:t});return 0!==r.code?r:{...r,openid:d,unionid:p,...w,mobileConfirmed:!1,emailConfirmed:!1}}},loginByQQ:async function({code:e,accessToken:t,accessTokenExpired:r,myInviteCode:n,needPermission:i,role:o,type:s}={}){const a=this.context.PLATFORM,c="mp-qq"===a,{openid:u,unionid:d,sessionKey:p}=await this._getQQApi()[c?"code2Session":"getOpenidByToken"]({code:e,accessToken:t});if(!u)return{code:10801,messageValues:{account:"qq openid"}};const l=function({clientPlatform:e}={}){switch(e){case"app":case"app-plus":return"app";case"mp-qq":return"mp";default:throw new Error("Unsupported qq platform")}}({clientPlatform:a}),f={dcloudAppid:this.context.APPID,openid:u,platform:"qq-"+l},m=require("uni-open-bridge-common");let h;c?(h={sessionKey:p},await m.setSessionKey(f,{session_key:p},2592e3)):(h={accessToken:t,accessTokenExpired:r},await m.setUserAccessToken(f,{access_token:t,access_token_expired:r},r?Math.floor((r-Date.now())/1e3):2592e3));const g=Qr.command,y=[{qq_openid:{[a]:u}}];d&&y.push({qq_unionid:d});let w=await P.where(g.or(...y)).get();if(w=this._getCurrentAppUser(w.data),w&&w.length>0){if("register"===s)return{code:10802,messageValues:{type:this.t("qq-account")}};if(1!==w.length)return{code:10005};const e=w[0],t={qq_openid:{[a]:u}};d&&(t.qq_unionid=d);const r=await this._loginExec(e,{needPermission:i,extraData:t});if(0!==r.code)return r;const{userInfo:n}=r;return{...r,openid:u,unionid:d,...h,mobileConfirmed:1===n.mobile_confirmed,emailConfirmed:1===n.email_confirmed}}{if("login"===s)return{code:10803,messageValues:{type:this.t("qq-account")}};const e={qq_openid:{[a]:u},qq_unionid:d};e.my_invite_code=n,e.role=o;const t=await this._registerExec(e);return 0!==t.code?t:{...t,openid:u,unionid:d,...h,mobileConfirmed:!1,emailConfirmed:!1}}},loginByUniverify:async function({openid:e,access_token:t,password:r,inviteCode:n,myInviteCode:i,type:o,needPermission:s,role:a}){const c=this._getConfig(),u=c&&c.service&&c.service.univerify;if(!u)throw new Error(this.t("uni-verify-config-required"));if(c.forceInviteCode&&!o)throw new Error(this.t("login-with-invite-type-required"));const d=await Xr.bind(this)({...u,openid:e,access_token:t});if(0!==d.code)return d;const p=String(d.phoneNumber);let l=await P.where({mobile:p,mobile_confirmed:1}).get();if(l=this._getCurrentAppUser(l.data),l&&l.length>0){if("register"===o)return{code:10601,messageValues:{type:this.t("mobile")}};if(1!==l.length)return{code:10005};const e=l[0],t=await this._loginExec(e,{needPermission:s});return 0!==t.code?t:{...t,mobile:p}}if("login"===o)return{code:10602,messageValues:{type:this.t("mobile")}};const f=Date.now(),m={mobile:p,my_invite_code:i,mobile_confirmed:1,role:a},h=r&&r.trim();if(h){const{passwordHash:e,version:t}=this.encryptPwd(h);m.password=e,t&&(m.password_secret_version=t)}if(n){let e=await P.where({my_invite_code:n}).get();if(1!==e.data.length)return{code:10203};e=e.data[0],m.inviter_uid=[e._id].concat(e.inviter_uid||[]),m.invite_time=f}else if(c.forceInviteCode)return{code:10203};m.my_invite_code=i;const g=await this._registerExec(m,{needPermission:s});return 0!==g.code?g:{...g,mobile:p}},loginByApple:async function({nickName:e,fullName:t,identityToken:r,myInviteCode:n,type:i,needPermission:o,role:s}){const a=this._getConfig(),c=a&&a.oauth&&a.oauth.apple,u=c&&c.bundleId;if(!u)throw new Error(this.t("config-param-require",{param:"(app || app-plus).apple.bundleId"}));if(!r)return{code:N,messageValues:{param:"identityToken"}};t=e||(t&&Object.keys(t).length>0?t.familyName+t.givenName:"");const{code:d,msg:p}=await Lr().verifyIdentityToken(r);if(0!==d)return{code:d,msg:p,messageValues:{account:this.t("apple-account")}};const{iss:l,sub:f,aud:m,email:h}=p;if("https://appleid.apple.com"!==l)return{code:10706,messageValues:{account:this.t("apple-account")}};if(!f)return{code:10701,messageValues:{account:this.t("apple-account")}};if(u!==m)return{code:10702,messageValues:{account:this.t("apple-account")}};const g=t||"User-"+(h?h.split("@")[0]:Math.random().toString(32).slice(2));let y=await P.where({apple_openid:f}).get();if(y=this._getCurrentAppUser(y.data),y&&y.length>0){if("register"===i)return{code:10703,messageValues:{type:this.t("apple-account")}};if(1!==y.length)return{code:10005};const e=y[0],t=await this._loginExec(e,{needPermission:o});return 0!==t.code?t:{...t,openid:f}}if("login"===i)return{code:10704,messageValues:{type:this.t("apple-account")}};const w={nickname:g,apple_openid:f,my_invite_code:n,role:s},_=await this._registerExec(w,{needPermission:o});return 0!==_.code?_:{..._,openid:f}},login:async function({username:e,password:t,queryField:r=[],needPermission:n}){const i=Yr.command,o=[];r&&r.length||(r=["username"]),r.length>1&&console.warn(this.t("query-field-warning"));const{usernameToLowerCase:s,emailToLowerCase:a,passwordErrorLimit:c,passwordErrorRetryTime:u}=this._getConfig(),d={email:{email_confirmed:1},mobile:{mobile_confirmed:1}},p={},l=e&&e.trim();if(!l)return{code:N,messageValues:{param:this.t("username")}};s&&(p.username=l.toLowerCase()),a&&(p.email=l.toLowerCase());const f=[];r.forEach(t=>{o.push({[t]:e,...d[t]});const r={field:t,value:e};"username"===t&&p.username!==e?(o.push({[t]:p.username,...d[t]}),r.fallbackValue=p.username):"email"===t&&p.email!==e&&(o.push({[t]:p.email,...d[t]}),r.fallbackValue=p.email),f.push(r)});let m=await P.where(i.or(...o)).get();m=this._getCurrentAppUser(m.data);const h=this.context.CLIENTIP,g=this._getMatchedUser(m,f);if(g.code)return g;const{userMatched:y}=g;let w=y.login_ip_limit||[];w=w.filter(e=>e.last_error_time>Date.now()-1e3*u);let _=w.find(e=>e.ip===h);if(_&&_.error_times>=c)return{code:10103};const v=t&&t.trim();if(!v)return{code:N,messageValues:{param:"密码"}};const b=this._checkPwd(y,v);if(0===b.code){const e=w.indexOf(_);e>-1&&w.splice(e,1);const t={login_ip_limit:w},{passwordHash:r,passwordVersion:i}=b;r&&i&&(t.password=r,t.password_secret_version=i);const o=await this._loginExec(y,{needPermission:n,extraData:t});return o.code,o}return _?(_.error_times++,_.last_error_time=Date.now()):(_={ip:h,error_times:1,last_error_time:Date.now()},w.push(_)),await P.doc(y._id).update({login_ip_limit:w}),{code:10102,msg:"密码错误"}},register:async function(e){const t=[],r=[{name:"username",desc:this.t("username")},{name:"email",desc:this.t("email"),extraCond:{email_confirmed:1}},{name:"mobile",desc:this.t("mobile"),extraCond:{mobile_confirmed:1}}],{usernameToLowerCase:n,emailToLowerCase:i}=this._getConfig();r.forEach(r=>{const o=r.name;let s=e[o]&&e[o].trim();s?(("username"===r.name&&n||"email"===r.name&&i)&&(s=s.toLowerCase()),e[o]=s,t.push({[o]:s,...r.extraCond})):delete e[o]});const{username:o,email:s,mobile:a,myInviteCode:c,needPermission:u,autoSetDcloudAppid:d=!0}=e;if("needPermission"in e&&delete e.needPermission,"autoSetDcloudAppid"in e&&delete e.autoSetDcloudAppid,0===t.length)return{code:20101,messageValues:{param:this.t("user-unique-param")}};const p=zr.command;let l=await P.where(p.or(...t)).get();if(l=this._getCurrentAppUser(l.data),l&&l.length>0){const t=l[0];if(t.status===F)return{code:10006};for(let n=0;n<r.length;n++){const i=r[n];let o=!0;if(i.extraCond&&(o=Object.keys(i.extraCond).every(e=>t[e]===i.extraCond[e])),t[i.name]===e[i.name]&&o)return{code:20102,messageValues:{type:i.desc}}}}const f=e.password&&e.password.trim();if(!f)return{code:N,messageValues:{param:this.t("password")}};const{passwordHash:m,version:h}=this.encryptPwd(f);e.password=m,h&&(e.password_secret_version=h),e.my_invite_code=c,delete e.myInviteCode;const g=await this._registerExec(e,{needPermission:u,autoSetDcloudAppid:d});return 0!==g.code?g:{...g,username:o,email:s,mobile:a}},logout:async function(e){const t=await this.checkToken(e);if(t.code)return t;const r=Wr.command;return await P.doc(t.uid).update({token:r.pull(e)}),{code:0,msg:""}},getRoleByUid:async function({uid:e}){if(!e)return{code:N,messageValues:{param:this.t("user-id")}};const t=await P.doc(e).get();return 0===t.data.length?{code:L}:{code:0,msg:"",role:t.data[0].role||[]}},getPermissionByRole:async function({roleID:e}){if(!e)return{code:N,messageValues:{param:"roleID"}};if("admin"===e){return{code:0,msg:"",permission:(await D.limit(1e3).get()).data.map(e=>e.permission_id)}}const t=await j.where({role_id:e}).get();return 0===t.data.length?{code:V}:{code:0,msg:"",permission:t.data[0].permission||[]}},getPermissionByUid:async function({uid:e}={}){const t=await P.aggregate().match({_id:e}).project({role:!0}).unwind("$role").lookup({from:"uni-id-roles",localField:"role",foreignField:"role_id",as:"roleDetail"}).unwind("$roleDetail").replaceRoot({newRoot:"$roleDetail"}).end(),r=[],n=[];return t.data.forEach(e=>{n.push(e.role_id),r.push(...e.permission)}),{code:0,msg:"",role:n,permission:A(r)}},bindRole:async function({uid:e,roleList:t,reset:r=!1}){const n={};return"string"==typeof t&&(t=[t]),n.role=r?t:Jr.push(t),await P.doc(e).update(n),{code:0,msg:""}},bindPermission:async function({roleID:e,permissionList:t,reset:r=!1}){const n={};return"string"==typeof t&&(t=[t]),n.permission=r?t:Jr.push(t),await j.where({role_id:e}).update(n),{code:0,msg:""}},unbindRole:async function({uid:e,roleList:t}){return"string"==typeof t&&(t=[t]),await P.doc(e).update({role:Jr.pull(Jr.in(t))}),{code:0,msg:""}},unbindPermission:async function({roleID:e,permissionList:t}){return"string"==typeof t&&(t=[t]),await j.where({role_id:e}).update({permission:Jr.pull(Jr.in(t))}),{code:0,msg:""}},addRole:async function({roleID:e,roleName:t,comment:r,permission:n=[]}){return e?"admin"===e?{code:U,messageValues:{param:"roleID",reason:this.t("add-role-admin-is-not-allowed")}}:(await j.add({role_id:e,role_name:t,comment:r,permission:n,create_date:Date.now()}),{code:0,msg:""}):{code:N,messageValues:{param:this.t("role-id")}}},addPermission:async function({permissionID:e,permissionName:t,comment:r}){return e?(await D.add({permission_id:e,permission_name:t,comment:r,create_date:Date.now()}),{code:0,msg:""}):{code:N,messageValues:{param:this.t("permission-id")}}},getRoleList:async function({limit:e=20,offset:t=0,needTotal:r=!0}){const n={code:0,msg:"",roleList:(await j.skip(t).limit(e).get()).data};if(r){const{total:e}=await j.where({_id:Jr.exists(!0)}).count();n.total=e}return n},getRoleInfo:async function(e){const t=await j.where({role_id:e}).get();return 0===t.data.length?{code:V}:{code:0,...t.data[0]}},updateRole:async function({roleID:e,roleName:t,comment:r,permission:n}){return e?(await j.where({role_id:e}).update({role_name:t,comment:r,permission:n}),{code:0,msg:""}):{code:N,messageValues:{param:this.t("role-id")}}},deleteRole:async function({roleID:e}){const t=m(e);if("string"===t)e=[e];else if("array"!==t)throw new Error("typeof roleID must be array or string");return await j.where({role_id:Jr.in(e)}).remove(),await P.where({role:Jr.elemMatch(Jr.in(e))}).update({role:Jr.pullAll(e)}),{code:0,msg:""}},getPermissionList:async function({limit:e=20,offset:t=0,needTotal:r=!0}){const n={code:0,msg:"",permissionList:(await D.skip(t).limit(e).get()).data};if(r){const{total:e}=await D.where({_id:Jr.exists(!0)}).count();n.total=e}return n},getPermissionInfo:async function(e){const t=await D.where({permission_id:e}).get();return 0===t.data.length?{code:N,messageValues:{param:this.t("permission-id")}}:{code:0,...t.data[0]}},updatePermission:async function({permissionID:e,permissionName:t,comment:r}){return e?(await D.where({permission_id:e}).update({permission_name:t,comment:r}),{code:0,msg:""}):{code:N,messageValues:{param:this.t("permission-id")}}},deletePermission:async function({permissionID:e}){const t=m(e);if("string"===t)e=[e];else if("array"!==t)throw new Error("typeof permissionID must be array or string");return await D.where({permission_id:Jr.in(e)}).remove(),await j.where({permission:Jr.elemMatch(Jr.in(e))}).update({permission:Jr.pullAll(e)}),{code:0,msg:""}},bindAlipay:async function({uid:e,code:t,platform:r}){const n=r||this.context.PLATFORM,{openid:i}=await this._getAlipayApi({platform:n}).code2Session(t);if(!i)return{code:60401,messageValues:{account:this.t("alipay-account")}};let o=await P.where({ali_openid:i}).get();return o=this._getCurrentAppUser(o.data),o&&o.length>0?{code:60402,messageValues:{type:this.t("alipay-account")}}:(await P.doc(e).update({ali_openid:i}),{code:0,openid:i,msg:""})},bindEmail:async function(e){let{uid:t,email:r,code:n}=e||{};if(r=r&&r.trim(),!r)return{code:N,messageValues:{param:this.t("email")}};if(!n)return{code:N,messageValues:{param:this.t("verify-code")}};const{emailToLowerCase:i}=this._getConfig();i&&(r=r.toLowerCase());let o=await P.where({email:r,email_confirmed:1}).get();if(o=this._getCurrentAppUser(o.data),o&&o.length>0)return{code:60201,messageValues:{type:this.t("email")}};const s=await this.verifyCode({email:r,code:n,type:"bind"});return 0!==s.code?s:(await P.doc(t).update({email:r,email_confirmed:1}),{code:0,msg:"",email:r})},bindMobile:async function(e){let{uid:t,mobile:r,code:n,openid:i,access_token:o,type:s="sms"}=e||{};if("univerify"===s){const e=this._getConfig(),t=e&&e.service&&e.service.univerify;if(!t)throw new Error("请在config.json中配置service.univerify下一键登录相关参数");const n=await Xr.bind(this)({...t,openid:i,access_token:o});if(0!==n.code)return n;r=""+n.phoneNumber}let a=await P.where({mobile:r,mobile_confirmed:1}).get();if(a=this._getCurrentAppUser(a.data),a&&a.length>0)return{code:60101,messageValues:{type:"手机号"}};if("sms"===s&&"code"in e){if(!r)return{code:N,messageValues:{param:this.t("mobile")}};if(!n)return{code:N,messageValues:{param:this.t("verify-code")}};const e=await this.verifyCode({mobile:r,code:n,type:"bind"});if(0!==e.code)return e}return await P.doc(t).update({mobile:r,mobile_confirmed:1}),{code:0,msg:"",mobile:r}},bindWeixin:async function({uid:e,code:t,platform:r}){const n=r||this.context.PLATFORM,i="mp-weixin"===n,{openid:o,unionid:s,sessionKey:a,accessToken:c,refreshToken:u,expired:d}=await this._getWeixinApi({platform:n})[i?"code2Session":"getOauthAccessToken"](t);if(!o)return{code:60301,messageValues:{account:"微信openid"}};const p=Zr.command,l=[{wx_openid:{[n]:o}}];s&&l.push({wx_unionid:s});let f=await P.where(p.or(...l)).get();if(f=this._getCurrentAppUser(f.data),f&&f.length>0)return{code:60302,messageValues:{type:this.t("wechat-account")}};const m={wx_openid:{[n]:o}};let h;return s&&(m.wx_unionid=s),await P.doc(e).update(m),h=i?{sessionKey:a}:{accessToken:c,refreshToken:u,accessTokenExpired:d},{code:0,msg:"",openid:o,unionid:s,...h}},bindQQ:async function({uid:e,code:t,accessToken:r,platform:n}={}){const i=n||this.context.PLATFORM,o="mp-qq"===i,{openid:s,unionid:a,sessionKey:c}=await this._getQQApi()[o?"code2Session":"getOpenidByToken"]({code:t,accessToken:r});if(!s)return{code:60501,messageValues:{account:"qq openid"}};const u=en.command,d=[{qq_openid:{[i]:s}}];a&&d.push({qq_unionid:a});let p=await P.where(u.or(...d)).get();if(p=this._getCurrentAppUser(p.data),p&&p.length>0)return{code:60502,messageValues:{type:this.t("qq-account")}};const l={qq_openid:{[i]:s}};return a&&(l.qq_unionid=a),await P.doc(e).update(l),{code:0,msg:"",openid:s,unionid:a,...{accessToken:r,sessionKey:c}}},unbindAlipay:async function(e){const t=tn.command,r=await P.doc(e).update({ali_openid:t.remove()});return E("upRes:",r),1===r.updated?{code:0,msg:""}:{code:70401}},unbindEmail:async function(e){let{uid:t,email:r,code:n}=e||{};if(r=r&&r.trim(),!t||!r)return{code:N,messageValues:{param:t?this.t("email"):this.t("user-id")}};const{emailToLowerCase:i}=this._getConfig();if("code"in e){const e=await this.verifyCode({email:r,code:n,type:"unbind"});if(0!==e.code)return e}const o=rn.command;let s={_id:t,email:r};if(i){const e=r.toLowerCase();e!==r&&(s=o.or(s,{_id:t,email:e}))}return 1===(await P.where(s).update({email:o.remove(),email_confirmed:o.remove()})).updated?{code:0,msg:""}:{code:70201}},unbindMobile:async function(e){const{uid:t,mobile:r,code:n}=e||{};if("code"in e){const e=await this.verifyCode({mobile:r,code:n,type:"unbind"});if(0!==e.code)return e}const i=nn.command;return 1===(await P.where({_id:t,mobile:r}).update({mobile:i.remove(),mobile_confirmed:i.remove()})).updated?{code:0,msg:""}:{code:70101}},unbindWeixin:async function(e){const t=on.command,r=await P.doc(e).update({wx_openid:t.remove(),wx_unionid:t.remove()});return E("upRes:",r),1===r.updated?{code:0,msg:""}:{code:70301}},unbindQQ:async function(e){const t=sn.command,r=await P.doc(e).update({qq_openid:t.remove(),qq_unionid:t.remove()});return E("upRes:",r),1===r.updated?{code:0,msg:""}:{code:70501}},getSupportedLoginType:function({appid:e,platform:t}={}){if(!e||!t)throw new Error("Parameter appid and platform is required");const r=this._getConfig({appid:e,platform:t}),n=["username-password","mobile-password","email-password"];for(const e in an)an[e](r)&&n.push(e);return{supportedLoginType:n}},code2SessionAlipay:async function(e){let t=e;"string"==typeof e&&(t={code:e});try{const e=t.platform||this.context.PLATFORM,r=await this._getAlipayApi({platform:e}).code2Session(t.code);return r.openid?{code:0,msg:"",...r}:{code:80701,messageValues:{account:this.t("alipay-account")}}}catch(e){return console.error(e),{code:80702,messageValues:{account:this.t("alipay-account")}}}},code2SessionWeixin:async function(e){let t=e;"string"==typeof e&&(t={code:e});try{const e=t.platform||this.context.PLATFORM,r=await this._getWeixinApi({platform:e})["mp-weixin"===e?"code2Session":"getOauthAccessToken"](t.code);return r.openid?{code:0,msg:"",...r}:{code:80601,messageValues:{account:"微信openid"}}}catch(e){return console.error(e),{code:80602,messageValues:{account:"微信openid"}}}},verifyAppleIdentityToken:async function({identityToken:e,platform:t}){const r=t||this.context.PLATFORM,{code:n,msg:i}=await Lr({clientType:r}).verifyIdentityToken(e);return 0!==n?{code:n,msg:i}:{code:n,msg:"验证通过",...i}},wxBizDataCrypt:async function({code:e,sessionKey:r,encryptedData:n,iv:i}){if(!n)return{code:N,messageValues:{param:"encryptedData"}};if(!i)return{code:N,messageValues:{param:"iv"}};if(!e&&!r)return{code:N,messageValues:{param:"sessionKey"}};const o=this._getWeixinApi();if(!r){const t=await o.code2Session(e);if(!t.sessionKey)return{code:80801};r=t.sessionKey}r=Buffer.from(r,"base64"),n=Buffer.from(n,"base64"),i=Buffer.from(i,"base64");try{var s=t.createDecipheriv("aes-128-cbc",r,i);s.setAutoPadding(!0);var a=s.update(n,"binary","utf8");a+=s.final("utf8"),a=JSON.parse(a)}catch(e){return console.error(e),{code:80802}}return a.watermark.appid!==o.options.appId?{code:80803}:{code:0,msg:"",...a}},getWeixinUserInfo:async function({accessToken:e,openid:t}={}){const r=this.context.PLATFORM;if("app"!==r&&"app-plus"!==r)throw new Error(this.t("limit-client-platform"));try{return{code:0,msg:"",...await this._getWeixinApi().getUserInfo({accessToken:e,openid:t})}}catch(e){return console.error(e),{code:80901}}},encryptPwd:function(e,{value:r,version:n}={}){if(!(e=e&&e.trim()))throw new Error(this.t("param-required",{param:this.t("password")}));if(!r){const e=this._getConfig(),{passwordSecret:t}=e;if("array"===m(t)){const e=t.sort((e,t)=>e.version-t.version);r=e[e.length-1].value,n=e[e.length-1].version}else r=t}if(!r)throw new Error(this.t("param-error",{param:"passwordSecret",reason:"invalid passwordSecret"}));const i=t.createHmac("sha1",r.toString("ascii"));return i.update(e),{passwordHash:i.digest("hex"),version:n}},checkToken:async function(e,{needPermission:t,needUserInfo:r=!0}={}){const n=this._getConfig(),i=this._verifyToken(e);if(i.code)return i;const{uid:o,needPermission:s,role:a,permission:c,exp:u,iat:d,...p}=i,l=a&&c;t=void 0===t?s:t;const f=n.removePermissionAndRoleFromToken||!l||r,m=!n.removePermissionAndRoleFromToken&&!l||n.removePermissionAndRoleFromToken&&l||n.tokenExpiresThreshold&&u-Date.now()/1e3<n.tokenExpiresThreshold;let h={};if(f||m){const t=await P.doc(o).get();if(!t.data||0===t.data.length||!t.data[0].token)return{code:30202};if(h=t.data[0],h.status===B)return{code:10001};if(h.status===F)return{code:10006};let r=h.token;if(r?"string"==typeof r&&(r=[r]):r=[],-1===r.indexOf(e))return{code:30202}}const g={code:0,uid:o,...p};let y,w;if(l&&(g.role=a,g.permission=c),r&&(g.userInfo=h),(!l&&t||m)&&(y=g.role=h.role||[],w=0===y.length||y.includes("admin")?g.permission=[]:g.permission=await this._getPermissionListByRoleList(g.role),t&&(g.role=y,g.permission=w)),m){let e;e=n.removePermissionAndRoleFromToken?await this.createToken({uid:o,needPermission:s}):await this.createToken({uid:o,role:y,permission:w});const t=h.token;return await this._updateToken({uid:o,tokenList:t,addToken:[e.token]}),{...g,...e}}return g},createToken:function({uid:e,needPermission:t,role:r,permission:n}){if(!e)return{code:30101,messageValues:{param:this.t("user-id")}};const i={uid:e,needPermission:t,role:r,permission:n},o=this._getConfig();if(!this.interceptorMap.has("customToken")){const e={...i};return this._createTokenInternal({signContent:e,config:o})}const s=this.interceptorMap.get("customToken");if("function"!=typeof s)throw new Error(this.t("type-function-required","customToken"));const a=s(i);return a instanceof Promise?a.then(e=>this._createTokenInternal({signContent:e,config:o})):this._createTokenInternal({signContent:a,config:o})},_updateToken:async function({uid:e,tokenList:t,removeToken:r=[],addToken:n=[]}={}){if(!t){const r=await P.doc(e).get(),n=r.data&&r.data[0];t=n&&n.token||[]}"string"==typeof t&&(t=[t]);const i=this._getExpiredToken(t);(t=t.filter(e=>-1===i.indexOf(e))).push(...n);for(let e=0;e<r.length;e++){const n=t.indexOf(r[e]);t.splice(n,1)}await P.doc(e).update({token:t,last_login_date:Date.now(),last_login_ip:this.context.CLIENTIP})},refreshToken:async function({token:e}={}){const t=this._getConfig(),r=this._verifyToken(e);if(r.code)return r;const{uid:n,needPermission:i}=r;let o;if(t.removePermissionAndRoleFromToken)o=await this.createToken({uid:n,needPermission:i});else{const{role:e,permission:t}=await this.getPermissionByUid({uid:n});o=await this.createToken({uid:n,role:e,permission:t})}return await this._updateToken({uid:n,addToken:[o.token],removeToken:[e]}),o},_checkPwd:function(e,t){if(!t)return{code:1};const{password:r,password_secret_version:n}=e,i=this._getConfig(),{passwordSecret:o}=i,s=m(o);if("string"===s){const{passwordHash:e}=this.encryptPwd(t,{value:o});return e===r?{code:0,message:""}:{code:2}}if("array"!==s)throw new Error(this.t("password-secret-type-error"));const a=o.sort((e,t)=>e.version-t.version);let c;if(c=n?a.find(e=>e.version===n):a[0],!c)return{code:3};const u=a[a.length-1],{passwordHash:d}=this.encryptPwd(t,c);if(d===r){const e={code:0};if(c!==u){const{passwordHash:r,version:n}=this.encryptPwd(t,u);e.passwordHash=r,e.passwordVersion=n}return e}return{code:4,message:""}},_verifyToken:function(e){const t=this._getConfig();let r;try{r=Pr(e,t.tokenSecret)}catch(e){return"TokenExpiredError"===e.name?{code:30203,err:e}:{code:30204,err:e}}return t.bindTokenToDevice&&r.clientId&&r.clientId!==this._getClientUaHash()?{code:30201}:{code:0,message:"",...r}},_getExpiredToken:function(e){const t=this._getConfig(),r=[];return e.forEach(e=>{try{Pr(e,t.tokenSecret)}catch(t){r.push(e)}}),r},_getPermissionListByRoleList:async function(e){if(!Array.isArray(e))return[];if(0===e.length)return[];if(e.includes("admin")){return(await D.limit(500).get()).data.map(e=>e.permission_id)}const t=await j.where({role_id:Kr.in(e)}).get(),r=[];return t.data.forEach(e=>{Array.prototype.push.apply(r,e.permission)}),A(r)},_getClientUaHash:function(){const e=t.createHash("md5"),r=/MicroMessenger/i.test(this.context.CLIENTUA)?this.context.CLIENTUA.replace(/(MicroMessenger\S+).*/i,"$1"):this.context.CLIENTUA;return e.update(r),e.digest("hex")},_createTokenInternal:function({signContent:e,config:t}){if(t.tokenExpiresIn&&t.tokenExpiresThreshold&&t.tokenExpiresIn<=t.tokenExpiresThreshold)throw new Error(this.t("token-expires-config-warning"));return"object"===m(e)&&e.uid?(t.bindTokenToDevice&&(e.clientId=this._getClientUaHash()),{token:Rr(e,t.tokenSecret,{expiresIn:t.tokenExpiresIn}),tokenExpired:Date.now()+1e3*t.tokenExpiresIn}):{code:30101,messageValues:{param:this.t("user-id")}}},setVerifyCode:async function({mobile:e,email:t,code:r,expiresIn:n,type:i}){if(t=t&&t.trim(),e=e&&e.trim(),t){const{emailToLowerCase:e}=this._getConfig();e&&(t=t.toLowerCase())}if(!e&&!t)return{code:50101,messageValues:{param:"手机号或邮箱"}};if(e&&t)return{code:50102,messageValues:{param:"参数",reason:"手机号和邮箱不可同时存在"}};r||(r=C()),n||(n=180);const o=Date.now(),s={mobile:e,email:t,type:i,code:r,state:0,ip:this.context.CLIENTIP,created_at:o,expired_at:o+1e3*n};return await R.add(s),{code:0,mobile:e,email:t}},verifyCode:async function({mobile:e,email:t,code:r,type:n}){if(t=t&&t.trim(),e=e&&e.trim(),t){const{emailToLowerCase:e}=this._getConfig();e&&(t=t.toLowerCase())}if(!e&&!t)return{code:50201,messageValues:{param:"手机号或邮箱"}};if(e&&t)return{code:50203,messageValues:{param:"参数",reason:"手机号和邮箱不可同时存在"}};if(!r)return{code:50202,messageValues:{type:this.t(e?"sms":"email")}};const i=cn.command,o=Date.now(),s={mobile:e,email:t,type:n,code:r,state:0,expired_at:i.gt(o)},a=await R.where(s).orderBy("created_at","desc").limit(1).get();if(a&&a.data&&a.data.length>0){const e=a.data[0];return await R.doc(e._id).update({state:1}),{code:0,msg:"验证通过"}}return{code:50202,messageValues:{type:this.t(e?"sms":"email")}}},sendSmsCode:async function({mobile:e,code:t,type:r,templateId:n}){if(!e)return{code:N,messageValues:{param:this.t("mobile")}};if(t||(t=C()),!r)return{code:N,messageValues:{param:this.t("verify-code-type")}};const i=this._getConfig();let o=i&&i.service&&i.service.sms;if(!o)throw new Error(this.t("config-param-required",{param:"service.sms"}));o=Object.assign({codeExpiresIn:300},o);const{name:s,smsKey:a,smsSecret:c,codeExpiresIn:u}=o;let d;switch(r){case"login":d=this.t("login");break;default:d=this.t("verify-mobile")}try{const i={name:s,code:t,action:d,expMinute:""+Math.round(u/60)};s&&(i.name=s),await uniCloud.sendSms({smsKey:a,smsSecret:c,phone:e,templateId:n||"uniID_code",data:i});const o=await this.setVerifyCode({mobile:e,code:t,expiresIn:u,type:r});return o.code>=0?o:{code:0,msg:""}}catch(e){return console.error(e),{code:50301}}}});let dn;try{dn=require("uni-config-center")}catch(e){throw new Error("Plugin[uni-config-center] was not found")}class pn{constructor({context:e,clientInfo:t,config:r}={}){const n=dn({pluginId:"uni-id"});this.pluginConfig=n,this.config=r||this._getConfigContent(),this._configCache={},Object.defineProperty(this,"context",{get(){let r;r=t?{OS:t.os,CLIENTIP:t.clientIP,CLIENTUA:t.userAgent,PLATFORM:t.platform,APPID:t.appId,LOCALE:t.locale,DEVICEID:t.deviceId}:Object.assign({},e||global.__ctx__||{});const n=["CLIENTIP","PLATFORM","APPID","LOCALE"];for(let e=0;e<n.length;e++){const t=n[e];void 0===r[t]&&console.warn(i.t("context-required",{key:t}))}const o=r.APPID,s=r.PLATFORM,a=this._getAppConfig(this.config,o);if(!a)throw new Error(`Config for current app (${o}) was not found, please check your config file or client appId`);if("app"===s||"app-plus"===s?r.PLATFORM=a.preferedAppPlatform||s:"web"!==s&&"h5"!==s||(r.PLATFORM=a.preferedWebPlatform||s),"app"===r.PLATFORM&&a["app-plus"]||"app-plus"===r.PLATFORM&&a.app)throw new Error(`Client platform is ${r.PLATFORM}, but ${"app"===r.PLATFORM?"app-plus":"app"} was found in config. Please refer to: https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=prefered-app-platform`);if("web"===r.PLATFORM&&a.h5||"h5"===r.PLATFORM&&a.web)throw new Error(`Client platform is ${r.PLATFORM}, but ${"web"===r.PLATFORM?"h5":"web"} was found in config. Please refer to: https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=prefered-web-platform`);return r}}),this.interceptorMap=new Map,n&&n.hasFile("custom-token.js")&&this.setInterceptor("customToken",require(n.resolve("custom-token.js")));let i,o=k;if(n&&n.hasFile("lang/index.js")){const e=n.requireFile("lang/index.js");o=function(e,t){const r=Object.keys(e);r.push(...Object.keys(t));const n={};for(let i=0;i<r.length;i++){const o=r[i];n[o]=Object.assign({},e[o],t[o])}return n}(k,e)}if(!uniCloud.initI18n)throw new Error("The HBuilderX version is too old, please upgrade to the latest version of HBuilderX");i=uniCloud.initI18n({locale:"en",fallbackLocale:"zh-Hans",messages:o}),Object.defineProperty(this,"t",{get(){return i.setLocale(this.context.LOCALE||"zh-Hans"),i.t.bind(i)}})}get dev(){return console.warn(this.t("dev-warning")),{getConfig:this._getConfig.bind(this)}}_getAppConfig(e,t){return Array.isArray(e)?e.find(e=>e.dcloudAppid===t)||e.find(e=>e.isDefaultConfig):e}_parseConfigContent(e){return Array.isArray(e)?e:e[0]?Object.values(e):e}_getConfigContent(){if(this.pluginConfig&&this.pluginConfig.hasFile("config.json")){let e;try{e=this.pluginConfig.config()}catch(e){throw new Error("Invalid uni-id config file\n"+e.message)}return this._parseConfigContent(e)}{let e;try{e=require("./config.json")}catch(e){if("MODULE_NOT_FOUND"===e.code||"ENOENT"===e.code)throw new Error("uni-id config file[uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json] not found");throw e}return this._parseConfigContent(e)}}init(){throw new Error("uniID.init has been deprecated, use uniID.createInstance instead")}setInterceptor(e,t){this.interceptorMap.set(e,t)}_getConfig({appid:e,platform:t}={}){const r=`${e=e||this.context.APPID}_${t=t||this.context.PLATFORM}`;if(this._configCache[r])return this._configCache[r];if(!(this.config&&0!==Object.keys(this.config).length))throw new Error(this.t("config-file-not-found"));const n=this._getAppConfig(this.config,e);"app"!==t&&"app-plus"!==t||(t=n.preferedAppPlatform||t),"web"!==t&&"h5"!==t||(t=n.preferedWebPlatform||t);const i=Object.assign(n,n[t])||{},o=Object.assign({bindTokenToDevice:!1,tokenExpiresIn:7200,tokenExpiresThreshold:1200,passwordErrorLimit:6,passwordErrorRetryTime:3600,usernameToLowerCase:!0,emailToLowerCase:!0},i);return["passwordSecret","tokenSecret","tokenExpiresIn","passwordErrorLimit","passwordErrorRetryTime"].forEach(e=>{if(!o||!o[e])throw new Error(this.t("config-param-required",{param:e}))}),this._configCache[r]=o,o}}for(const e in un)pn.prototype[e]=un[e];function ln(e){const t=new pn(e);return new Proxy(t,{get(e,t){if(t in e&&0!==t.indexOf("_")){if("function"==typeof e[t])return(r=e[t],function(){const e=r.apply(this,arguments);return f(e)?e.then(e=>(S.bind(this)(e),e)):(S.bind(this)(e),e)}).bind(e);if("context"!==t&&"config"!==t)return e[t]}var r}})}pn.prototype.createInstance=ln;var fn=ln();module.exports=fn;
+"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var t=e(require("crypto")),r=e(require("buffer")),n=e(require("stream")),i=e(require("util"));const o={PARAM_ERROR:{errCode:"param-error"},PARAM_REQUIRED:{errCode:"param-required"},USER_NOT_EXIST:{errCode:"user-not-exist"},ROLE_NOT_EXIST:{errCode:"role-not-exist"},PERMISSION_NOT_EXIST:{errCode:"permission-not-exist"},MULTI_USER_MATCHED:{errCode:"multi-user-matched"},USER_INFO_ERROR:{errCode:"user-info-error"},USER_ACCOUNT_CONFLICT:{errCode:"user-account-conflict"},USER_ACCOUNT_CLOSED:{errCode:"user-account-closed"},ACCOUNT_EXISTS:{errCode:"account-exists"},ACCOUNT_NOT_EXISTS:{errCode:"account-not-exists"},ACCOUNT_BOUND:{errCode:"account-bound"},UNBIND_FAILED:{errCode:"unbind-failed"},INVALID_INVITE_CODE:{errCode:"invalid-invite-code"},SET_INVITE_CODE_FAILED:{errCode:"set-invite-code-failed"},GET_THIRD_PARTY_ACCOUNT_FAILED:{errCode:"get-third-party-account-failed"},GET_THIRD_PARTY_USER_INFO_FAILED:{errCode:"get-third-party-user-info-failed"}},s={0:{errCode:0,errMsg:""},10001:{errCode:"account-banned"},10002:o.USER_NOT_EXIST,10003:o.MULTI_USER_MATCHED,10004:o.USER_INFO_ERROR,10005:o.USER_ACCOUNT_CONFLICT,10006:o.USER_ACCOUNT_CLOSED,10102:{errCode:"password-error"},10103:{errCode:"password-error-exceed-limit"},10201:o.ACCOUNT_EXISTS,10202:o.ACCOUNT_NOT_EXISTS,10203:o.INVALID_INVITE_CODE,10301:o.ACCOUNT_EXISTS,10302:o.ACCOUNT_NOT_EXISTS,10401:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10402:o.ACCOUNT_EXISTS,10403:o.ACCOUNT_NOT_EXISTS,10501:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10502:o.ACCOUNT_EXISTS,10503:o.ACCOUNT_NOT_EXISTS,10601:o.ACCOUNT_EXISTS,10602:o.ACCOUNT_NOT_EXISTS,10701:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10702:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10703:o.ACCOUNT_EXISTS,10704:o.ACCOUNT_NOT_EXISTS,10705:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10706:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10801:o.GET_THIRD_PARTY_ACCOUNT_FAILED,10802:o.ACCOUNT_EXISTS,10803:o.ACCOUNT_NOT_EXISTS,20101:o.PARAM_REQUIRED,20102:o.ACCOUNT_EXISTS,30101:o.PARAM_REQUIRED,30201:{errCode:"check-device-feature-failed"},30202:{errCode:"token-not-exist"},30203:{errCode:"token-expired"},30204:{errCode:"check-token-failed"},40201:o.USER_NOT_EXIST,40202:{errCode:"invalid-old-password"},50101:o.PARAM_REQUIRED,50102:o.PARAM_ERROR,50201:o.PARAM_REQUIRED,50203:o.PARAM_ERROR,50202:{errCode:"invalid-verify-code"},50301:{errCode:"send-sms-code-failed"},60101:o.ACCOUNT_BOUND,60201:o.ACCOUNT_BOUND,60301:o.GET_THIRD_PARTY_ACCOUNT_FAILED,60302:o.ACCOUNT_BOUND,60401:o.GET_THIRD_PARTY_ACCOUNT_FAILED,60402:o.ACCOUNT_BOUND,60501:o.GET_THIRD_PARTY_ACCOUNT_FAILED,60502:o.ACCOUNT_BOUND,70101:o.UNBIND_FAILED,70201:o.UNBIND_FAILED,70301:o.UNBIND_FAILED,70401:o.UNBIND_FAILED,70501:o.UNBIND_FAILED,80301:o.USER_NOT_EXIST,80401:o.SET_INVITE_CODE_FAILED,80402:o.SET_INVITE_CODE_FAILED,80501:o.INVALID_INVITE_CODE,80502:o.USER_NOT_EXIST,80503:{errCode:"modify-invite-code-is-not-allowed"},80601:o.GET_THIRD_PARTY_ACCOUNT_FAILED,80602:o.GET_THIRD_PARTY_ACCOUNT_FAILED,80701:o.GET_THIRD_PARTY_ACCOUNT_FAILED,80702:o.GET_THIRD_PARTY_ACCOUNT_FAILED,80801:{errCode:"decrypt-weixin-data-failed"},80802:{errCode:"decrypt-weixin-data-failed"},80803:{errCode:"invalid-weixin-appid"},80804:o.PARAM_REQUIRED,80805:o.PARAM_REQUIRED,80806:o.PARAM_REQUIRED,80901:o.GET_THIRD_PARTY_USER_INFO_FAILED,90001:{errCode:"database-operation-failed"},90002:o.PARAM_REQUIRED,90003:o.PARAM_ERROR,90004:o.USER_NOT_EXIST,90005:o.ROLE_NOT_EXIST,90006:o.PERMISSION_NOT_EXIST};class a extends Error{constructor(e){super(e.message),this.errMsg=e.message||"",Object.defineProperties(this,{message:{get(){return`errCode: ${e.code||""} | errMsg: `+this.errMsg},set(e){this.errMsg=e}}})}}const c=Object.prototype.toString,u=Object.prototype.hasOwnProperty;function d(e,t){return u.call(e,t)}function p(e){return"[object Object]"===c.call(e)}function l(e){return"function"==typeof e}function f(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"function"==typeof e.then}function m(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}const h=/_(\w)/g,g=/[A-Z]/g;function y(e){return e.replace(h,(e,t)=>t?t.toUpperCase():"")}function w(e){return e.replace(g,e=>"_"+e.toLowerCase())}function v(e,t){let r,n;switch(t){case"snake2camel":n=y,r=h;break;case"camel2snake":n=w,r=g}for(const i in e)if(d(e,i)&&r.test(i)){const r=n(i);e[r]=e[i],delete e[i],p(e[r])?e[r]=v(e[r],t):Array.isArray(e[r])&&(e[r]=e[r].map(e=>v(e,t)))}return e}function _(e){return v(e,"snake2camel")}function b(e){return v(e,"camel2snake")}function T(e){return function(e,t="-"){e=e||new Date;const r=[];return r.push(e.getFullYear()),r.push(("00"+(e.getMonth()+1)).substr(-2)),r.push(("00"+e.getDate()).substr(-2)),r.join(t)}(e=e||new Date)+" "+function(e,t=":"){e=e||new Date;const r=[];return r.push(("00"+e.getHours()).substr(-2)),r.push(("00"+e.getMinutes()).substr(-2)),r.push(("00"+e.getSeconds()).substr(-2)),r.join(t)}(e)}function E(){"development"===process.env.NODE_ENV&&console.log(...arguments)}function C(e=6){let t="";for(let r=0;r<e;r++)t+=Math.floor(10*Math.random());return t}function A(e){return Array.from(new Set(e))}function x(e={},t){if(!t||!e)return e;const r=["_pre","_purify","_post"];t._pre&&(e=t._pre(e));let n={shouldDelete:new Set([])};if(t._purify){const e=t._purify;for(const t in e)e[t]=new Set(e[t]);n=Object.assign(n,e)}if(p(t))for(const i in t){const o=t[i];l(o)&&-1===r.indexOf(i)?e[i]=o(e):"string"==typeof o&&-1===r.indexOf(i)&&(e[i]=e[o],n.shouldDelete.add(o))}else l(t)&&(e=t(e));if(n.shouldDelete)for(const t of n.shouldDelete)delete e[t];return t._post&&(e=t._post(e)),e}function I(e,t){const r=new e(t);return new Proxy(r,{get:function(e,t){if("function"==typeof e[t]&&0!==t.indexOf("_")&&e._protocols&&e._protocols[t]){const r=e._protocols[t];return async function(n){n=x(n,r.args);let i=await e[t](n);return i=x(i,r.returnValue),i}}return e[t]}})}function S(e){if(p(e))if(0===e.code)e.errCode=e.code,e.message=e.errMsg=e.msg,delete e.messageValues;else if(d(s,e.code)){const t=s[e.code];e.errCode="uni-id-"+t.errCode,e.errMsg=this.t(t.errCode,e.messageValues||{})||e.msg,e.message=e.msg=e.errMsg,delete e.messageValues}else e.code&&console.warn(`error code not found, error code: ${e.code}, please contact us`)}var k={"zh-Hans":{alipay:"支付宝",wechat:"微信",user:"用户","user-id":"用户ID","dcloud-appid":"应用Appid","dcloud-appid-list":"应用列表",account:"账号",username:"用户名",email:"邮箱",mobile:"手机号",sms:"短信","wechat-openid":"微信openid","wechat-account":"微信账号","alipay-account":"支付宝账号","qq-openid":"QQ openid","qq-account":"QQ账号","apple-account":"苹果账号",password:"密码","verify-code":"验证码","verify-code-type":"验证码类型","user-unique-param":"用户名、邮箱或手机号","role-id":"角色ID","permission-id":"权限ID",login:"登录","verify-mobile":"验证手机","context-param-required":"context内缺少{param}，请使用uniID.createInstance传入客户端信息","config-param-require":"uni-id的配置内缺少{param}","uni-verify-config-required":"请在config.json中配置service.univerify下一键登录相关参数","login-with-invite-type-required":"强制使用邀请码注册时，需指明type为register还是login","type-array-required":"{param}应为数组形式","query-field-warning":"检测到当前使用queryField匹配多字段进行登录操作，需要注意：uni-id并未限制用户名不能是手机号或邮箱，需要开发者自行限制。否则可能出现用户输入abc@xx.com会同时匹配到邮箱为此值的用户和用户名为此值的用户，导致登录失败","add-role-admin-is-not-allowed":"不可新增roleID为admin的角色","password-secret-type-error":"config内passwordSecret类型错误，只可设置string类型和array类型","token-expires-config-warning":"tokenExpiresIn不可小于或等于tokenExpiresThreshold","type-function-required":"{param}应为function类型","dev-warning":"当前正在使用uniID.dev属性，注意此属性仅可用于开发调试","config-file-invalid":"请确保公用模块uni-id对应的配置文件（common/uni-config-center/uni-id/config.json）格式正确（不可包含注释）","config-file-not-found":"请在common/uni-config-center/uni-id/config.json内添加uni-id相关配置信息","hx-version-warning":"当前使用的HBuilderX版本过低，请升级HBuilderX到最新版本","account-banned":"账号已禁用","user-not-exist":"用户不存在","multi-user-matched":"匹配到多个账号","user-info-error":"用户信息不正确","user-account-conflict":"用户账号冲突","user-account-closed":"此账号已注销","password-error":"密码错误","password-error-exceed-limit":"密码错误次数过多，请稍后再试","account-exists":"此账号已注册","account-not-exists":"此账号尚未注册","invalid-invite-code":"邀请码无效","get-third-party-account-failed":"获取{account}失败","get-third-party-user-info-failed":"获取用户信息失败","param-required":"{param}不可为空","check-device-feature-failed":"设备特征校验未通过","token-not-exist":"登录状态无效，云端已不包含此token","token-expired":"token已过期","check-token-failed":"token校验未通过","invalid-old-password":"旧密码错误","param-error":"{param}参数错误，{reason}","invalid-verify-code":"{type}验证码错误或已失效","send-sms-code-failed":"短信验证码发送失败","account-bound":"此账号已被绑定","unbind-failed":"解绑失败","set-invite-code-failed":"邀请码设置失败","modify-invite-code-is-not-allowed":"邀请码不可修改","decrypt-weixin-data-failed":"解密失败","invalid-weixin-appid":"appid不匹配","database-operation-failed":"数据库读写异常","role-not-exist":"角色不存在","permission-not-exist":"权限不存在","context-required":"uni-id无法获取context.{key}，请使用uniID.createInstance方法传入","limit-client-platform":"当前客户端平台不支持此接口"},en:{alipay:"alipay",wechat:"wechat",user:"user","user-id":"user id","dcloud-appid":"DCloud appid","dcloud-appid-list":"DCloud appid list",account:"account",username:"username",email:"email",mobile:"phone number",sms:"sms","wechat-openid":"wechat openid","wechat-account":"wechat account","alipay-account":"alipay account","qq-openid":"QQ openid","qq-account":"QQ account","apple-account":"apple account",password:"password","verify-code":"verify code","verify-code-type":"verify code type","user-unique-param":"username, email or mobile phone number","role-id":"role id","permission-id":"permission id",login:"login","verify-mobile":"verify mobile phone number","context-param-required":"You should pass {param} in context using uniID.createInstance","config-param-require":"{param} is required in uni-id's config","uni-verify-config-required":"Univerify config required: service.univerify","login-with-invite-type-required":"Parameter type is required when forceInviteCode set to true","type-array-required":"Type of {param} must be array","query-field-warning":"You are using multi query field to login, be aware that uni-id will not check username's fromat, eg: abc@xx.com is a valid username for uni-id. You should check username in your code.","add-role-admin-is-not-allowed":'Add role with an id of "admin" is not allowed',"password-secret-type-error":'"passwordSecret" in config must be string or array',"token-expires-config-warning":'"tokenExpiresIn" must be greater than "tokenExpiresThreshold"',"type-function-required":"{param} must be a function","dev-warning":"warning: uniID.dev is only for development","config-file-invalid":"Invalid config file (common/uni-config-center/uni-id/config.json), please note that comment is not allowed","config-file-not-found":"Config file (common/uni-config-center/uni-id/config.json) not found","hx-version-warning":"The HBuilderX you are using is too old, please upgrade to the latest version of HBuilderX","account-banned":"Account is banned","user-not-exist":"User does not exist","multi-user-matched":"Multiple users are matched","user-info-error":"User info error","user-account-conflict":"User account conflict","user-account-closed":"User account has been closed","password-error":"The password is incorrect","password-error-exceed-limit":"The number of password errors exceeded the limit","account-exists":"Account exists","account-not-exists":"Account does not exists","invalid-invite-code":"Invalid invite code","get-third-party-account-failed":"Get {account} failed","get-third-party-user-info-failed":"Get user info failed","param-required":"{param} is required","check-device-feature-failed":"Check device feature failed","token-not-exist":"The login status is invalid, token does not exist","token-expired":"The login status is invalid, token has expired","check-token-failed":"Check token failed","invalid-old-password":"Invalid old password","param-error":"{param} error, {reason}","invalid-verify-code":"Invalid {type} verify code","send-sms-code-failed":"Send sms code failed","account-bound":"Account has been bound","unbind-failed":"Unbind failed","set-invite-code-failed":"Set invite code failed","modify-invite-code-is-not-allowed":"Modifying the invitation code is prohibited","decrypt-weixin-data-failed":"Decrypt weixin data failed","invalid-weixin-appid":"Invalid weixin appid","database-operation-failed":"Database operation failed","role-not-exist":"Role does not exist","permission-not-exist":"Permission does not exist","context-required":'"context.{key}" is required, you should pass context using uniID.createInstance',"limit-client-platform":"Unsupported client platform"}};const O=uniCloud.database(),P=O.collection("uni-id-users"),R=O.collection("opendb-verify-codes"),j=O.collection("uni-id-roles"),D=O.collection("uni-id-permissions"),q={username:"username",mobile:"mobile",email:"email",wx_unionid:"wechat-account","wx_openid.app-plus":"wechat-account","wx_openid.app":"wechat-account","wx_openid.mp-weixin":"wechat-account",qq_unionid:"qq-account","qq_openid.app-plus":"qq-account","qq_openid.app":"qq-account","qq_openid.mp-weixin":"qq-account",ali_openid:"alipay-account",apple_openid:"alipay-account"},N=90002,U=90003,L=90004,V=90005,M=0,B=1,F=4;async function $({uid:e,status:t}={}){return e?(await P.doc(e).update({status:t,status_update_date:Date.now()}),{code:0}):{code:N,messageValues:{param:this.t("user-id")}}}async function H({name:e,url:t,data:r,options:n,defaultOptions:i}){let o={};const s=b(Object.assign({},r));s&&s.access_token&&delete s.access_token;try{n=Object.assign({},i,n,{data:s}),o=await uniCloud.httpclient.request(t,n)}catch(t){return function(e,t){throw new a({code:t.code||-2,message:t.message||e+" fail"})}(e,t)}let c=o.data;const u=o.headers["content-type"];if(!Buffer.isBuffer(c)||0!==u.indexOf("text/plain")&&0!==u.indexOf("application/json"))Buffer.isBuffer(c)&&(c={buffer:c,contentType:u});else try{c=JSON.parse(c.toString())}catch(e){c=c.toString()}return _(function(e,t){if(t.errcode)throw new a({code:t.errcode||-2,message:t.errmsg||e+" fail"});return delete t.errcode,delete t.errmsg,{...t,errMsg:e+" ok",errCode:0}}(e,c||{errCode:-2,errMsg:"Request failed"}))}function K(e,t){let r="";if(t&&t.accessToken){r=`${e.indexOf("?")>-1?"&":"?"}access_token=${t.accessToken}`}return`${e}${r}`}class G{constructor(e){this.options=Object.assign({baseUrl:"https://api.weixin.qq.com",timeout:5e3},e)}async _requestWxOpenapi({name:e,url:t,data:r,options:n}){const i={method:"GET",dataType:"json",dataAsQueryString:!0,timeout:this.options.timeout};return await H({name:"auth."+e,url:`${this.options.baseUrl}${K(t,r)}`,data:r,options:n,defaultOptions:i})}async code2Session(e){return await this._requestWxOpenapi({name:"code2Session",url:"/sns/jscode2session",data:{grant_type:"authorization_code",appid:this.options.appId,secret:this.options.secret,js_code:e}})}async getOauthAccessToken(e){const t=await this._requestWxOpenapi({name:"getOauthAccessToken",url:"/sns/oauth2/access_token",data:{grant_type:"authorization_code",appid:this.options.appId,secret:this.options.secret,code:e}});return t.expiresIn&&(t.expired=Date.now()+1e3*t.expiresIn),t}async getUserInfo({accessToken:e,openid:t}={}){const{nickname:r,headimgurl:n}=await this._requestWxOpenapi({name:"getUserInfo",url:"/sns/userinfo",data:{accessToken:e,openid:t,appid:this.options.appId,secret:this.options.secret,scope:"snsapi_userinfo"}});return{nickname:r,avatar:n}}}async function Q({name:e,url:t,data:r,options:n,defaultOptions:i}){let o;n=Object.assign({},i,n,{data:b(Object.assign({},r))});try{o=await uniCloud.httpclient.request(t,n)}catch(t){return function(e,t){throw new a({code:t.code||-2,message:t.message||e+" fail"})}(e,t)}let s=o.data;const c=o.headers["content-type"];if(!Buffer.isBuffer(s)||0!==c.indexOf("text/plain")&&0!==c.indexOf("application/json"))Buffer.isBuffer(s)&&(s={buffer:s,contentType:c});else try{s=JSON.parse(s.toString())}catch(e){s=s.toString()}return _(function(e,t){if(t.ret||t.error){const r=t.ret||t.error||t.errcode||-2,n=t.msg||t.error_description||t.errmsg||e+" fail";throw new a({code:r,message:n})}return delete t.ret,delete t.msg,delete t.error,delete t.error_description,delete t.errcode,delete t.errmsg,{...t,errMsg:e+" ok",errCode:0}}(e,s||{errCode:-2,errMsg:"Request failed"}))}class X{constructor(e){this.options=Object.assign({baseUrl:"https://graph.qq.com",timeout:5e3},e)}async _requestQQOpenapi({name:e,url:t,data:r,options:n}){const i={method:"GET",dataType:"json",dataAsQueryString:!0,timeout:this.options.timeout};var o,s;return await Q({name:"auth."+e,url:(o=this.options.baseUrl,s=t,/^https?:/.test(s)?s:o+s),data:r,options:n,defaultOptions:i})}async getOpenidByToken({accessToken:e}={}){const t=await this._requestQQOpenapi({name:"getOpenidByToken",url:"/oauth2.0/me",data:{accessToken:e,unionid:1,fmt:"json"}});if(t.clientId!==this.options.appId)throw new a({code:"APPID_NOT_MATCH",message:"appid not match"});return{openid:t.openid,unionid:t.unionid}}async code2Session({code:e}={}){return await this._requestQQOpenapi({name:"getOpenidByToken",url:"https://api.q.qq.com/sns/jscode2session",data:{grant_type:"authorization_code",appid:this.options.appId,secret:this.options.secret,js_code:e}})}}const Y={RSA:"RSA-SHA1",RSA2:"RSA-SHA256"};var z={code2Session:{returnValue:{openid:"userId"}}};class W extends class{constructor(e={}){if(!e.appId)throw new Error("appId required");if(!e.privateKey)throw new Error("privateKey required");const t={gateway:"https://openapi.alipay.com/gateway.do",timeout:5e3,charset:"utf-8",version:"1.0",signType:"RSA2",timeOffset:-(new Date).getTimezoneOffset()/60,keyType:"PKCS8"};e.sandbox&&(e.gateway="https://openapi.alipaydev.com/gateway.do"),this.options=Object.assign({},t,e);const r="PKCS8"===this.options.keyType?"PRIVATE KEY":"RSA PRIVATE KEY";this.options.privateKey=this._formatKey(this.options.privateKey,r),this.options.alipayPublicKey&&(this.options.alipayPublicKey=this._formatKey(this.options.alipayPublicKey,"PUBLIC KEY"))}_formatKey(e,t){return`-----BEGIN ${t}-----\n${e}\n-----END ${t}-----`}_formatUrl(e,t){let r=e;const n=["app_id","method","format","charset","sign_type","sign","timestamp","version","notify_url","return_url","auth_token","app_auth_token"];for(const e in t)if(n.indexOf(e)>-1){const n=encodeURIComponent(t[e]);r=`${r}${r.includes("?")?"&":"?"}${e}=${n}`,delete t[e]}return{execParams:t,url:r}}_getSign(e,r){const n=r.bizContent||null;delete r.bizContent;const i=Object.assign({method:e,appId:this.options.appId,charset:this.options.charset,version:this.options.version,signType:this.options.signType,timestamp:T((o=this.options.timeOffset,new Date(Date.now()+6e4*((new Date).getTimezoneOffset()+60*(o||0)))))},r);var o;n&&(i.bizContent=JSON.stringify(b(n)));const s=b(i),a=Object.keys(s).sort().map(e=>{let t=s[e];return"[object String]"!==Array.prototype.toString.call(t)&&(t=JSON.stringify(t)),`${e}=${t}`}).join("&"),c=t.createSign(Y[this.options.signType]).update(a,"utf8").sign(this.options.privateKey,"base64");return Object.assign(s,{sign:c})}async _exec(e,t={},r={}){const n=this._getSign(e,t),{url:i,execParams:o}=this._formatUrl(this.options.gateway,n),{status:s,data:a}=await uniCloud.httpclient.request(i,{method:"POST",data:o,dataType:"text",timeout:this.options.timeout});if(200!==s)throw new Error("request fail");const c=JSON.parse(a),u=e.replace(/\./g,"_")+"_response",d=c[u],p=c.error_response;if(d){if(!r.validateSign||this._checkResponseSign(a,u)){if(!d.code||"10000"===d.code){return{errCode:0,errMsg:d.msg||"",..._(d)}}const e=d.sub_code?`${d.sub_code} ${d.sub_msg}`:""+(d.msg||"unkonwn error");throw new Error(e)}throw new Error("check sign error")}if(p)throw new Error(p.sub_msg||p.msg||"request fail");throw new Error("request fail")}_checkResponseSign(e,r){if(!this.options.alipayPublicKey||""===this.options.alipayPublicKey)return console.warn("options.alipayPublicKey is empty"),!0;if(!e)return!1;const n=this._getSignStr(e,r),i=JSON.parse(e).sign,o=t.createVerify(Y[this.options.signType]);return o.update(n,"utf8"),o.verify(this.options.alipayPublicKey,i,"base64")}_getSignStr(e,t){let r=e.trim();const n=e.indexOf(t+'"'),i=e.lastIndexOf('"sign"');return r=r.substr(n+t.length+1),r=r.substr(0,i),r=r.replace(/^[^{]*{/g,"{"),r=r.replace(/\}([^}]*)$/g,"}"),r}}{constructor(e){super(e),this._protocols=z}async code2Session(e){return await this._exec("alipay.system.oauth.token",{grantType:"authorization_code",code:e})}}function J(e){var t=e[0];return t<"0"||t>"7"?"00"+e:e}function Z(e){var t=e.toString(16);return t.length%2?"0"+t:t}function ee(e){if(e<=127)return Z(e);var t=Z(e);return Z(128+t.length/2)+t}function te(e,t){return e(t={exports:{}},t.exports),t.exports}var re=te((function(e,t){var n=r.Buffer;function i(e,t){for(var r in e)t[r]=e[r]}function o(e,t,r){return n(e,t,r)}n.from&&n.alloc&&n.allocUnsafe&&n.allocUnsafeSlow?e.exports=r:(i(r,t),t.Buffer=o),o.prototype=Object.create(n.prototype),i(n,o),o.from=function(e,t,r){if("number"==typeof e)throw new TypeError("Argument must not be a number");return n(e,t,r)},o.alloc=function(e,t,r){if("number"!=typeof e)throw new TypeError("Argument must be a number");var i=n(e);return void 0!==t?"string"==typeof r?i.fill(t,r):i.fill(t):i.fill(0),i},o.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return n(e)},o.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return r.SlowBuffer(e)}})),ne=(re.Buffer,re.Buffer);function ie(e){if(this.buffer=null,this.writable=!0,this.readable=!0,!e)return this.buffer=ne.alloc(0),this;if("function"==typeof e.pipe)return this.buffer=ne.alloc(0),e.pipe(this),this;if(e.length||"object"==typeof e)return this.buffer=e,this.writable=!1,process.nextTick(function(){this.emit("end",e),this.readable=!1,this.emit("close")}.bind(this)),this;throw new TypeError("Unexpected data type ("+typeof e+")")}i.inherits(ie,n),ie.prototype.write=function(e){this.buffer=ne.concat([this.buffer,ne.from(e)]),this.emit("data",e)},ie.prototype.end=function(e){e&&this.write(e),this.emit("end",e),this.emit("close"),this.writable=!1,this.readable=!1};var oe=ie,se=r.Buffer,ae=r.SlowBuffer,ce=ue;function ue(e,t){if(!se.isBuffer(e)||!se.isBuffer(t))return!1;if(e.length!==t.length)return!1;for(var r=0,n=0;n<e.length;n++)r|=e[n]^t[n];return 0===r}ue.install=function(){se.prototype.equal=ae.prototype.equal=function(e){return ue(this,e)}};var de=se.prototype.equal,pe=ae.prototype.equal;function le(e){return(e/8|0)+(e%8==0?0:1)}ue.restore=function(){se.prototype.equal=de,ae.prototype.equal=pe};var fe={ES256:le(256),ES384:le(384),ES512:le(521)};var me=function(e){var t=fe[e];if(t)return t;throw new Error('Unknown algorithm "'+e+'"')},he=re.Buffer;function ge(e){if(he.isBuffer(e))return e;if("string"==typeof e)return he.from(e,"base64");throw new TypeError("ECDSA signature must be a Base64 string or a Buffer")}function ye(e,t,r){for(var n=0;t+n<r&&0===e[t+n];)++n;return e[t+n]>=128&&--n,n}var we={derToJose:function(e,t){e=ge(e);var r=me(t),n=r+1,i=e.length,o=0;if(48!==e[o++])throw new Error('Could not find expected "seq"');var s=e[o++];if(129===s&&(s=e[o++]),i-o<s)throw new Error('"seq" specified length of "'+s+'", only "'+(i-o)+'" remaining');if(2!==e[o++])throw new Error('Could not find expected "int" for "r"');var a=e[o++];if(i-o-2<a)throw new Error('"r" specified length of "'+a+'", only "'+(i-o-2)+'" available');if(n<a)throw new Error('"r" specified length of "'+a+'", max of "'+n+'" is acceptable');var c=o;if(o+=a,2!==e[o++])throw new Error('Could not find expected "int" for "s"');var u=e[o++];if(i-o!==u)throw new Error('"s" specified length of "'+u+'", expected "'+(i-o)+'"');if(n<u)throw new Error('"s" specified length of "'+u+'", max of "'+n+'" is acceptable');var d=o;if((o+=u)!==i)throw new Error('Expected to consume entire buffer, but "'+(i-o)+'" bytes remain');var p=r-a,l=r-u,f=he.allocUnsafe(p+a+l+u);for(o=0;o<p;++o)f[o]=0;e.copy(f,o,c+Math.max(-p,0),c+a);for(var m=o=r;o<m+l;++o)f[o]=0;return e.copy(f,o,d+Math.max(-l,0),d+u),f=(f=f.toString("base64")).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")},joseToDer:function(e,t){e=ge(e);var r=me(t),n=e.length;if(n!==2*r)throw new TypeError('"'+t+'" signatures must be "'+2*r+'" bytes, saw "'+n+'"');var i=ye(e,0,r),o=ye(e,r,e.length),s=r-i,a=r-o,c=2+s+1+1+a,u=c<128,d=he.allocUnsafe((u?2:3)+c),p=0;return d[p++]=48,u?d[p++]=c:(d[p++]=129,d[p++]=255&c),d[p++]=2,d[p++]=s,i<0?(d[p++]=0,p+=e.copy(d,p,0,r)):p+=e.copy(d,p,i,r),d[p++]=2,d[p++]=a,o<0?(d[p++]=0,e.copy(d,p,r)):e.copy(d,p,r+o),d}},ve=re.Buffer,_e="secret must be a string or buffer",be="key must be a string or a buffer",Te="function"==typeof t.createPublicKey;function Ee(e){if(!ve.isBuffer(e)&&"string"!=typeof e){if(!Te)throw Ie(be);if("object"!=typeof e)throw Ie(be);if("string"!=typeof e.type)throw Ie(be);if("string"!=typeof e.asymmetricKeyType)throw Ie(be);if("function"!=typeof e.export)throw Ie(be)}}function Ce(e){if(!ve.isBuffer(e)&&"string"!=typeof e&&"object"!=typeof e)throw Ie("key must be a string, a buffer or an object")}function Ae(e){return e.replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function xe(e){var t=4-(e=e.toString()).length%4;if(4!==t)for(var r=0;r<t;++r)e+="=";return e.replace(/\-/g,"+").replace(/_/g,"/")}function Ie(e){var t=[].slice.call(arguments,1),r=i.format.bind(i,e).apply(null,t);return new TypeError(r)}function Se(e){var t;return t=e,ve.isBuffer(t)||"string"==typeof t||(e=JSON.stringify(e)),e}function ke(e){return function(r,n){!function(e){if(!ve.isBuffer(e)){if("string"==typeof e)return e;if(!Te)throw Ie(_e);if("object"!=typeof e)throw Ie(_e);if("secret"!==e.type)throw Ie(_e);if("function"!=typeof e.export)throw Ie(_e)}}(n),r=Se(r);var i=t.createHmac("sha"+e,n);return Ae((i.update(r),i.digest("base64")))}}function Oe(e){return function(t,r,n){var i=ke(e)(t,n);return ce(ve.from(r),ve.from(i))}}function Pe(e){return function(r,n){Ce(n),r=Se(r);var i=t.createSign("RSA-SHA"+e);return Ae((i.update(r),i.sign(n,"base64")))}}function Re(e){return function(r,n,i){Ee(i),r=Se(r),n=xe(n);var o=t.createVerify("RSA-SHA"+e);return o.update(r),o.verify(i,n,"base64")}}function je(e){return function(r,n){Ce(n),r=Se(r);var i=t.createSign("RSA-SHA"+e);return Ae((i.update(r),i.sign({key:n,padding:t.constants.RSA_PKCS1_PSS_PADDING,saltLength:t.constants.RSA_PSS_SALTLEN_DIGEST},"base64")))}}function De(e){return function(r,n,i){Ee(i),r=Se(r),n=xe(n);var o=t.createVerify("RSA-SHA"+e);return o.update(r),o.verify({key:i,padding:t.constants.RSA_PKCS1_PSS_PADDING,saltLength:t.constants.RSA_PSS_SALTLEN_DIGEST},n,"base64")}}function qe(e){var t=Pe(e);return function(){var r=t.apply(null,arguments);return r=we.derToJose(r,"ES"+e)}}function Ne(e){var t=Re(e);return function(r,n,i){return n=we.joseToDer(n,"ES"+e).toString("base64"),t(r,n,i)}}function Ue(){return function(){return""}}function Le(){return function(e,t){return""===t}}Te&&(be+=" or a KeyObject",_e+="or a KeyObject");var Ve=function(e){var t={hs:ke,rs:Pe,ps:je,es:qe,none:Ue},r={hs:Oe,rs:Re,ps:De,es:Ne,none:Le},n=e.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/i);if(!n)throw Ie('"%s" is not a valid algorithm.\n  Supported algorithms are:\n  "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" and "none".',e);var i=(n[1]||n[3]).toLowerCase(),o=n[2];return{sign:t[i](o),verify:r[i](o)}},Me=r.Buffer,Be=function(e){return"string"==typeof e?e:"number"==typeof e||Me.isBuffer(e)?e.toString():JSON.stringify(e)},Fe=re.Buffer;function $e(e,t){return Fe.from(e,t).toString("base64").replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function He(e){var t=e.header,r=e.payload,n=e.secret||e.privateKey,o=e.encoding,s=Ve(t.alg),a=function(e,t,r){r=r||"utf8";var n=$e(Be(e),"binary"),o=$e(Be(t),r);return i.format("%s.%s",n,o)}(t,r,o),c=s.sign(a,n);return i.format("%s.%s",a,c)}function Ke(e){var t=e.secret||e.privateKey||e.key,r=new oe(t);this.readable=!0,this.header=e.header,this.encoding=e.encoding,this.secret=this.privateKey=this.key=r,this.payload=new oe(e.payload),this.secret.once("close",function(){!this.payload.writable&&this.readable&&this.sign()}.bind(this)),this.payload.once("close",function(){!this.secret.writable&&this.readable&&this.sign()}.bind(this))}i.inherits(Ke,n),Ke.prototype.sign=function(){try{var e=He({header:this.header,payload:this.payload.buffer,secret:this.secret.buffer,encoding:this.encoding});return this.emit("done",e),this.emit("data",e),this.emit("end"),this.readable=!1,e}catch(e){this.readable=!1,this.emit("error",e),this.emit("close")}},Ke.sign=He;var Ge=Ke,Qe=re.Buffer,Xe=/^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.([a-zA-Z0-9\-_]+)?$/;function Ye(e){if(function(e){return"[object Object]"===Object.prototype.toString.call(e)}(e))return e;try{return JSON.parse(e)}catch(e){return}}function ze(e){var t=e.split(".",1)[0];return Ye(Qe.from(t,"base64").toString("binary"))}function We(e){return e.split(".")[2]}function Je(e){return Xe.test(e)&&!!ze(e)}function Ze(e,t,r){if(!t){var n=new Error("Missing algorithm parameter for jws.verify");throw n.code="MISSING_ALGORITHM",n}var i=We(e=Be(e)),o=function(e){return e.split(".",2).join(".")}(e);return Ve(t).verify(o,i,r)}function et(e,t){if(t=t||{},!Je(e=Be(e)))return null;var r=ze(e);if(!r)return null;var n=function(e,t){t=t||"utf8";var r=e.split(".")[1];return Qe.from(r,"base64").toString(t)}(e);return("JWT"===r.typ||t.json)&&(n=JSON.parse(n,t.encoding)),{header:r,payload:n,signature:We(e)}}function tt(e){var t=(e=e||{}).secret||e.publicKey||e.key,r=new oe(t);this.readable=!0,this.algorithm=e.algorithm,this.encoding=e.encoding,this.secret=this.publicKey=this.key=r,this.signature=new oe(e.signature),this.secret.once("close",function(){!this.signature.writable&&this.readable&&this.verify()}.bind(this)),this.signature.once("close",function(){!this.secret.writable&&this.readable&&this.verify()}.bind(this))}i.inherits(tt,n),tt.prototype.verify=function(){try{var e=Ze(this.signature.buffer,this.algorithm,this.key.buffer),t=et(this.signature.buffer,this.encoding);return this.emit("done",e,t),this.emit("data",e),this.emit("end"),this.readable=!1,e}catch(e){this.readable=!1,this.emit("error",e),this.emit("close")}},tt.decode=et,tt.isValid=Je,tt.verify=Ze;var rt=tt,nt={ALGORITHMS:["HS256","HS384","HS512","RS256","RS384","RS512","PS256","PS384","PS512","ES256","ES384","ES512"],sign:Ge.sign,verify:rt.verify,decode:rt.decode,isValid:rt.isValid,createSign:function(e){return new Ge(e)},createVerify:function(e){return new rt(e)}},it=function(e,t){t=t||{};var r=nt.decode(e,t);if(!r)return null;var n=r.payload;if("string"==typeof n)try{var i=JSON.parse(n);null!==i&&"object"==typeof i&&(n=i)}catch(e){}return!0===t.complete?{header:r.header,payload:n,signature:r.signature}:n},ot=function(e,t){Error.call(this,e),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name="JsonWebTokenError",this.message=e,t&&(this.inner=t)};(ot.prototype=Object.create(Error.prototype)).constructor=ot;var st=ot,at=function(e,t){st.call(this,e),this.name="NotBeforeError",this.date=t};(at.prototype=Object.create(st.prototype)).constructor=at;var ct=at,ut=function(e,t){st.call(this,e),this.name="TokenExpiredError",this.expiredAt=t};(ut.prototype=Object.create(st.prototype)).constructor=ut;var dt=ut,pt=1e3,lt=60*pt,ft=60*lt,mt=24*ft,ht=function(e,t){t=t||{};var r=typeof e;if("string"===r&&e.length>0)return function(e){if((e=String(e)).length>100)return;var t=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);if(!t)return;var r=parseFloat(t[1]);switch((t[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return 315576e5*r;case"weeks":case"week":case"w":return 6048e5*r;case"days":case"day":case"d":return r*mt;case"hours":case"hour":case"hrs":case"hr":case"h":return r*ft;case"minutes":case"minute":case"mins":case"min":case"m":return r*lt;case"seconds":case"second":case"secs":case"sec":case"s":return r*pt;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}(e);if("number"===r&&isFinite(e))return t.long?function(e){var t=Math.abs(e);if(t>=mt)return gt(e,t,mt,"day");if(t>=ft)return gt(e,t,ft,"hour");if(t>=lt)return gt(e,t,lt,"minute");if(t>=pt)return gt(e,t,pt,"second");return e+" ms"}(e):function(e){var t=Math.abs(e);if(t>=mt)return Math.round(e/mt)+"d";if(t>=ft)return Math.round(e/ft)+"h";if(t>=lt)return Math.round(e/lt)+"m";if(t>=pt)return Math.round(e/pt)+"s";return e+"ms"}(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))};function gt(e,t,r,n){var i=t>=1.5*r;return Math.round(e/r)+" "+n+(i?"s":"")}var yt=function(e,t){var r=t||Math.floor(Date.now()/1e3);if("string"==typeof e){var n=ht(e);if(void 0===n)return;return Math.floor(r+n/1e3)}return"number"==typeof e?r+e:void 0},wt=te((function(e,t){var r;t=e.exports=Y,r="object"==typeof process&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?function(){var e=Array.prototype.slice.call(arguments,0);e.unshift("SEMVER"),console.log.apply(console,e)}:function(){},t.SEMVER_SPEC_VERSION="2.0.0";var n=Number.MAX_SAFE_INTEGER||9007199254740991,i=t.re=[],o=t.safeRe=[],s=t.src=[],a=0,c=[["\\s",1],["\\d",256],["[a-zA-Z0-9-]",250]];function u(e){for(var t=0;t<c.length;t++){var r=c[t][0],n=c[t][1];e=e.split(r+"*").join(r+"{0,"+n+"}").split(r+"+").join(r+"{1,"+n+"}")}return e}var d=a++;s[d]="0|[1-9]\\d*";var p=a++;s[p]="\\d+";var l=a++;s[l]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var f=a++;s[f]="("+s[d]+")\\.("+s[d]+")\\.("+s[d]+")";var m=a++;s[m]="("+s[p]+")\\.("+s[p]+")\\.("+s[p]+")";var h=a++;s[h]="(?:"+s[d]+"|"+s[l]+")";var g=a++;s[g]="(?:"+s[p]+"|"+s[l]+")";var y=a++;s[y]="(?:-("+s[h]+"(?:\\."+s[h]+")*))";var w=a++;s[w]="(?:-?("+s[g]+"(?:\\."+s[g]+")*))";var v=a++;s[v]="[a-zA-Z0-9-]+";var _=a++;s[_]="(?:\\+("+s[v]+"(?:\\."+s[v]+")*))";var b=a++,T="v?"+s[f]+s[y]+"?"+s[_]+"?";s[b]="^"+T+"$";var E="[v=\\s]*"+s[m]+s[w]+"?"+s[_]+"?",C=a++;s[C]="^"+E+"$";var A=a++;s[A]="((?:<|>)?=?)";var x=a++;s[x]=s[p]+"|x|X|\\*";var I=a++;s[I]=s[d]+"|x|X|\\*";var S=a++;s[S]="[v=\\s]*("+s[I]+")(?:\\.("+s[I]+")(?:\\.("+s[I]+")(?:"+s[y]+")?"+s[_]+"?)?)?";var k=a++;s[k]="[v=\\s]*("+s[x]+")(?:\\.("+s[x]+")(?:\\.("+s[x]+")(?:"+s[w]+")?"+s[_]+"?)?)?";var O=a++;s[O]="^"+s[A]+"\\s*"+s[S]+"$";var P=a++;s[P]="^"+s[A]+"\\s*"+s[k]+"$";var R=a++;s[R]="(?:^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])";var j=a++;s[j]="(?:~>?)";var D=a++;s[D]="(\\s*)"+s[j]+"\\s+",i[D]=new RegExp(s[D],"g"),o[D]=new RegExp(u(s[D]),"g");var q=a++;s[q]="^"+s[j]+s[S]+"$";var N=a++;s[N]="^"+s[j]+s[k]+"$";var U=a++;s[U]="(?:\\^)";var L=a++;s[L]="(\\s*)"+s[U]+"\\s+",i[L]=new RegExp(s[L],"g"),o[L]=new RegExp(u(s[L]),"g");var V=a++;s[V]="^"+s[U]+s[S]+"$";var M=a++;s[M]="^"+s[U]+s[k]+"$";var B=a++;s[B]="^"+s[A]+"\\s*("+E+")$|^$";var F=a++;s[F]="^"+s[A]+"\\s*("+T+")$|^$";var $=a++;s[$]="(\\s*)"+s[A]+"\\s*("+E+"|"+s[S]+")",i[$]=new RegExp(s[$],"g"),o[$]=new RegExp(u(s[$]),"g");var H=a++;s[H]="^\\s*("+s[S]+")\\s+-\\s+("+s[S]+")\\s*$";var K=a++;s[K]="^\\s*("+s[k]+")\\s+-\\s+("+s[k]+")\\s*$";var G=a++;s[G]="(<|>)?=?\\s*\\*";for(var Q=0;Q<35;Q++)r(Q,s[Q]),i[Q]||(i[Q]=new RegExp(s[Q]),o[Q]=new RegExp(u(s[Q])));function X(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof Y)return e;if("string"!=typeof e)return null;if(e.length>256)return null;if(!(t.loose?o[C]:o[b]).test(e))return null;try{return new Y(e,t)}catch(e){return null}}function Y(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof Y){if(e.loose===t.loose)return e;e=e.version}else if("string"!=typeof e)throw new TypeError("Invalid Version: "+e);if(e.length>256)throw new TypeError("version is longer than 256 characters");if(!(this instanceof Y))return new Y(e,t);r("SemVer",e,t),this.options=t,this.loose=!!t.loose;var i=e.trim().match(t.loose?o[C]:o[b]);if(!i)throw new TypeError("Invalid Version: "+e);if(this.raw=e,this.major=+i[1],this.minor=+i[2],this.patch=+i[3],this.major>n||this.major<0)throw new TypeError("Invalid major version");if(this.minor>n||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>n||this.patch<0)throw new TypeError("Invalid patch version");i[4]?this.prerelease=i[4].split(".").map((function(e){if(/^[0-9]+$/.test(e)){var t=+e;if(t>=0&&t<n)return t}return e})):this.prerelease=[],this.build=i[5]?i[5].split("."):[],this.format()}t.parse=X,t.valid=function(e,t){var r=X(e,t);return r?r.version:null},t.clean=function(e,t){var r=X(e.trim().replace(/^[=v]+/,""),t);return r?r.version:null},t.SemVer=Y,Y.prototype.format=function(){return this.version=this.major+"."+this.minor+"."+this.patch,this.prerelease.length&&(this.version+="-"+this.prerelease.join(".")),this.version},Y.prototype.toString=function(){return this.version},Y.prototype.compare=function(e){return r("SemVer.compare",this.version,this.options,e),e instanceof Y||(e=new Y(e,this.options)),this.compareMain(e)||this.comparePre(e)},Y.prototype.compareMain=function(e){return e instanceof Y||(e=new Y(e,this.options)),W(this.major,e.major)||W(this.minor,e.minor)||W(this.patch,e.patch)},Y.prototype.comparePre=function(e){if(e instanceof Y||(e=new Y(e,this.options)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;var t=0;do{var n=this.prerelease[t],i=e.prerelease[t];if(r("prerelease compare",t,n,i),void 0===n&&void 0===i)return 0;if(void 0===i)return 1;if(void 0===n)return-1;if(n!==i)return W(n,i)}while(++t)},Y.prototype.inc=function(e,t){switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",t);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",t);break;case"prepatch":this.prerelease.length=0,this.inc("patch",t),this.inc("pre",t);break;case"prerelease":0===this.prerelease.length&&this.inc("patch",t),this.inc("pre",t);break;case"major":0===this.minor&&0===this.patch&&0!==this.prerelease.length||this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":0===this.patch&&0!==this.prerelease.length||this.minor++,this.patch=0,this.prerelease=[];break;case"patch":0===this.prerelease.length&&this.patch++,this.prerelease=[];break;case"pre":if(0===this.prerelease.length)this.prerelease=[0];else{for(var r=this.prerelease.length;--r>=0;)"number"==typeof this.prerelease[r]&&(this.prerelease[r]++,r=-2);-1===r&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error("invalid increment argument: "+e)}return this.format(),this.raw=this.version,this},t.inc=function(e,t,r,n){"string"==typeof r&&(n=r,r=void 0);try{return new Y(e,r).inc(t,n).version}catch(e){return null}},t.diff=function(e,t){if(te(e,t))return null;var r=X(e),n=X(t),i="";if(r.prerelease.length||n.prerelease.length){i="pre";var o="prerelease"}for(var s in r)if(("major"===s||"minor"===s||"patch"===s)&&r[s]!==n[s])return i+s;return o},t.compareIdentifiers=W;var z=/^[0-9]+$/;function W(e,t){var r=z.test(e),n=z.test(t);return r&&n&&(e=+e,t=+t),e===t?0:r&&!n?-1:n&&!r?1:e<t?-1:1}function J(e,t,r){return new Y(e,r).compare(new Y(t,r))}function Z(e,t,r){return J(e,t,r)>0}function ee(e,t,r){return J(e,t,r)<0}function te(e,t,r){return 0===J(e,t,r)}function re(e,t,r){return 0!==J(e,t,r)}function ne(e,t,r){return J(e,t,r)>=0}function ie(e,t,r){return J(e,t,r)<=0}function oe(e,t,r,n){switch(t){case"===":return"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),e===r;case"!==":return"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),e!==r;case"":case"=":case"==":return te(e,r,n);case"!=":return re(e,r,n);case">":return Z(e,r,n);case">=":return ne(e,r,n);case"<":return ee(e,r,n);case"<=":return ie(e,r,n);default:throw new TypeError("Invalid operator: "+t)}}function se(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof se){if(e.loose===!!t.loose)return e;e=e.value}if(!(this instanceof se))return new se(e,t);e=e.trim().split(/\s+/).join(" "),r("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===ae?this.value="":this.value=this.operator+this.semver.version,r("comp",this)}t.rcompareIdentifiers=function(e,t){return W(t,e)},t.major=function(e,t){return new Y(e,t).major},t.minor=function(e,t){return new Y(e,t).minor},t.patch=function(e,t){return new Y(e,t).patch},t.compare=J,t.compareLoose=function(e,t){return J(e,t,!0)},t.rcompare=function(e,t,r){return J(t,e,r)},t.sort=function(e,r){return e.sort((function(e,n){return t.compare(e,n,r)}))},t.rsort=function(e,r){return e.sort((function(e,n){return t.rcompare(e,n,r)}))},t.gt=Z,t.lt=ee,t.eq=te,t.neq=re,t.gte=ne,t.lte=ie,t.cmp=oe,t.Comparator=se;var ae={};function ce(e,t){if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),e instanceof ce)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new ce(e.raw,t);if(e instanceof se)return new ce(e.value,t);if(!(this instanceof ce))return new ce(e,t);if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e.trim().split(/\s+/).join(" "),this.set=this.raw.split("||").map((function(e){return this.parseRange(e.trim())}),this).filter((function(e){return e.length})),!this.set.length)throw new TypeError("Invalid SemVer Range: "+this.raw);this.format()}function ue(e){return!e||"x"===e.toLowerCase()||"*"===e}function de(e,t,r,n,i,o,s,a,c,u,d,p,l){return((t=ue(r)?"":ue(n)?">="+r+".0.0":ue(i)?">="+r+"."+n+".0":">="+t)+" "+(a=ue(c)?"":ue(u)?"<"+(+c+1)+".0.0":ue(d)?"<"+c+"."+(+u+1)+".0":p?"<="+c+"."+u+"."+d+"-"+p:"<="+a)).trim()}function pe(e,t,n){for(var i=0;i<e.length;i++)if(!e[i].test(t))return!1;if(t.prerelease.length&&!n.includePrerelease){for(i=0;i<e.length;i++)if(r(e[i].semver),e[i].semver!==ae&&e[i].semver.prerelease.length>0){var o=e[i].semver;if(o.major===t.major&&o.minor===t.minor&&o.patch===t.patch)return!0}return!1}return!0}function le(e,t,r){try{t=new ce(t,r)}catch(e){return!1}return t.test(e)}function fe(e,t,r,n){var i,o,s,a,c;switch(e=new Y(e,n),t=new ce(t,n),r){case">":i=Z,o=ie,s=ee,a=">",c=">=";break;case"<":i=ee,o=ne,s=Z,a="<",c="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(le(e,t,n))return!1;for(var u=0;u<t.set.length;++u){var d=t.set[u],p=null,l=null;if(d.forEach((function(e){e.semver===ae&&(e=new se(">=0.0.0")),p=p||e,l=l||e,i(e.semver,p.semver,n)?p=e:s(e.semver,l.semver,n)&&(l=e)})),p.operator===a||p.operator===c)return!1;if((!l.operator||l.operator===a)&&o(e,l.semver))return!1;if(l.operator===c&&s(e,l.semver))return!1}return!0}se.prototype.parse=function(e){var t=this.options.loose?o[B]:o[F],r=e.match(t);if(!r)throw new TypeError("Invalid comparator: "+e);this.operator=r[1],"="===this.operator&&(this.operator=""),r[2]?this.semver=new Y(r[2],this.options.loose):this.semver=ae},se.prototype.toString=function(){return this.value},se.prototype.test=function(e){return r("Comparator.test",e,this.options.loose),this.semver===ae||("string"==typeof e&&(e=new Y(e,this.options)),oe(e,this.operator,this.semver,this.options))},se.prototype.intersects=function(e,t){if(!(e instanceof se))throw new TypeError("a Comparator is required");var r;if(t&&"object"==typeof t||(t={loose:!!t,includePrerelease:!1}),""===this.operator)return r=new ce(e.value,t),le(this.value,r,t);if(""===e.operator)return r=new ce(this.value,t),le(e.semver,r,t);var n=!(">="!==this.operator&&">"!==this.operator||">="!==e.operator&&">"!==e.operator),i=!("<="!==this.operator&&"<"!==this.operator||"<="!==e.operator&&"<"!==e.operator),o=this.semver.version===e.semver.version,s=!(">="!==this.operator&&"<="!==this.operator||">="!==e.operator&&"<="!==e.operator),a=oe(this.semver,"<",e.semver,t)&&(">="===this.operator||">"===this.operator)&&("<="===e.operator||"<"===e.operator),c=oe(this.semver,">",e.semver,t)&&("<="===this.operator||"<"===this.operator)&&(">="===e.operator||">"===e.operator);return n||i||o&&s||a||c},t.Range=ce,ce.prototype.format=function(){return this.range=this.set.map((function(e){return e.join(" ").trim()})).join("||").trim(),this.range},ce.prototype.toString=function(){return this.range},ce.prototype.parseRange=function(e){var t=this.options.loose,n=t?o[K]:o[H];e=e.replace(n,de),r("hyphen replace",e),e=e.replace(o[$],"$1$2$3"),r("comparator trim",e,o[$]),e=(e=e.replace(o[D],"$1~")).replace(o[L],"$1^");var i=t?o[B]:o[F],s=e.split(" ").map((function(e){return function(e,t){return r("comp",e,t),e=function(e,t){return e.trim().split(/\s+/).map((function(e){return function(e,t){r("caret",e,t);var n=t.loose?o[M]:o[V];return e.replace(n,(function(t,n,i,o,s){var a;return r("caret",e,t,n,i,o,s),ue(n)?a="":ue(i)?a=">="+n+".0.0 <"+(+n+1)+".0.0":ue(o)?a="0"===n?">="+n+"."+i+".0 <"+n+"."+(+i+1)+".0":">="+n+"."+i+".0 <"+(+n+1)+".0.0":s?(r("replaceCaret pr",s),a="0"===n?"0"===i?">="+n+"."+i+"."+o+"-"+s+" <"+n+"."+i+"."+(+o+1):">="+n+"."+i+"."+o+"-"+s+" <"+n+"."+(+i+1)+".0":">="+n+"."+i+"."+o+"-"+s+" <"+(+n+1)+".0.0"):(r("no pr"),a="0"===n?"0"===i?">="+n+"."+i+"."+o+" <"+n+"."+i+"."+(+o+1):">="+n+"."+i+"."+o+" <"+n+"."+(+i+1)+".0":">="+n+"."+i+"."+o+" <"+(+n+1)+".0.0"),r("caret return",a),a}))}(e,t)})).join(" ")}(e,t),r("caret",e),e=function(e,t){return e.trim().split(/\s+/).map((function(e){return function(e,t){var n=t.loose?o[N]:o[q];return e.replace(n,(function(t,n,i,o,s){var a;return r("tilde",e,t,n,i,o,s),ue(n)?a="":ue(i)?a=">="+n+".0.0 <"+(+n+1)+".0.0":ue(o)?a=">="+n+"."+i+".0 <"+n+"."+(+i+1)+".0":s?(r("replaceTilde pr",s),a=">="+n+"."+i+"."+o+"-"+s+" <"+n+"."+(+i+1)+".0"):a=">="+n+"."+i+"."+o+" <"+n+"."+(+i+1)+".0",r("tilde return",a),a}))}(e,t)})).join(" ")}(e,t),r("tildes",e),e=function(e,t){return r("replaceXRanges",e,t),e.split(/\s+/).map((function(e){return function(e,t){e=e.trim();var n=t.loose?o[P]:o[O];return e.replace(n,(function(t,n,i,o,s,a){r("xRange",e,t,n,i,o,s,a);var c=ue(i),u=c||ue(o),d=u||ue(s);return"="===n&&d&&(n=""),c?t=">"===n||"<"===n?"<0.0.0":"*":n&&d?(u&&(o=0),s=0,">"===n?(n=">=",u?(i=+i+1,o=0,s=0):(o=+o+1,s=0)):"<="===n&&(n="<",u?i=+i+1:o=+o+1),t=n+i+"."+o+"."+s):u?t=">="+i+".0.0 <"+(+i+1)+".0.0":d&&(t=">="+i+"."+o+".0 <"+i+"."+(+o+1)+".0"),r("xRange return",t),t}))}(e,t)})).join(" ")}(e,t),r("xrange",e),e=function(e,t){return r("replaceStars",e,t),e.trim().replace(o[G],"")}(e,t),r("stars",e),e}(e,this.options)}),this).join(" ").split(/\s+/);return this.options.loose&&(s=s.filter((function(e){return!!e.match(i)}))),s=s.map((function(e){return new se(e,this.options)}),this)},ce.prototype.intersects=function(e,t){if(!(e instanceof ce))throw new TypeError("a Range is required");return this.set.some((function(r){return r.every((function(r){return e.set.some((function(e){return e.every((function(e){return r.intersects(e,t)}))}))}))}))},t.toComparators=function(e,t){return new ce(e,t).set.map((function(e){return e.map((function(e){return e.value})).join(" ").trim().split(" ")}))},ce.prototype.test=function(e){if(!e)return!1;"string"==typeof e&&(e=new Y(e,this.options));for(var t=0;t<this.set.length;t++)if(pe(this.set[t],e,this.options))return!0;return!1},t.satisfies=le,t.maxSatisfying=function(e,t,r){var n=null,i=null;try{var o=new ce(t,r)}catch(e){return null}return e.forEach((function(e){o.test(e)&&(n&&-1!==i.compare(e)||(i=new Y(n=e,r)))})),n},t.minSatisfying=function(e,t,r){var n=null,i=null;try{var o=new ce(t,r)}catch(e){return null}return e.forEach((function(e){o.test(e)&&(n&&1!==i.compare(e)||(i=new Y(n=e,r)))})),n},t.minVersion=function(e,t){e=new ce(e,t);var r=new Y("0.0.0");if(e.test(r))return r;if(r=new Y("0.0.0-0"),e.test(r))return r;r=null;for(var n=0;n<e.set.length;++n){e.set[n].forEach((function(e){var t=new Y(e.semver.version);switch(e.operator){case">":0===t.prerelease.length?t.patch++:t.prerelease.push(0),t.raw=t.format();case"":case">=":r&&!Z(r,t)||(r=t);break;case"<":case"<=":break;default:throw new Error("Unexpected operation: "+e.operator)}}))}if(r&&e.test(r))return r;return null},t.validRange=function(e,t){try{return new ce(e,t).range||"*"}catch(e){return null}},t.ltr=function(e,t,r){return fe(e,t,"<",r)},t.gtr=function(e,t,r){return fe(e,t,">",r)},t.outside=fe,t.prerelease=function(e,t){var r=X(e,t);return r&&r.prerelease.length?r.prerelease:null},t.intersects=function(e,t,r){return e=new ce(e,r),t=new ce(t,r),e.intersects(t)},t.coerce=function(e){if(e instanceof Y)return e;if("string"!=typeof e)return null;var t=e.match(o[R]);if(null==t)return null;return X(t[1]+"."+(t[2]||"0")+"."+(t[3]||"0"))}})),vt=(wt.SEMVER_SPEC_VERSION,wt.re,wt.safeRe,wt.src,wt.parse,wt.valid,wt.clean,wt.SemVer,wt.inc,wt.diff,wt.compareIdentifiers,wt.rcompareIdentifiers,wt.major,wt.minor,wt.patch,wt.compare,wt.compareLoose,wt.rcompare,wt.sort,wt.rsort,wt.gt,wt.lt,wt.eq,wt.neq,wt.gte,wt.lte,wt.cmp,wt.Comparator,wt.Range,wt.toComparators,wt.satisfies,wt.maxSatisfying,wt.minSatisfying,wt.minVersion,wt.validRange,wt.ltr,wt.gtr,wt.outside,wt.prerelease,wt.intersects,wt.coerce,wt.satisfies(process.version,"^6.12.0 || >=8.0.0")),_t=["RS256","RS384","RS512","ES256","ES384","ES512"],bt=["RS256","RS384","RS512"],Tt=["HS256","HS384","HS512"];vt&&(_t.splice(3,0,"PS256","PS384","PS512"),bt.splice(3,0,"PS256","PS384","PS512"));var Et=/^\s+|\s+$/g,Ct=/^[-+]0x[0-9a-f]+$/i,At=/^0b[01]+$/i,xt=/^0o[0-7]+$/i,It=/^(?:0|[1-9]\d*)$/,St=parseInt;function kt(e){return e!=e}function Ot(e,t){return function(e,t){for(var r=-1,n=e?e.length:0,i=Array(n);++r<n;)i[r]=t(e[r],r,e);return i}(t,(function(t){return e[t]}))}var Pt,Rt,jt=Object.prototype,Dt=jt.hasOwnProperty,qt=jt.toString,Nt=jt.propertyIsEnumerable,Ut=(Pt=Object.keys,Rt=Object,function(e){return Pt(Rt(e))}),Lt=Math.max;function Vt(e,t){var r=Ft(e)||function(e){return function(e){return Kt(e)&&$t(e)}(e)&&Dt.call(e,"callee")&&(!Nt.call(e,"callee")||"[object Arguments]"==qt.call(e))}(e)?function(e,t){for(var r=-1,n=Array(e);++r<e;)n[r]=t(r);return n}(e.length,String):[],n=r.length,i=!!n;for(var o in e)!t&&!Dt.call(e,o)||i&&("length"==o||Bt(o,n))||r.push(o);return r}function Mt(e){if(r=(t=e)&&t.constructor,n="function"==typeof r&&r.prototype||jt,t!==n)return Ut(e);var t,r,n,i=[];for(var o in Object(e))Dt.call(e,o)&&"constructor"!=o&&i.push(o);return i}function Bt(e,t){return!!(t=null==t?9007199254740991:t)&&("number"==typeof e||It.test(e))&&e>-1&&e%1==0&&e<t}var Ft=Array.isArray;function $t(e){return null!=e&&function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}(e.length)&&!function(e){var t=Ht(e)?qt.call(e):"";return"[object Function]"==t||"[object GeneratorFunction]"==t}(e)}function Ht(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function Kt(e){return!!e&&"object"==typeof e}var Gt=function(e,t,r,n){var i;e=$t(e)?e:(i=e)?Ot(i,function(e){return $t(e)?Vt(e):Mt(e)}(i)):[],r=r&&!n?function(e){var t=function(e){if(!e)return 0===e?e:0;if((e=function(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||Kt(e)&&"[object Symbol]"==qt.call(e)}(e))return NaN;if(Ht(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=Ht(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(Et,"");var r=At.test(e);return r||xt.test(e)?St(e.slice(2),r?2:8):Ct.test(e)?NaN:+e}(e))===1/0||e===-1/0){return 17976931348623157e292*(e<0?-1:1)}return e==e?e:0}(e),r=t%1;return t==t?r?t-r:t:0}(r):0;var o=e.length;return r<0&&(r=Lt(o+r,0)),function(e){return"string"==typeof e||!Ft(e)&&Kt(e)&&"[object String]"==qt.call(e)}(e)?r<=o&&e.indexOf(t,r)>-1:!!o&&function(e,t,r){if(t!=t)return function(e,t,r,n){for(var i=e.length,o=r+(n?1:-1);n?o--:++o<i;)if(t(e[o],o,e))return o;return-1}(e,kt,r);for(var n=r-1,i=e.length;++n<i;)if(e[n]===t)return n;return-1}(e,t,r)>-1},Qt=Object.prototype.toString;var Xt=function(e){return!0===e||!1===e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Boolean]"==Qt.call(e)},Yt=/^\s+|\s+$/g,zt=/^[-+]0x[0-9a-f]+$/i,Wt=/^0b[01]+$/i,Jt=/^0o[0-7]+$/i,Zt=parseInt,er=Object.prototype.toString;function tr(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var rr=function(e){return"number"==typeof e&&e==function(e){var t=function(e){if(!e)return 0===e?e:0;if((e=function(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==er.call(e)}(e))return NaN;if(tr(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=tr(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(Yt,"");var r=Wt.test(e);return r||Jt.test(e)?Zt(e.slice(2),r?2:8):zt.test(e)?NaN:+e}(e))===1/0||e===-1/0){return 17976931348623157e292*(e<0?-1:1)}return e==e?e:0}(e),r=t%1;return t==t?r?t-r:t:0}(e)},nr=Object.prototype.toString;var ir=function(e){return"number"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Number]"==nr.call(e)};var or=Function.prototype,sr=Object.prototype,ar=or.toString,cr=sr.hasOwnProperty,ur=ar.call(Object),dr=sr.toString,pr=function(e,t){return function(r){return e(t(r))}}(Object.getPrototypeOf,Object);var lr=function(e){if(!function(e){return!!e&&"object"==typeof e}(e)||"[object Object]"!=dr.call(e)||function(e){var t=!1;if(null!=e&&"function"!=typeof e.toString)try{t=!!(e+"")}catch(e){}return t}(e))return!1;var t=pr(e);if(null===t)return!0;var r=cr.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&&ar.call(r)==ur},fr=Object.prototype.toString,mr=Array.isArray;var hr=function(e){return"string"==typeof e||!mr(e)&&function(e){return!!e&&"object"==typeof e}(e)&&"[object String]"==fr.call(e)},gr=/^\s+|\s+$/g,yr=/^[-+]0x[0-9a-f]+$/i,wr=/^0b[01]+$/i,vr=/^0o[0-7]+$/i,_r=parseInt,br=Object.prototype.toString;function Tr(e,t){var r;if("function"!=typeof t)throw new TypeError("Expected a function");return e=function(e){var t=function(e){if(!e)return 0===e?e:0;if((e=function(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==br.call(e)}(e))return NaN;if(Er(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=Er(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(gr,"");var r=wr.test(e);return r||vr.test(e)?_r(e.slice(2),r?2:8):yr.test(e)?NaN:+e}(e))===1/0||e===-1/0){return 17976931348623157e292*(e<0?-1:1)}return e==e?e:0}(e),r=t%1;return t==t?r?t-r:t:0}(e),function(){return--e>0&&(r=t.apply(this,arguments)),e<=1&&(t=void 0),r}}function Er(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var Cr=function(e){return Tr(2,e)},Ar=["RS256","RS384","RS512","ES256","ES384","ES512","HS256","HS384","HS512","none"];vt&&Ar.splice(3,0,"PS256","PS384","PS512");var xr={expiresIn:{isValid:function(e){return rr(e)||hr(e)&&e},message:'"expiresIn" should be a number of seconds or string representing a timespan'},notBefore:{isValid:function(e){return rr(e)||hr(e)&&e},message:'"notBefore" should be a number of seconds or string representing a timespan'},audience:{isValid:function(e){return hr(e)||Array.isArray(e)},message:'"audience" must be a string or array'},algorithm:{isValid:Gt.bind(null,Ar),message:'"algorithm" must be a valid string enum value'},header:{isValid:lr,message:'"header" must be an object'},encoding:{isValid:hr,message:'"encoding" must be a string'},issuer:{isValid:hr,message:'"issuer" must be a string'},subject:{isValid:hr,message:'"subject" must be a string'},jwtid:{isValid:hr,message:'"jwtid" must be a string'},noTimestamp:{isValid:Xt,message:'"noTimestamp" must be a boolean'},keyid:{isValid:hr,message:'"keyid" must be a string'},mutatePayload:{isValid:Xt,message:'"mutatePayload" must be a boolean'}},Ir={iat:{isValid:ir,message:'"iat" should be a number of seconds'},exp:{isValid:ir,message:'"exp" should be a number of seconds'},nbf:{isValid:ir,message:'"nbf" should be a number of seconds'}};function Sr(e,t,r,n){if(!lr(r))throw new Error('Expected "'+n+'" to be a plain object.');Object.keys(r).forEach((function(i){var o=e[i];if(o){if(!o.isValid(r[i]))throw new Error(o.message)}else if(!t)throw new Error('"'+i+'" is not allowed in "'+n+'"')}))}var kr={audience:"aud",issuer:"iss",subject:"sub",jwtid:"jti"},Or=["expiresIn","notBefore","noTimestamp","audience","issuer","subject","jwtid"],Pr=function(e,t,r,n){var i;if("function"!=typeof r||n||(n=r,r={}),r||(r={}),r=Object.assign({},r),i=n||function(e,t){if(e)throw e;return t},r.clockTimestamp&&"number"!=typeof r.clockTimestamp)return i(new st("clockTimestamp must be a number"));if(void 0!==r.nonce&&("string"!=typeof r.nonce||""===r.nonce.trim()))return i(new st("nonce must be a non-empty string"));var o=r.clockTimestamp||Math.floor(Date.now()/1e3);if(!e)return i(new st("jwt must be provided"));if("string"!=typeof e)return i(new st("jwt must be a string"));var s,a=e.split(".");if(3!==a.length)return i(new st("jwt malformed"));try{s=it(e,{complete:!0})}catch(e){return i(e)}if(!s)return i(new st("invalid token"));var c,u=s.header;if("function"==typeof t){if(!n)return i(new st("verify must be called asynchronous if secret or public key is provided as a callback"));c=t}else c=function(e,r){return r(null,t)};return c(u,(function(t,n){if(t)return i(new st("error in secret or public key callback: "+t.message));var c,d=""!==a[2].trim();if(!d&&n)return i(new st("jwt signature is required"));if(d&&!n)return i(new st("secret or public key must be provided"));if(d||r.algorithms||(r.algorithms=["none"]),r.algorithms||(r.algorithms=~n.toString().indexOf("BEGIN CERTIFICATE")||~n.toString().indexOf("BEGIN PUBLIC KEY")?_t:~n.toString().indexOf("BEGIN RSA PUBLIC KEY")?bt:Tt),!~r.algorithms.indexOf(s.header.alg))return i(new st("invalid algorithm"));try{c=nt.verify(e,s.header.alg,n)}catch(e){return i(e)}if(!c)return i(new st("invalid signature"));var p=s.payload;if(void 0!==p.nbf&&!r.ignoreNotBefore){if("number"!=typeof p.nbf)return i(new st("invalid nbf value"));if(p.nbf>o+(r.clockTolerance||0))return i(new ct("jwt not active",new Date(1e3*p.nbf)))}if(void 0!==p.exp&&!r.ignoreExpiration){if("number"!=typeof p.exp)return i(new st("invalid exp value"));if(o>=p.exp+(r.clockTolerance||0))return i(new dt("jwt expired",new Date(1e3*p.exp)))}if(r.audience){var l=Array.isArray(r.audience)?r.audience:[r.audience];if(!(Array.isArray(p.aud)?p.aud:[p.aud]).some((function(e){return l.some((function(t){return t instanceof RegExp?t.test(e):t===e}))})))return i(new st("jwt audience invalid. expected: "+l.join(" or ")))}if(r.issuer&&("string"==typeof r.issuer&&p.iss!==r.issuer||Array.isArray(r.issuer)&&-1===r.issuer.indexOf(p.iss)))return i(new st("jwt issuer invalid. expected: "+r.issuer));if(r.subject&&p.sub!==r.subject)return i(new st("jwt subject invalid. expected: "+r.subject));if(r.jwtid&&p.jti!==r.jwtid)return i(new st("jwt jwtid invalid. expected: "+r.jwtid));if(r.nonce&&p.nonce!==r.nonce)return i(new st("jwt nonce invalid. expected: "+r.nonce));if(r.maxAge){if("number"!=typeof p.iat)return i(new st("iat required when maxAge is specified"));var f=yt(r.maxAge,p.iat);if(void 0===f)return i(new st('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));if(o>=f+(r.clockTolerance||0))return i(new dt("maxAge exceeded",new Date(1e3*f)))}if(!0===r.complete){var m=s.signature;return i(null,{header:u,payload:p,signature:m})}return i(null,p)}))},Rr=function(e,t,r,n){"function"==typeof r?(n=r,r={}):r=r||{};var i="object"==typeof e&&!Buffer.isBuffer(e),o=Object.assign({alg:r.algorithm||"HS256",typ:i?"JWT":void 0,kid:r.keyid},r.header);function s(e){if(n)return n(e);throw e}if(!t&&"none"!==r.algorithm)return s(new Error("secretOrPrivateKey must have a value"));if(void 0===e)return s(new Error("payload is required"));if(i){try{!function(e){Sr(Ir,!0,e,"payload")}(e)}catch(e){return s(e)}r.mutatePayload||(e=Object.assign({},e))}else{var a=Or.filter((function(e){return void 0!==r[e]}));if(a.length>0)return s(new Error("invalid "+a.join(",")+" option for "+typeof e+" payload"))}if(void 0!==e.exp&&void 0!==r.expiresIn)return s(new Error('Bad "options.expiresIn" option the payload already has an "exp" property.'));if(void 0!==e.nbf&&void 0!==r.notBefore)return s(new Error('Bad "options.notBefore" option the payload already has an "nbf" property.'));try{!function(e){Sr(xr,!1,e,"options")}(r)}catch(e){return s(e)}var c=e.iat||Math.floor(Date.now()/1e3);if(r.noTimestamp?delete e.iat:i&&(e.iat=c),void 0!==r.notBefore){try{e.nbf=yt(r.notBefore,c)}catch(e){return s(e)}if(void 0===e.nbf)return s(new Error('"notBefore" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'))}if(void 0!==r.expiresIn&&"object"==typeof e){try{e.exp=yt(r.expiresIn,c)}catch(e){return s(e)}if(void 0===e.exp)return s(new Error('"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'))}Object.keys(kr).forEach((function(t){var n=kr[t];if(void 0!==r[t]){if(void 0!==e[n])return s(new Error('Bad "options.'+t+'" option. The payload already has an "'+n+'" property.'));e[n]=r[t]}}));var u=r.encoding||"utf8";if("function"!=typeof n)return nt.sign({header:o,payload:e,secret:t,encoding:u});n=n&&Cr(n),nt.createSign({header:o,privateKey:t,payload:e,encoding:u}).once("error",n).once("done",(function(e){n(null,e)}))};let jr=[];class Dr{constructor(e){this.options=Object.assign({baseUrl:"https://appleid.apple.com",timeout:1e4},e)}async _fetch(e,t){const{baseUrl:r}=this.options;return uniCloud.httpclient.request(r+e,t)}async verifyIdentityToken(e){const t=e.split(".")[0],{kid:r}=JSON.parse(Buffer.from(t,"base64").toString());if(!jr.length)try{jr=await this.getAuthKeys()}catch(e){return{code:10705,msg:e.message}}const n=this.getUsedKey(jr,r);if(!Object.keys(n).length&&!this.fetched)try{jr=await this.getAuthKeys()}catch(e){return{code:10705,msg:e.message}}let i=null;try{i=Pr(e,function(e,t){var r=Buffer.from(e,"base64"),n=Buffer.from(t,"base64"),i=r.toString("hex"),o=n.toString("hex");i=J(i),o=J(o);var s=i.length/2,a=o.length/2,c=ee(s),u=ee(a),d="30"+ee(s+a+c.length/2+u.length/2+2)+"02"+c+i+"02"+u+o;return"-----BEGIN RSA PUBLIC KEY-----\n"+Buffer.from(d,"hex").toString("base64").match(/.{1,64}/g).join("\n")+"\n-----END RSA PUBLIC KEY-----\n"}(n.n,n.e),{algorithms:n.alg})}catch(e){return{code:10705,msg:e.message}}return{code:0,msg:i}}async getAuthKeys(){const{status:e,data:t}=await this._fetch("/auth/keys",{method:"GET",dataType:"json",timeout:this.options.timeout});if(200!==e)throw new Error("request https://appleid.apple.com/auth/keys fail");return t.keys}getUsedKey(e,t){let r={};for(let n=0;n<e.length;n++){const i=e[n];if(i.kid===t){r=i;break}}return r}}var qr=function(e={}){return e.appId=e.appid,e.secret=e.appsecret,I(G,e)},Nr=function(e={}){return e.appId=e.appid,e.secret=e.appsecret,I(X,e)},Ur=function(e={}){return e.appId=e.appid,I(W,e)},Lr=function(e={}){return I(Dr,e)};function Vr(e=6){const t=["2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z"];let r="";for(let n=0;n<e;n++)r+=t[Math.floor(Math.random()*t.length)];return r}async function Mr(e){return 0===(await P.where({my_invite_code:e}).get()).data.length}const Br=O.command;async function Fr({uid:e,dcloudAppidList:t}={}){if(!e)return{code:N,messageValues:{param:this.t("user-id")}};if(!t||0===t.length||t.some(e=>void 0===e))return{code:N,messageValues:{param:this.t("dcloud-appid")}};const r=await P.doc(e).get(),n=r&&r.data&&r.data[0];if(!n)return{code:10002};const i=Object.keys(q).reduce((e,t)=>{const r=t,i=function(e,t){return t.split(".").reduce((e,t)=>e&&e[t],e)}(n,t);return i&&e.push({[r]:i}),e},[]);let o;const s={dcloud_appid:Br.in(t),_id:Br.neq(n._id)},a={dcloud_appid:Br.exists(!1),_id:Br.neq(n._id)};switch(i.length){case 0:return{code:10004};case 1:o=Br.or([Br.and([i[0],s]),Br.and([i[0],a])]);break;default:o=Br.or([Br.and([Br.or(i),s]),Br.and([Br.or(i),a])])}const c=await P.where(o).limit(1).get();return c&&c.data&&c.data[0]?{code:10005}:{code:0}}const $r=uniCloud.database().command;const Hr=uniCloud.database();const Kr=uniCloud.database().command;const Gr=uniCloud.database();const Qr=uniCloud.database();async function Xr(e){if(!e.openid||!e.access_token)throw new Error(this.t("config-param-required",{param:"openid, access_token"}));return function(e,t){const r={0:"",4e3:"缺失参数",4001:"apiKey不存在",4002:"sign校验不通过",4003:"appid不存在",4004:"应用未开通一键登录服务",4005:"应用开通的一键登录服务正在审核中",4006:"服务空间不在白名单中",4100:"账户余额不足",5e3:"获取手机号失败，请稍后重试(或其他未知错误)"};return{...e,msg:r[e.code]?"[getPhoneNumber] 获取手机号: "+r[e.code]:e.errMsg}}(await uniCloud.getPhoneNumber({provider:"univerify",...e}))}const Yr=uniCloud.database();const zr=uniCloud.database();const Wr=uniCloud.database();const Jr=uniCloud.database().command;const Zr=uniCloud.database();const en=uniCloud.database();const tn=uniCloud.database();const rn=uniCloud.database();const nn=uniCloud.database();const on=uniCloud.database();const sn=uniCloud.database();const an={"mobile-code":function(e){return!(!e.service||!e.service.sms)},univerify:function(e){return!(!e.service||!e.service.univerify)},weixin:function(e){return!!(e.oauth&&e.oauth.weixin&&e.oauth.weixin.appsecret)},qq:function(e){return!!(e.oauth&&e.oauth.qq&&e.oauth.qq.appsecret)},apple:function(e){return!!(e.oauth&&e.oauth.apple&&e.oauth.apple.bundleId)},alipay:function(e){return!!(e.oauth&&e.oauth.alipay&&e.oauth.alipay.privateKey)}};const cn=uniCloud.database();var un=Object.freeze({__proto__:null,addUser:async function({username:e,nickname:t,password:r,mobile:n,email:i,role:o=[],authorizedApp:s=[]}={}){const a=O.command,c=[];if(!e&&!n&&!i)throw new Error("username, mobile or email required");let u;if(e&&c.push({username:e}),n&&c.push({mobile:n,mobile_confirmed:1}),i&&c.push({email:i,email_confirmed:1}),s.length>0){u=a.and(a.or(c),a.or({dcloud_appid:a.in(s)},{dcloud_appid:a.exists(!1)}));if((await P.where(u).limit(1).get()).data.length>0)return{code:10201,messageValues:{type:this.t("username")}}}const d={role:o,nickname:t,dcloud_appid:s,register_date:Date.now()};if(e&&(d.username=e),r){const{passwordHash:e,version:t}=this.encryptPwd(r);d.password=e,t&&(d.password_secret_version=t)}return n&&(d.mobile=n,d.mobile_confirmed=1),i&&(d.email=i,d.email_confirmed=1),{code:0,uid:(await P.add(d)).id}},getUserInfo:async function({uid:e,field:t}){if(!e)return{code:N,messageValues:{param:this.t("user-id")}};let r;if(t&&t.length){const n={};for(let e=0;e<t.length;e++)n[t[e]]=!0;r=await P.doc(e).field(n).get()}else r=await P.doc(e).get();return 0===r.data.length?{code:80301}:{code:0,msg:"",userInfo:r.data[0]}},getUserInfoByToken:async function(e){const t=this._verifyToken(e);return t.code||(delete t.iat,delete t.exp),t},resetPwd:async function({uid:e,password:t}){const{passwordHash:r,version:n}=this.encryptPwd(t),i={password:r,token:[]};return n&&(i.password_secret_version=n),E("upRes",await P.doc(e).update(i)),{code:0,msg:""}},resetPwdBySms:async function({mobile:e,code:t,password:r}){const n=await this.verifyCode({mobile:e,code:t,type:"reset-pwd"});if(0!==n.code)return n;const i=(await P.where({mobile:e}).get()).data.filter(e=>void 0===e.dcloud_appid||e.dcloud_appid.includes(this.context.APPID));if(0===i.length)return{code:10002};if(i.length>1)return{code:10005};const o=i[0]._id;return this.resetPwd({uid:o,password:r})},setAvatar:async function(e){return await P.doc(e.uid).update({avatar:e.avatar}),{code:0,msg:""}},updatePwd:async function(e){const t=await P.doc(e.uid).get();if(t&&t.data&&t.data.length>0){if(0===this._checkPwd(t.data[0],e.oldPassword).code){const{passwordHash:r,version:n}=this.encryptPwd(e.newPassword),i={password:r,token:[]};n&&(i.password_secret_version=n);return E("upRes",await P.doc(t.data[0]._id).update(i)),{code:0,msg:""}}return{code:40202}}return{code:40201}},updateUser:async function(e){const t=e.uid;if(!t)return{code:N,messageValues:{param:this.t("user-id")}};delete e.uid;const{username:r,email:n}=e,{usernameToLowerCase:i,emailToLowerCase:o}=this._getConfig();let s=r&&r.trim(),a=n&&n.trim();return s&&(i&&(s=s.toLowerCase()),e.username=s),a&&(o&&(a=a.toLowerCase()),e.email=a),E("update -> upRes",await P.doc(t).update(e)),{code:0,msg:""}},banAccount:async function({uid:e}={}){return $.call(this,{uid:e,status:B})},unbanAccount:async function({uid:e}={}){return $.call(this,{uid:e,status:M})},closeAccount:async function({uid:e}={}){return $.call(this,{uid:e,status:F})},openAccount:async function({uid:e}={}){return $.call(this,{uid:e,status:M})},_getAlipayApi:function(){const e=this.context.PLATFORM,t=this._getConfig();if(!t.oauth||!t.oauth.alipay)throw new Error(this.t("config-param-require",{param:e+".alipay"}));return["appid","privateKey"].forEach(r=>{if(!t.oauth.alipay[r])throw new Error(this.t("config-param-require",{param:`${e}.alipay.${r}`}))}),Ur({...t.oauth.alipay})},_getValidInviteCode:async function({inviteCode:e}={}){if(e){return await Mr(e)?{code:0,inviteCode:e}:{code:80401}}return async function(){let e,t=10,r=!1;for(;t>0&&!r;){t--,e=Vr();if(await Mr(e)){r=!0;break}}return r?{code:0,inviteCode:e}:{code:80402}}()},_addUser:async function(e,{needPermission:t,autoSetDcloudAppid:r=!0}={}){const n=this._getConfig(),i={...e,dcloud_appid:r?[this.context.APPID]:[],register_date:Date.now()},o=(await P.add(i)).id;let s;if(n.removePermissionAndRoleFromToken)s=await this.createToken({uid:o,needPermission:t});else{const t=e.role||[];let r;r=0===t.length||t.includes("admin")?[]:await this._getPermissionListByRoleList(t),s=await this.createToken({uid:o,role:t,permission:r})}const{token:a,tokenExpired:c}=s;return await P.doc(o).update({token:[a]}),{token:a,tokenExpired:c,uid:o,type:"register",userInfo:Object.assign({},i,{token:[a]})}},_loginExec:async function(e,t={}){if(e.status===B)return{code:10001};if(e.status===F)return{code:10006};const r=this._getConfig();let n=e.token||[];"string"==typeof n&&(n=[n]);const i=this._getExpiredToken(n);let o;if(n=n.filter(e=>-1===i.indexOf(e)),r.removePermissionAndRoleFromToken){const r=t.needPermission;o=await this.createToken({uid:e._id,needPermission:r})}else{const t=e.role||[];let r;r=0===t.length||t.includes("admin")?[]:await this._getPermissionListByRoleList(t),o=await this.createToken({uid:e._id,role:t,permission:r})}const{token:s,tokenExpired:a}=o;n.push(s),e.token=n;const c={last_login_date:Date.now(),last_login_ip:this.context.CLIENTIP,token:n,...t.extraData};await P.doc(e._id).update(c);const u=Object.assign({},e,c);return{code:0,msg:"",token:s,uid:u._id,username:u.username,type:"login",userInfo:u,tokenExpired:a}},_registerExec:async function(e,{needPermission:t,autoSetDcloudAppid:r=!0}={}){const{my_invite_code:n}=e;if(this._getConfig().autoSetInviteCode||n){const t=await this._getValidInviteCode({inviteCode:n});if(t.code)return t;e.my_invite_code=t.inviteCode}const{PLATFORM:i,appId:o,appid:s,APPID:a,uniPlatform:c,appName:u,appVersion:d,appVersionCode:p,channel:l,clientIP:f,CLIENTIP:m,OS:h,osName:g}=this.context;return e.register_env={appid:o||s||a||"",uni_platform:c||i||"",os_name:g||h||"",app_name:u||"",app_version:d||"",app_version_code:p||"",channel:l?l+"":"",client_ip:f||m||""},{code:0,msg:"",...await this._addUser(e,{needPermission:t,autoSetDcloudAppid:r})}},_getWeixinApi:function(){const e=this.context.PLATFORM,t=this._getConfig();if(!t.oauth||!t.oauth.weixin)throw new Error(this.t("config-param-require",{param:e+".weixin"}));return["appid","appsecret"].forEach(r=>{if(!t.oauth.weixin[r])throw new Error(this.t("config-param-require",{param:`${e}.weixin.${r}`}))}),qr({...t.oauth.weixin})},_getQQApi:function(){const e=this.context.PLATFORM,t=this._getConfig();if(!t.oauth||!t.oauth.qq)throw new Error(this.t("config-param-require",{param:e+".qq"}));return["appid","appsecret"].forEach(r=>{if(!t.oauth.qq[r])throw new Error(this.t("config-param-require",{param:`${e}.qq.${r}`}))}),Nr({...t.oauth.qq})},_getMatchedUser:function(e,t){if(0===e.length)return{code:10002};let r;const n={},i={};for(let r=e.length-1;r>=0;r--){const o=e[r];for(let s=0;s<t.length;s++){const{field:a,value:c,fallbackValue:u}=t[s];c&&o[a]===c?(n[a]=o,e.splice(r,1)):u&&o[a]===u&&(n[a]||(n[a]=o),i[a]=!0,e.splice(r,1))}}const o=Object.keys(n);let s;switch(o.length){case 0:r=e[0],e.splice(0,1);break;case 1:s=o[0],r=n[s];break;default:return{code:10003,messageValues:{target:"用户"}}}return e.length>0?{code:10003,messageValues:{target:"用户"}}:{code:0,msg:"",userMatched:r,fieldMatched:s,isFallbackValueMatched:!!s&&i[s]}},_getCurrentAppUser:function(e){const t=this.context.APPID;return e.filter(e=>void 0===e.dcloud_appid||null===e.dcloud_appid||e.dcloud_appid.indexOf(t)>-1||e.dcloud_appid.indexOf(null)>-1)},_checkLoginUserList:function(e){if(e&&1!==e.length)return e[0].status===F?{code:10006}:{code:10005}},setAuthorizedAppLogin:async function({uid:e,dcloudAppidList:t}={}){if("array"!==m(t))return{code:U,messageValues:{param:"dcloudAppidList",reason:this.t("type-array-required",{param:this.t("dcloud-appid-list")})}};if(t&&0!==t.length){const r=await Fr.bind(this)({uid:e,dcloudAppidList:t});if(r.code)return r}return await P.doc(e).update({dcloud_appid:Br.set(t)}),{code:0}},authorizeAppLogin:async function({uid:e,dcloudAppid:t}={}){const r=await Fr.bind(this)({uid:e,dcloudAppidList:[t]});return r.code?r:(await P.doc(e).update({dcloud_appid:Br.push(t)}),{code:0})},forbidAppLogin:async function({uid:e,dcloudAppid:t}={}){return e?(await P.doc(e).update({dcloud_appid:Br.pull(t)}),{code:0}):{code:N,messageValues:{param:this.t("user-id")}}},acceptInvite:async function({uid:e,inviteCode:t}){const r=await P.where({_id:$r.neq(e),inviter_uid:$r.not($r.all([e])),my_invite_code:t}).get();if(1!==r.data.length)return{code:80501,msg:"邀请码无效"};const n=[r.data[0]._id].concat(r.data[0].inviter_uid||[]),i=await P.doc(e).field({my_invite_code:!0,inviter_uid:!0}).get();if(0===i.data.length)return{code:80502};if(i.data[0].inviter_uid&&i.data[0].inviter_uid.length>0)return{code:80503,msg:"邀请码不可修改"};const o=Date.now();return await P.doc(e).update({inviter_uid:n,invite_time:o}),await P.where({inviter_uid:e}).update({inviter_uid:$r.push(n)}),{code:0,msg:""}},getInvitedUser:async function({uid:e,level:t=1,limit:r=20,offset:n=0,needTotal:i=!1}){const o={code:0,msg:"",invitedUser:(await P.where({["inviter_uid."+(t-1)]:e}).field({_id:!0,username:!0,mobile:!0,invite_time:!0}).orderBy("invite_time","desc").skip(n).limit(r).get()).data};if(i){const r=await P.where({["inviter_uid."+(t-1)]:e}).count();o.total=r.total}return o},setUserInviteCode:async function({uid:e,myInviteCode:t}){const r=await this._getValidInviteCode({inviteCode:t});return r.code?r:(await P.doc(e).update({my_invite_code:r.inviteCode}),{code:0,msg:"",myInviteCode:r.inviteCode})},loginByAlipay:async function(e){"string"==typeof e&&(e={code:e});const{needPermission:t,code:r,myInviteCode:n,role:i,type:o}=e,{openid:s}=await this._getAlipayApi().code2Session(r);if(!s)return{code:10501,messageValues:{account:this.t("alipay-account")}};let a=await P.where({ali_openid:s}).get();if(a=this._getCurrentAppUser(a.data),a&&a.length>0){if("register"===o)return{code:10502,messageValues:{type:this.t("alipay-account")}};if(1!==a.length)return{code:10005};const e=a[0],r=await this._loginExec(e,{needPermission:t});if(0!==r.code)return r;const{userInfo:n}=r;return{...r,openid:s,mobileConfirmed:1===n.mobile_confirmed,emailConfirmed:1===n.email_confirmed}}{if("login"===o)return{code:10503,messageValues:{type:this.t("alipay-account")}};const e={ali_openid:s};e.my_invite_code=n,e.role=i;const r=await this._registerExec(e,{needPermission:t});return 0!==r.code?r:{...r,openid:s,mobileConfirmed:!1,emailConfirmed:!1}}},loginByEmail:async function(e){let{email:t,code:r,password:n,myInviteCode:i,type:o,needPermission:s,role:a}=e||{};if(t=t&&t.trim(),!t)return{code:N,messageValues:{param:"邮箱"}};const{emailToLowerCase:c}=this._getConfig();let u=t;c&&(u=t.toLowerCase());const d=await this.verifyCode({email:u,code:r,type:o||"login"});if(0!==d.code)return d;let p={email:t,email_confirmed:1};const l={field:"email",value:t},f=Hr.command;u!==t&&(p=f.or(p,{email:u,email_confirmed:1}),l.fallbackValue=u);let m=await P.where(p).get();if(m=this._getCurrentAppUser(m.data),m&&m.length>0){if("register"===o)return{code:10301,messageValues:{type:"邮箱"}};const e=this._getMatchedUser(m,[l]);if(e.code)return e;const{userMatched:t}=e,r=await this._loginExec(t,{needPermission:s});return 0!==r.code?r:{...r,email:u}}{if("login"===o)return{code:10302,messageValues:{type:"邮箱"}};const e={email:u,email_confirmed:1},t=n&&n.trim();if(t){const{passwordHash:r,version:n}=this.encryptPwd(t);e.password=r,n&&(e.password_secret_version=n)}e.my_invite_code=i,e.role=a;const r=await this._registerExec(e,{needPermission:s});return 0!==r.code?r:{...r,email:u}}},loginBySms:async function({mobile:e,code:t,password:r,inviteCode:n,myInviteCode:i,type:o,needPermission:s,role:a}){if(!(e=e&&e.trim()))return{code:N,messageValues:{param:this.t("mobile")}};const c=this._getConfig();if(c.forceInviteCode&&!o)throw new Error(this.t("login-with-invite-type-required"));const u=await this.verifyCode({mobile:e,code:t,type:o||"login"});if(0!==u.code)return u;const d={mobile:e,mobile_confirmed:1};let p=await P.where(d).get();if(p=this._getCurrentAppUser(p.data),p&&p.length>0){if("register"===o)return{code:10201,messageValues:{type:this.t("mobile")}};if(1!==p.length)return{code:10005};const t=p[0],r=await this._loginExec(t,{needPermission:s});return 0!==r.code?r:{...r,mobile:e}}{const t=Date.now();if("login"===o)return{code:10202,messageValues:{type:this.t("mobile")}};const u={mobile:e,mobile_confirmed:1,register_ip:this.context.CLIENTIP,register_date:t},d=r&&r.trim();if(d){const{passwordHash:e,version:t}=this.encryptPwd(d);u.password=e,t&&(u.password_secret_version=t)}if(n){const e=await P.where({my_invite_code:n}).get();if(1!==e.data.length)return{code:10203};u.inviter_uid=[e.data[0]._id].concat(e.data[0].inviter_uid||[]),u.invite_time=t}else if(c.forceInviteCode)return{code:10203};u.my_invite_code=i,u.role=a;const p=await this._registerExec(u,{needPermission:s});return 0!==p.code?p:{...p,mobile:e}}},loginByWeixin:async function(e){"string"==typeof e&&(e={code:e});const{needPermission:t,platform:r,code:n,myInviteCode:i,role:o,type:s}=e,a=r||this.context.PLATFORM,c=function({clientPlatform:e,userAgent:t}={}){switch(e){case"app":case"app-plus":return"app";case"mp-weixin":return"mp";case"h5":case"web":return t.indexOf("MicroMessenger")>-1?"h5":"web";default:throw new Error("Unsupported weixin platform")}}({clientPlatform:a,userAgent:this.context.CLIENTUA}),u="mp-weixin"===a,{openid:d,unionid:p,sessionKey:l,accessToken:f,refreshToken:m,expired:h}=await this._getWeixinApi()[u?"code2Session":"getOauthAccessToken"](n);if(!d)return{code:10401,messageValues:{account:"微信openid"}};const g={dcloudAppid:this.context.APPID,openid:d,platform:"weixin-"+c},y=require("uni-open-bridge-common");let w;u?(w={sessionKey:l},await y.setSessionKey(g,{session_key:l},2592e3)):(w={accessToken:f,refreshToken:m,accessTokenExpired:h},await y.setUserAccessToken(g,{access_token:f,refresh_token:m,access_token_expired:h},2592e3));const v=Gr.command,_=[{wx_openid:{[a]:d}}];p&&_.push({wx_unionid:p});let b=await P.where(v.or(..._)).get();if(b=this._getCurrentAppUser(b.data),b&&b.length>0){if("register"===s)return{code:10402,messageValues:{type:this.t("wechat-account")}};if(1!==b.length)return{code:10005};const e=b[0],r={wx_openid:{[a]:d}};p&&(r.wx_unionid=p);const n=await this._loginExec(e,{needPermission:t,extraData:r});if(0!==n.code)return n;const{userInfo:i}=n;return{...n,openid:d,unionid:p,...w,mobileConfirmed:1===i.mobile_confirmed,emailConfirmed:1===i.email_confirmed}}{if("login"===s)return{code:10403,messageValues:{type:this.t("wechat-account")}};const e={wx_openid:{[a]:d},wx_unionid:p};e.my_invite_code=i,e.role=o;const r=await this._registerExec(e,{needPermission:t});return 0!==r.code?r:{...r,openid:d,unionid:p,...w,mobileConfirmed:!1,emailConfirmed:!1}}},loginByQQ:async function({code:e,accessToken:t,accessTokenExpired:r,myInviteCode:n,needPermission:i,role:o,type:s}={}){const a=this.context.PLATFORM,c="mp-qq"===a,{openid:u,unionid:d,sessionKey:p}=await this._getQQApi()[c?"code2Session":"getOpenidByToken"]({code:e,accessToken:t});if(!u)return{code:10801,messageValues:{account:"qq openid"}};const l=function({clientPlatform:e}={}){switch(e){case"app":case"app-plus":return"app";case"mp-qq":return"mp";default:throw new Error("Unsupported qq platform")}}({clientPlatform:a}),f={dcloudAppid:this.context.APPID,openid:u,platform:"qq-"+l},m=require("uni-open-bridge-common");let h;c?(h={sessionKey:p},await m.setSessionKey(f,{session_key:p},2592e3)):(h={accessToken:t,accessTokenExpired:r},await m.setUserAccessToken(f,{access_token:t,access_token_expired:r},r?Math.floor((r-Date.now())/1e3):2592e3));const g=Qr.command,y=[{qq_openid:{[a]:u}}];d&&y.push({qq_unionid:d});let w=await P.where(g.or(...y)).get();if(w=this._getCurrentAppUser(w.data),w&&w.length>0){if("register"===s)return{code:10802,messageValues:{type:this.t("qq-account")}};if(1!==w.length)return{code:10005};const e=w[0],t={qq_openid:{[a]:u}};d&&(t.qq_unionid=d);const r=await this._loginExec(e,{needPermission:i,extraData:t});if(0!==r.code)return r;const{userInfo:n}=r;return{...r,openid:u,unionid:d,...h,mobileConfirmed:1===n.mobile_confirmed,emailConfirmed:1===n.email_confirmed}}{if("login"===s)return{code:10803,messageValues:{type:this.t("qq-account")}};const e={qq_openid:{[a]:u},qq_unionid:d};e.my_invite_code=n,e.role=o;const t=await this._registerExec(e);return 0!==t.code?t:{...t,openid:u,unionid:d,...h,mobileConfirmed:!1,emailConfirmed:!1}}},loginByUniverify:async function({openid:e,access_token:t,password:r,inviteCode:n,myInviteCode:i,type:o,needPermission:s,role:a}){const c=this._getConfig(),u=c&&c.service&&c.service.univerify;if(!u)throw new Error(this.t("uni-verify-config-required"));if(c.forceInviteCode&&!o)throw new Error(this.t("login-with-invite-type-required"));const d=await Xr.bind(this)({...u,openid:e,access_token:t});if(0!==d.code)return d;const p=String(d.phoneNumber);let l=await P.where({mobile:p,mobile_confirmed:1}).get();if(l=this._getCurrentAppUser(l.data),l&&l.length>0){if("register"===o)return{code:10601,messageValues:{type:this.t("mobile")}};if(1!==l.length)return{code:10005};const e=l[0],t=await this._loginExec(e,{needPermission:s});return 0!==t.code?t:{...t,mobile:p}}if("login"===o)return{code:10602,messageValues:{type:this.t("mobile")}};const f=Date.now(),m={mobile:p,my_invite_code:i,mobile_confirmed:1,role:a},h=r&&r.trim();if(h){const{passwordHash:e,version:t}=this.encryptPwd(h);m.password=e,t&&(m.password_secret_version=t)}if(n){let e=await P.where({my_invite_code:n}).get();if(1!==e.data.length)return{code:10203};e=e.data[0],m.inviter_uid=[e._id].concat(e.inviter_uid||[]),m.invite_time=f}else if(c.forceInviteCode)return{code:10203};m.my_invite_code=i;const g=await this._registerExec(m,{needPermission:s});return 0!==g.code?g:{...g,mobile:p}},loginByApple:async function({nickName:e,fullName:t,identityToken:r,myInviteCode:n,type:i,needPermission:o,role:s}){const a=this._getConfig(),c=a&&a.oauth&&a.oauth.apple,u=c&&c.bundleId;if(!u)throw new Error(this.t("config-param-require",{param:"(app || app-plus).apple.bundleId"}));if(!r)return{code:N,messageValues:{param:"identityToken"}};t=e||(t&&Object.keys(t).length>0?t.familyName+t.givenName:"");const{code:d,msg:p}=await Lr().verifyIdentityToken(r);if(0!==d)return{code:d,msg:p,messageValues:{account:this.t("apple-account")}};const{iss:l,sub:f,aud:m,email:h}=p;if("https://appleid.apple.com"!==l)return{code:10706,messageValues:{account:this.t("apple-account")}};if(!f)return{code:10701,messageValues:{account:this.t("apple-account")}};if(u!==m)return{code:10702,messageValues:{account:this.t("apple-account")}};const g=t||"User-"+(h?h.split("@")[0]:Math.random().toString(32).slice(2));let y=await P.where({apple_openid:f}).get();if(y=this._getCurrentAppUser(y.data),y&&y.length>0){if("register"===i)return{code:10703,messageValues:{type:this.t("apple-account")}};if(1!==y.length)return{code:10005};const e=y[0],t=await this._loginExec(e,{needPermission:o});return 0!==t.code?t:{...t,openid:f}}if("login"===i)return{code:10704,messageValues:{type:this.t("apple-account")}};const w={nickname:g,apple_openid:f,my_invite_code:n,role:s},v=await this._registerExec(w,{needPermission:o});return 0!==v.code?v:{...v,openid:f}},login:async function({username:e,password:t,queryField:r=[],needPermission:n}){const i=Yr.command,o=[];r&&r.length||(r=["username"]),r.length>1&&console.warn(this.t("query-field-warning"));const{usernameToLowerCase:s,emailToLowerCase:a,passwordErrorLimit:c,passwordErrorRetryTime:u}=this._getConfig(),d={email:{email_confirmed:1},mobile:{mobile_confirmed:1}},p={},l=e&&e.trim();if(!l)return{code:N,messageValues:{param:this.t("username")}};s&&(p.username=l.toLowerCase()),a&&(p.email=l.toLowerCase());const f=[];r.forEach(t=>{o.push({[t]:e,...d[t]});const r={field:t,value:e};"username"===t&&p.username!==e?(o.push({[t]:p.username,...d[t]}),r.fallbackValue=p.username):"email"===t&&p.email!==e&&(o.push({[t]:p.email,...d[t]}),r.fallbackValue=p.email),f.push(r)});let m=await P.where(i.or(...o)).get();m=this._getCurrentAppUser(m.data);const h=this.context.CLIENTIP,g=this._getMatchedUser(m,f);if(g.code)return g;const{userMatched:y}=g;let w=y.login_ip_limit||[];w=w.filter(e=>e.last_error_time>Date.now()-1e3*u);let v=w.find(e=>e.ip===h);if(v&&v.error_times>=c)return{code:10103};const _=t&&t.trim();if(!_)return{code:N,messageValues:{param:"密码"}};const b=this._checkPwd(y,_);if(0===b.code){const e=w.indexOf(v);e>-1&&w.splice(e,1);const t={login_ip_limit:w},{passwordHash:r,passwordVersion:i}=b;r&&i&&(t.password=r,t.password_secret_version=i);const o=await this._loginExec(y,{needPermission:n,extraData:t});return o.code,o}return v?(v.error_times++,v.last_error_time=Date.now()):(v={ip:h,error_times:1,last_error_time:Date.now()},w.push(v)),await P.doc(y._id).update({login_ip_limit:w}),{code:10102,msg:"密码错误"}},register:async function(e){const t=[],r=[{name:"username",desc:this.t("username")},{name:"email",desc:this.t("email"),extraCond:{email_confirmed:1}},{name:"mobile",desc:this.t("mobile"),extraCond:{mobile_confirmed:1}}],{usernameToLowerCase:n,emailToLowerCase:i}=this._getConfig();r.forEach(r=>{const o=r.name;let s=e[o]&&e[o].trim();s?(("username"===r.name&&n||"email"===r.name&&i)&&(s=s.toLowerCase()),e[o]=s,t.push({[o]:s,...r.extraCond})):delete e[o]});const{username:o,email:s,mobile:a,myInviteCode:c,needPermission:u,autoSetDcloudAppid:d=!0}=e;if("needPermission"in e&&delete e.needPermission,"autoSetDcloudAppid"in e&&delete e.autoSetDcloudAppid,0===t.length)return{code:20101,messageValues:{param:this.t("user-unique-param")}};const p=zr.command;let l=await P.where(p.or(...t)).get();if(l=this._getCurrentAppUser(l.data),l&&l.length>0){const t=l[0];if(t.status===F)return{code:10006};for(let n=0;n<r.length;n++){const i=r[n];let o=!0;if(i.extraCond&&(o=Object.keys(i.extraCond).every(e=>t[e]===i.extraCond[e])),t[i.name]===e[i.name]&&o)return{code:20102,messageValues:{type:i.desc}}}}const f=e.password&&e.password.trim();if(!f)return{code:N,messageValues:{param:this.t("password")}};const{passwordHash:m,version:h}=this.encryptPwd(f);e.password=m,h&&(e.password_secret_version=h),e.my_invite_code=c,delete e.myInviteCode;const g=await this._registerExec(e,{needPermission:u,autoSetDcloudAppid:d});return 0!==g.code?g:{...g,username:o,email:s,mobile:a}},logout:async function(e){const t=await this.checkToken(e);if(t.code)return t;const r=Wr.command;return await P.doc(t.uid).update({token:r.pull(e)}),{code:0,msg:""}},getRoleByUid:async function({uid:e}){if(!e)return{code:N,messageValues:{param:this.t("user-id")}};const t=await P.doc(e).get();return 0===t.data.length?{code:L}:{code:0,msg:"",role:t.data[0].role||[]}},getPermissionByRole:async function({roleID:e}){if(!e)return{code:N,messageValues:{param:"roleID"}};if("admin"===e){return{code:0,msg:"",permission:(await D.limit(1e3).get()).data.map(e=>e.permission_id)}}const t=await j.where({role_id:e}).get();return 0===t.data.length?{code:V}:{code:0,msg:"",permission:t.data[0].permission||[]}},getPermissionByUid:async function({uid:e}={}){const t=await P.aggregate().match({_id:e}).project({role:!0}).unwind("$role").lookup({from:"uni-id-roles",localField:"role",foreignField:"role_id",as:"roleDetail"}).unwind("$roleDetail").replaceRoot({newRoot:"$roleDetail"}).end(),r=[],n=[];return t.data.forEach(e=>{n.push(e.role_id),r.push(...e.permission)}),{code:0,msg:"",role:n,permission:A(r)}},bindRole:async function({uid:e,roleList:t,reset:r=!1}){const n={};return"string"==typeof t&&(t=[t]),n.role=r?t:Jr.push(t),await P.doc(e).update(n),{code:0,msg:""}},bindPermission:async function({roleID:e,permissionList:t,reset:r=!1}){const n={};return"string"==typeof t&&(t=[t]),n.permission=r?t:Jr.push(t),await j.where({role_id:e}).update(n),{code:0,msg:""}},unbindRole:async function({uid:e,roleList:t}){return"string"==typeof t&&(t=[t]),await P.doc(e).update({role:Jr.pull(Jr.in(t))}),{code:0,msg:""}},unbindPermission:async function({roleID:e,permissionList:t}){return"string"==typeof t&&(t=[t]),await j.where({role_id:e}).update({permission:Jr.pull(Jr.in(t))}),{code:0,msg:""}},addRole:async function({roleID:e,roleName:t,comment:r,permission:n=[]}){return e?"admin"===e?{code:U,messageValues:{param:"roleID",reason:this.t("add-role-admin-is-not-allowed")}}:(await j.add({role_id:e,role_name:t,comment:r,permission:n,create_date:Date.now()}),{code:0,msg:""}):{code:N,messageValues:{param:this.t("role-id")}}},addPermission:async function({permissionID:e,permissionName:t,comment:r}){return e?(await D.add({permission_id:e,permission_name:t,comment:r,create_date:Date.now()}),{code:0,msg:""}):{code:N,messageValues:{param:this.t("permission-id")}}},getRoleList:async function({limit:e=20,offset:t=0,needTotal:r=!0}){const n={code:0,msg:"",roleList:(await j.skip(t).limit(e).get()).data};if(r){const{total:e}=await j.where({_id:Jr.exists(!0)}).count();n.total=e}return n},getRoleInfo:async function(e){const t=await j.where({role_id:e}).get();return 0===t.data.length?{code:V}:{code:0,...t.data[0]}},updateRole:async function({roleID:e,roleName:t,comment:r,permission:n}){return e?(await j.where({role_id:e}).update({role_name:t,comment:r,permission:n}),{code:0,msg:""}):{code:N,messageValues:{param:this.t("role-id")}}},deleteRole:async function({roleID:e}){const t=m(e);if("string"===t)e=[e];else if("array"!==t)throw new Error("typeof roleID must be array or string");return await j.where({role_id:Jr.in(e)}).remove(),await P.where({role:Jr.elemMatch(Jr.in(e))}).update({role:Jr.pullAll(e)}),{code:0,msg:""}},getPermissionList:async function({limit:e=20,offset:t=0,needTotal:r=!0}){const n={code:0,msg:"",permissionList:(await D.skip(t).limit(e).get()).data};if(r){const{total:e}=await D.where({_id:Jr.exists(!0)}).count();n.total=e}return n},getPermissionInfo:async function(e){const t=await D.where({permission_id:e}).get();return 0===t.data.length?{code:N,messageValues:{param:this.t("permission-id")}}:{code:0,...t.data[0]}},updatePermission:async function({permissionID:e,permissionName:t,comment:r}){return e?(await D.where({permission_id:e}).update({permission_name:t,comment:r}),{code:0,msg:""}):{code:N,messageValues:{param:this.t("permission-id")}}},deletePermission:async function({permissionID:e}){const t=m(e);if("string"===t)e=[e];else if("array"!==t)throw new Error("typeof permissionID must be array or string");return await D.where({permission_id:Jr.in(e)}).remove(),await j.where({permission:Jr.elemMatch(Jr.in(e))}).update({permission:Jr.pullAll(e)}),{code:0,msg:""}},bindAlipay:async function({uid:e,code:t,platform:r}){const n=r||this.context.PLATFORM,{openid:i}=await this._getAlipayApi({platform:n}).code2Session(t);if(!i)return{code:60401,messageValues:{account:this.t("alipay-account")}};let o=await P.where({ali_openid:i}).get();return o=this._getCurrentAppUser(o.data),o&&o.length>0?{code:60402,messageValues:{type:this.t("alipay-account")}}:(await P.doc(e).update({ali_openid:i}),{code:0,openid:i,msg:""})},bindEmail:async function(e){let{uid:t,email:r,code:n}=e||{};if(r=r&&r.trim(),!r)return{code:N,messageValues:{param:this.t("email")}};if(!n)return{code:N,messageValues:{param:this.t("verify-code")}};const{emailToLowerCase:i}=this._getConfig();i&&(r=r.toLowerCase());let o=await P.where({email:r,email_confirmed:1}).get();if(o=this._getCurrentAppUser(o.data),o&&o.length>0)return{code:60201,messageValues:{type:this.t("email")}};const s=await this.verifyCode({email:r,code:n,type:"bind"});return 0!==s.code?s:(await P.doc(t).update({email:r,email_confirmed:1}),{code:0,msg:"",email:r})},bindMobile:async function(e){let{uid:t,mobile:r,code:n,openid:i,access_token:o,type:s="sms"}=e||{};if("univerify"===s){const e=this._getConfig(),t=e&&e.service&&e.service.univerify;if(!t)throw new Error("请在config.json中配置service.univerify下一键登录相关参数");const n=await Xr.bind(this)({...t,openid:i,access_token:o});if(0!==n.code)return n;r=""+n.phoneNumber}let a=await P.where({mobile:r,mobile_confirmed:1}).get();if(a=this._getCurrentAppUser(a.data),a&&a.length>0)return{code:60101,messageValues:{type:"手机号"}};if("sms"===s&&"code"in e){if(!r)return{code:N,messageValues:{param:this.t("mobile")}};if(!n)return{code:N,messageValues:{param:this.t("verify-code")}};const e=await this.verifyCode({mobile:r,code:n,type:"bind"});if(0!==e.code)return e}return await P.doc(t).update({mobile:r,mobile_confirmed:1}),{code:0,msg:"",mobile:r}},bindWeixin:async function({uid:e,code:t,platform:r}){const n=r||this.context.PLATFORM,i="mp-weixin"===n,{openid:o,unionid:s,sessionKey:a,accessToken:c,refreshToken:u,expired:d}=await this._getWeixinApi({platform:n})[i?"code2Session":"getOauthAccessToken"](t);if(!o)return{code:60301,messageValues:{account:"微信openid"}};const p=Zr.command,l=[{wx_openid:{[n]:o}}];s&&l.push({wx_unionid:s});let f=await P.where(p.or(...l)).get();if(f=this._getCurrentAppUser(f.data),f&&f.length>0)return{code:60302,messageValues:{type:this.t("wechat-account")}};const m={wx_openid:{[n]:o}};let h;return s&&(m.wx_unionid=s),await P.doc(e).update(m),h=i?{sessionKey:a}:{accessToken:c,refreshToken:u,accessTokenExpired:d},{code:0,msg:"",openid:o,unionid:s,...h}},bindQQ:async function({uid:e,code:t,accessToken:r,platform:n}={}){const i=n||this.context.PLATFORM,o="mp-qq"===i,{openid:s,unionid:a,sessionKey:c}=await this._getQQApi()[o?"code2Session":"getOpenidByToken"]({code:t,accessToken:r});if(!s)return{code:60501,messageValues:{account:"qq openid"}};const u=en.command,d=[{qq_openid:{[i]:s}}];a&&d.push({qq_unionid:a});let p=await P.where(u.or(...d)).get();if(p=this._getCurrentAppUser(p.data),p&&p.length>0)return{code:60502,messageValues:{type:this.t("qq-account")}};const l={qq_openid:{[i]:s}};return a&&(l.qq_unionid=a),await P.doc(e).update(l),{code:0,msg:"",openid:s,unionid:a,...{accessToken:r,sessionKey:c}}},unbindAlipay:async function(e){const t=tn.command,r=await P.doc(e).update({ali_openid:t.remove()});return E("upRes:",r),1===r.updated?{code:0,msg:""}:{code:70401}},unbindEmail:async function(e){let{uid:t,email:r,code:n}=e||{};if(r=r&&r.trim(),!t||!r)return{code:N,messageValues:{param:t?this.t("email"):this.t("user-id")}};const{emailToLowerCase:i}=this._getConfig();if("code"in e){const e=await this.verifyCode({email:r,code:n,type:"unbind"});if(0!==e.code)return e}const o=rn.command;let s={_id:t,email:r};if(i){const e=r.toLowerCase();e!==r&&(s=o.or(s,{_id:t,email:e}))}return 1===(await P.where(s).update({email:o.remove(),email_confirmed:o.remove()})).updated?{code:0,msg:""}:{code:70201}},unbindMobile:async function(e){const{uid:t,mobile:r,code:n}=e||{};if("code"in e){const e=await this.verifyCode({mobile:r,code:n,type:"unbind"});if(0!==e.code)return e}const i=nn.command;return 1===(await P.where({_id:t,mobile:r}).update({mobile:i.remove(),mobile_confirmed:i.remove()})).updated?{code:0,msg:""}:{code:70101}},unbindWeixin:async function(e){const t=on.command,r=await P.doc(e).update({wx_openid:t.remove(),wx_unionid:t.remove()});return E("upRes:",r),1===r.updated?{code:0,msg:""}:{code:70301}},unbindQQ:async function(e){const t=sn.command,r=await P.doc(e).update({qq_openid:t.remove(),qq_unionid:t.remove()});return E("upRes:",r),1===r.updated?{code:0,msg:""}:{code:70501}},getSupportedLoginType:function({appid:e,platform:t}={}){if(!e||!t)throw new Error("Parameter appid and platform is required");const r=this._getConfig({appid:e,platform:t}),n=["username-password","mobile-password","email-password"];for(const e in an)an[e](r)&&n.push(e);return{supportedLoginType:n}},code2SessionAlipay:async function(e){let t=e;"string"==typeof e&&(t={code:e});try{const e=t.platform||this.context.PLATFORM,r=await this._getAlipayApi({platform:e}).code2Session(t.code);return r.openid?{code:0,msg:"",...r}:{code:80701,messageValues:{account:this.t("alipay-account")}}}catch(e){return console.error(e),{code:80702,messageValues:{account:this.t("alipay-account")}}}},code2SessionWeixin:async function(e){let t=e;"string"==typeof e&&(t={code:e});try{const e=t.platform||this.context.PLATFORM,r=await this._getWeixinApi({platform:e})["mp-weixin"===e?"code2Session":"getOauthAccessToken"](t.code);return r.openid?{code:0,msg:"",...r}:{code:80601,messageValues:{account:"微信openid"}}}catch(e){return console.error(e),{code:80602,messageValues:{account:"微信openid"}}}},verifyAppleIdentityToken:async function({identityToken:e,platform:t}){const r=t||this.context.PLATFORM,{code:n,msg:i}=await Lr({clientType:r}).verifyIdentityToken(e);return 0!==n?{code:n,msg:i}:{code:n,msg:"验证通过",...i}},wxBizDataCrypt:async function({code:e,sessionKey:r,encryptedData:n,iv:i}){if(!n)return{code:N,messageValues:{param:"encryptedData"}};if(!i)return{code:N,messageValues:{param:"iv"}};if(!e&&!r)return{code:N,messageValues:{param:"sessionKey"}};const o=this._getWeixinApi();if(!r){const t=await o.code2Session(e);if(!t.sessionKey)return{code:80801};r=t.sessionKey}r=Buffer.from(r,"base64"),n=Buffer.from(n,"base64"),i=Buffer.from(i,"base64");try{var s=t.createDecipheriv("aes-128-cbc",r,i);s.setAutoPadding(!0);var a=s.update(n,"binary","utf8");a+=s.final("utf8"),a=JSON.parse(a)}catch(e){return console.error(e),{code:80802}}return a.watermark.appid!==o.options.appId?{code:80803}:{code:0,msg:"",...a}},getWeixinUserInfo:async function({accessToken:e,openid:t}={}){const r=this.context.PLATFORM;if("app"!==r&&"app-plus"!==r)throw new Error(this.t("limit-client-platform"));try{return{code:0,msg:"",...await this._getWeixinApi().getUserInfo({accessToken:e,openid:t})}}catch(e){return console.error(e),{code:80901}}},encryptPwd:function(e,{value:r,version:n}={}){if(!(e=e&&e.trim()))throw new Error(this.t("param-required",{param:this.t("password")}));if(!r){const e=this._getConfig(),{passwordSecret:t}=e;if("array"===m(t)){const e=t.sort((e,t)=>e.version-t.version);r=e[e.length-1].value,n=e[e.length-1].version}else r=t}if(!r)throw new Error(this.t("param-error",{param:"passwordSecret",reason:"invalid passwordSecret"}));const i=t.createHmac("sha1",r.toString("ascii"));return i.update(e),{passwordHash:i.digest("hex"),version:n}},checkToken:async function(e,{needPermission:t,needUserInfo:r=!0}={}){const n=this._getConfig(),i=this._verifyToken(e);if(i.code)return i;const{uid:o,needPermission:s,role:a,permission:c,exp:u,iat:d,...p}=i,l=a&&c;t=void 0===t?s:t;const f=n.removePermissionAndRoleFromToken||!l||r,m=!n.removePermissionAndRoleFromToken&&!l||n.removePermissionAndRoleFromToken&&l||n.tokenExpiresThreshold&&u-Date.now()/1e3<n.tokenExpiresThreshold;let h={};if(f||m){const t=await P.doc(o).get();if(!t.data||0===t.data.length||!t.data[0].token)return{code:30202};if(h=t.data[0],h.status===B)return{code:10001};if(h.status===F)return{code:10006};let r=h.token;if(r?"string"==typeof r&&(r=[r]):r=[],-1===r.indexOf(e))return{code:30202}}const g={code:0,uid:o,...p};let y,w;if(l&&(g.role=a,g.permission=c),r&&(g.userInfo=h),(!l&&t||m)&&(y=g.role=h.role||[],w=0===y.length||y.includes("admin")?g.permission=[]:g.permission=await this._getPermissionListByRoleList(g.role),t&&(g.role=y,g.permission=w)),m){let e;e=n.removePermissionAndRoleFromToken?await this.createToken({uid:o,needPermission:s}):await this.createToken({uid:o,role:y,permission:w});const t=h.token;return await this._updateToken({uid:o,tokenList:t,addToken:[e.token]}),{...g,...e}}return g},createToken:function({uid:e,needPermission:t,role:r,permission:n}){if(!e)return{code:30101,messageValues:{param:this.t("user-id")}};const i={uid:e,needPermission:t,role:r,permission:n},o=this._getConfig();if(!this.interceptorMap.has("customToken")){const e={...i};return this._createTokenInternal({signContent:e,config:o})}const s=this.interceptorMap.get("customToken");if("function"!=typeof s)throw new Error(this.t("type-function-required","customToken"));const a=s(i);return a instanceof Promise?a.then(e=>this._createTokenInternal({signContent:e,config:o})):this._createTokenInternal({signContent:a,config:o})},_updateToken:async function({uid:e,tokenList:t,removeToken:r=[],addToken:n=[]}={}){if(!t){const r=await P.doc(e).get(),n=r.data&&r.data[0];t=n&&n.token||[]}"string"==typeof t&&(t=[t]);const i=this._getExpiredToken(t);(t=t.filter(e=>-1===i.indexOf(e))).push(...n);for(let e=0;e<r.length;e++){const n=t.indexOf(r[e]);t.splice(n,1)}await P.doc(e).update({token:t,last_login_date:Date.now(),last_login_ip:this.context.CLIENTIP})},refreshToken:async function({token:e}={}){const t=this._getConfig(),r=this._verifyToken(e);if(r.code)return r;const{uid:n,needPermission:i}=r;let o;if(t.removePermissionAndRoleFromToken)o=await this.createToken({uid:n,needPermission:i});else{const{role:e,permission:t}=await this.getPermissionByUid({uid:n});o=await this.createToken({uid:n,role:e,permission:t})}return await this._updateToken({uid:n,addToken:[o.token],removeToken:[e]}),o},_checkPwd:function(e,t){if(!t)return{code:1};const{password:r,password_secret_version:n}=e,i=this._getConfig(),{passwordSecret:o}=i,s=m(o);if("string"===s){const{passwordHash:e}=this.encryptPwd(t,{value:o});return e===r?{code:0,message:""}:{code:2}}if("array"!==s)throw new Error(this.t("password-secret-type-error"));const a=o.sort((e,t)=>e.version-t.version);let c;if(c=n?a.find(e=>e.version===n):a[0],!c)return{code:3};const u=a[a.length-1],{passwordHash:d}=this.encryptPwd(t,c);if(d===r){const e={code:0};if(c!==u){const{passwordHash:r,version:n}=this.encryptPwd(t,u);e.passwordHash=r,e.passwordVersion=n}return e}return{code:4,message:""}},_verifyToken:function(e){const t=this._getConfig();let r;try{r=Pr(e,t.tokenSecret)}catch(e){return"TokenExpiredError"===e.name?{code:30203,err:e}:{code:30204,err:e}}return t.bindTokenToDevice&&r.clientId&&r.clientId!==this._getClientUaHash()?{code:30201}:{code:0,message:"",...r}},_getExpiredToken:function(e){const t=this._getConfig(),r=[];return e.forEach(e=>{try{Pr(e,t.tokenSecret)}catch(t){r.push(e)}}),r},_getPermissionListByRoleList:async function(e){if(!Array.isArray(e))return[];if(0===e.length)return[];if(e.includes("admin")){return(await D.limit(500).get()).data.map(e=>e.permission_id)}const t=await j.where({role_id:Kr.in(e)}).get(),r=[];return t.data.forEach(e=>{Array.prototype.push.apply(r,e.permission)}),A(r)},_getClientUaHash:function(){const e=t.createHash("md5"),r=/MicroMessenger/i.test(this.context.CLIENTUA)?this.context.CLIENTUA.replace(/(MicroMessenger\S+).*/i,"$1"):this.context.CLIENTUA;return e.update(r),e.digest("hex")},_createTokenInternal:function({signContent:e,config:t}){if(t.tokenExpiresIn&&t.tokenExpiresThreshold&&t.tokenExpiresIn<=t.tokenExpiresThreshold)throw new Error(this.t("token-expires-config-warning"));return"object"===m(e)&&e.uid?(t.bindTokenToDevice&&(e.clientId=this._getClientUaHash()),{token:Rr(e,t.tokenSecret,{expiresIn:t.tokenExpiresIn}),tokenExpired:Date.now()+1e3*t.tokenExpiresIn}):{code:30101,messageValues:{param:this.t("user-id")}}},setVerifyCode:async function({mobile:e,email:t,code:r,expiresIn:n,type:i}){if(t=t&&t.trim(),e=e&&e.trim(),t){const{emailToLowerCase:e}=this._getConfig();e&&(t=t.toLowerCase())}if(!e&&!t)return{code:50101,messageValues:{param:"手机号或邮箱"}};if(e&&t)return{code:50102,messageValues:{param:"参数",reason:"手机号和邮箱不可同时存在"}};r||(r=C()),n||(n=180);const o=Date.now(),s={mobile:e,email:t,type:i,code:r,state:0,ip:this.context.CLIENTIP,created_at:o,expired_at:o+1e3*n};return await R.add(s),{code:0,mobile:e,email:t}},verifyCode:async function({mobile:e,email:t,code:r,type:n}){if(t=t&&t.trim(),e=e&&e.trim(),t){const{emailToLowerCase:e}=this._getConfig();e&&(t=t.toLowerCase())}if(!e&&!t)return{code:50201,messageValues:{param:"手机号或邮箱"}};if(e&&t)return{code:50203,messageValues:{param:"参数",reason:"手机号和邮箱不可同时存在"}};if(!r)return{code:50202,messageValues:{type:this.t(e?"sms":"email")}};const i=cn.command,o=Date.now(),s={mobile:e,email:t,type:n,code:r,state:0,expired_at:i.gt(o)},a=await R.where(s).orderBy("created_at","desc").limit(1).get();if(a&&a.data&&a.data.length>0){const e=a.data[0];return await R.doc(e._id).update({state:1}),{code:0,msg:"验证通过"}}return{code:50202,messageValues:{type:this.t(e?"sms":"email")}}},sendSmsCode:async function({mobile:e,code:t,type:r,templateId:n}){if(!e)return{code:N,messageValues:{param:this.t("mobile")}};if(t||(t=C()),!r)return{code:N,messageValues:{param:this.t("verify-code-type")}};const i=this._getConfig();let o=i&&i.service&&i.service.sms;if(!o)throw new Error(this.t("config-param-required",{param:"service.sms"}));o=Object.assign({codeExpiresIn:300},o);const{name:s,smsKey:a,smsSecret:c,codeExpiresIn:u}=o;let d;switch(r){case"login":d=this.t("login");break;default:d=this.t("verify-mobile")}try{const i={name:s,code:t,action:d,expMinute:""+Math.round(u/60)};s&&(i.name=s),await uniCloud.sendSms({smsKey:a,smsSecret:c,phone:e,templateId:n||"uniID_code",data:i});const o=await this.setVerifyCode({mobile:e,code:t,expiresIn:u,type:r});return o.code>=0?o:{code:0,msg:""}}catch(e){return console.error(e),{code:50301}}}});let dn;try{dn=require("uni-config-center")}catch(e){throw new Error("Plugin[uni-config-center] was not found")}class pn{constructor({context:e,clientInfo:t,config:r}={}){const n=dn({pluginId:"uni-id"});this.pluginConfig=n,this.config=r||this._getConfigContent(),this._configCache={},Object.defineProperty(this,"context",{get(){let r;r=t?{OS:t.os,CLIENTIP:t.clientIP,CLIENTUA:t.userAgent,PLATFORM:t.platform,APPID:t.appId,LOCALE:t.locale,DEVICEID:t.deviceId}:Object.assign({},e||global.__ctx__||{});const n=["CLIENTIP","PLATFORM","APPID","LOCALE"];for(let e=0;e<n.length;e++){const t=n[e];void 0===r[t]&&console.warn(i.t("context-required",{key:t}))}const o=r.APPID,s=r.PLATFORM,a=this._getAppConfig(this.config,o);if(!a)throw new Error(`Config for current app (${o}) was not found, please check your config file or client appId`);if("app-android"===s||"app-ios"===s?r.PLATFORM=a.preferedAppPlatform||"app":"app"===s||"app-plus"===s?r.PLATFORM=a.preferedAppPlatform||s:"web"!==s&&"h5"!==s||(r.PLATFORM=a.preferedWebPlatform||s),"app"===r.PLATFORM&&a["app-plus"]||"app-plus"===r.PLATFORM&&a.app)throw new Error(`Client platform is ${r.PLATFORM}, but ${"app"===r.PLATFORM?"app-plus":"app"} was found in config. Please refer to: https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=prefered-app-platform`);if("web"===r.PLATFORM&&a.h5||"h5"===r.PLATFORM&&a.web)throw new Error(`Client platform is ${r.PLATFORM}, but ${"web"===r.PLATFORM?"h5":"web"} was found in config. Please refer to: https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=prefered-web-platform`);return r}}),this.interceptorMap=new Map,n&&n.hasFile("custom-token.js")&&this.setInterceptor("customToken",require(n.resolve("custom-token.js")));let i,o=k;if(n&&n.hasFile("lang/index.js")){const e=n.requireFile("lang/index.js");o=function(e,t){const r=Object.keys(e);r.push(...Object.keys(t));const n={};for(let i=0;i<r.length;i++){const o=r[i];n[o]=Object.assign({},e[o],t[o])}return n}(k,e)}if(!uniCloud.initI18n)throw new Error("The HBuilderX version is too old, please upgrade to the latest version of HBuilderX");i=uniCloud.initI18n({locale:"en",fallbackLocale:"zh-Hans",messages:o}),Object.defineProperty(this,"t",{get(){return i.setLocale(this.context.LOCALE||"zh-Hans"),i.t.bind(i)}})}get dev(){return console.warn(this.t("dev-warning")),{getConfig:this._getConfig.bind(this)}}_getAppConfig(e,t){return Array.isArray(e)?e.find(e=>e.dcloudAppid===t)||e.find(e=>e.isDefaultConfig):e}_parseConfigContent(e){return Array.isArray(e)?e:e[0]?Object.values(e):e}_getConfigContent(){if(this.pluginConfig&&this.pluginConfig.hasFile("config.json")){let e;try{e=this.pluginConfig.config()}catch(e){throw new Error("Invalid uni-id config file\n"+e.message)}return this._parseConfigContent(e)}{let e;try{e=require("./config.json")}catch(e){if("MODULE_NOT_FOUND"===e.code||"ENOENT"===e.code)throw new Error("uni-id config file[uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json] not found");throw e}return this._parseConfigContent(e)}}init(){throw new Error("uniID.init has been deprecated, use uniID.createInstance instead")}setInterceptor(e,t){this.interceptorMap.set(e,t)}_getConfig({appid:e,platform:t}={}){const r=`${e=e||this.context.APPID}_${t=t||this.context.PLATFORM}`;if(this._configCache[r])return this._configCache[r];if(!(this.config&&0!==Object.keys(this.config).length))throw new Error(this.t("config-file-not-found"));const n=this._getAppConfig(this.config,e);"app"!==t&&"app-plus"!==t||(t=n.preferedAppPlatform||t),"web"!==t&&"h5"!==t||(t=n.preferedWebPlatform||t);const i=Object.assign(n,n[t])||{},o=Object.assign({bindTokenToDevice:!1,tokenExpiresIn:7200,tokenExpiresThreshold:1200,passwordErrorLimit:6,passwordErrorRetryTime:3600,usernameToLowerCase:!0,emailToLowerCase:!0},i);return["passwordSecret","tokenSecret","tokenExpiresIn","passwordErrorLimit","passwordErrorRetryTime"].forEach(e=>{if(!o||!o[e])throw new Error(this.t("config-param-required",{param:e}))}),this._configCache[r]=o,o}}for(const e in un)pn.prototype[e]=un[e];function ln(e){const t=new pn(e);return new Proxy(t,{get(e,t){if(t in e&&0!==t.indexOf("_")){if("function"==typeof e[t])return(r=e[t],function(){const e=r.apply(this,arguments);return f(e)?e.then(e=>(S.bind(this)(e),e)):(S.bind(this)(e),e)}).bind(e);if("context"!==t&&"config"!==t)return e[t]}var r}})}pn.prototype.createInstance=ln;var fn=ln();module.exports=fn;
diff --git a/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json b/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json
index 2fc9ff6d..544f2360 100644
--- a/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json
+++ b/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json
@@ -1,16 +1,20 @@
 {
-  "name": "uni-id",
-  "version": "3.3.30",
-  "description": "uni-id for uniCloud",
-  "main": "index.js",
-  "homepage": "https://uniapp.dcloud.io/uniCloud/uni-id",
-  "repository": {
-    "type": "git",
-    "url": "git+https://gitee.com/dcloud/uni-id.git"
-  },
-  "author": "",
-  "license": "Apache-2.0",
-  "dependencies": {
-    "uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
-  }
+    "name": "uni-id",
+    "version": "3.3.32",
+    "description": "uni-id for uniCloud",
+    "main": "index.js",
+    "homepage": "https:\/\/uniapp.dcloud.io\/uniCloud\/uni-id",
+    "repository": {
+        "type": "git",
+        "url": "git+https:\/\/gitee.com\/dcloud\/uni-id.git"
+    },
+    "author": "",
+    "license": "Apache-2.0",
+    "dependencies": {
+        "uni-config-center": "file:..\/..\/..\/..\/..\/uni-config-center\/uniCloud\/cloudfunctions\/common\/uni-config-center"
+    },
+    "origin-plugin-dev-name": "uni-id",
+    "origin-plugin-version": "3.3.33",
+    "plugin-dev-name": "uni-id",
+    "plugin-version": "3.3.33"
 }
\ No newline at end of file
diff --git a/uni_modules/uni-list/changelog.md b/uni_modules/uni-list/changelog.md
index 8254a185..ddf45a47 100644
--- a/uni_modules/uni-list/changelog.md
+++ b/uni_modules/uni-list/changelog.md
@@ -1,3 +1,5 @@
+## 1.2.15（2025-01-08）
+- 修复 示例中过期图片地址
 ## 1.2.14（2023-04-14）
 - 优化 uni-list-chat 具名插槽`header` 非app端套一层元素，方便使用时通过外层元素定位实现样式修改
 ## 1.2.13（2023-03-03）
diff --git a/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue b/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
index c25779e4..2322373b 100644
--- a/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
+++ b/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
@@ -167,7 +167,7 @@
 					return {
 						type: '',
 						color: '#000000',
-						size: 20,
+						size: 20,
 						customPrefix: ''
 					};
 				}
@@ -184,7 +184,7 @@
 						backgroundColor: '#FFFFFF'
 					}
 				}
-			},
+			},
 			keepScrollPosition: {
 				type: Boolean,
 				default: false
@@ -192,34 +192,34 @@
 		},
 		watch: {
 			'customStyle.padding': {
-				handler(padding) {
-					if(typeof padding == 'number'){
-						padding += ''
-					}
+				handler(padding) {
+					if(typeof padding == 'number'){
+						padding += ''
+					}
 					let paddingArr = padding.split(' ')
 					if (paddingArr.length === 1) {
-						const allPadding = paddingArr[0]
-						this.padding = {
-							"top": allPadding,
-							"right": allPadding,
-							"bottom": allPadding,
-							"left": allPadding
+						const allPadding = paddingArr[0]
+						this.padding = {
+							"top": allPadding,
+							"right": allPadding,
+							"bottom": allPadding,
+							"left": allPadding
 						}
 					} else if (paddingArr.length === 2) {
-						const [verticalPadding, horizontalPadding] = paddingArr;
-						this.padding = {
-							"top": verticalPadding,
-							"right": horizontalPadding,
-							"bottom": verticalPadding,
-							"left": horizontalPadding
+						const [verticalPadding, horizontalPadding] = paddingArr;
+						this.padding = {
+							"top": verticalPadding,
+							"right": horizontalPadding,
+							"bottom": verticalPadding,
+							"left": horizontalPadding
 						}
 					} else if (paddingArr.length === 4) {
-							const [topPadding, rightPadding, bottomPadding, leftPadding] = paddingArr;
-							this.padding = {
-								"top": topPadding,
-								"right": rightPadding,
-								"bottom": bottomPadding,
-								"left": leftPadding
+							const [topPadding, rightPadding, bottomPadding, leftPadding] = paddingArr;
+							this.padding = {
+								"top": topPadding,
+								"right": rightPadding,
+								"bottom": bottomPadding,
+								"left": leftPadding
 							}
 					}
 				},
@@ -352,7 +352,7 @@
 	}
 
 	.uni-list-item--hover {
-		background-color: $uni-bg-color-hover !important;
+		background-color: $uni-bg-color-hover;
 	}
 
 	.uni-list-item__container {
diff --git a/uni_modules/uni-list/package.json b/uni_modules/uni-list/package.json
index 8350efce..5ebe1569 100644
--- a/uni_modules/uni-list/package.json
+++ b/uni_modules/uni-list/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-list",
   "displayName": "uni-list 列表",
-  "version": "1.2.14",
+  "version": "1.2.15",
   "description": "List 组件 ，帮助使用者快速构建列表。",
   "keywords": [
     "",
@@ -47,12 +47,15 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
-          "app-vue": "y",
-          "app-nvue": "y"
+            "app-vue": "y",
+            "app-nvue": "y",
+            "app-harmony": "u",
+            "app-uvue": "u"
         },
         "H5-mobile": {
           "Safari": "y",
diff --git a/uni_modules/uni-list/readme.md b/uni_modules/uni-list/readme.md
index 32c28654..ae499e66 100644
--- a/uni_modules/uni-list/readme.md
+++ b/uni_modules/uni-list/readme.md
@@ -20,304 +20,8 @@ uni-list-item有很多风格，uni-list-item组件通过内置的属性，满足
 
 uni-list不包含下拉刷新和上拉翻页。上拉翻页另见组件：[uni-load-more](https://ext.dcloud.net.cn/plugin?id=29)
 
-
-### 安装方式
-
-本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范，`HBuilderX 2.5.5`起，只需将本组件导入项目，在页面`template`中即可直接使用，无需在页面中`import`和注册`components`。
-
-如需通过`npm`方式使用`uni-ui`组件，另见文档：[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
-
-> **注意事项**
-> 为了避免错误使用，给大家带来不好的开发体验，请在使用组件前仔细阅读下面的注意事项，可以帮你避免一些错误。
-> - 组件需要依赖 `sass` 插件 ，请自行手动安装
-> - 组件内部依赖 `'uni-icons'` 、`uni-badge` 组件
-> - `uni-list` 和 `uni-list-item` 需要配套使用，暂不支持单独使用 `uni-list-item`
-> - 只有开启点击反馈后，会有点击选中效果
-> - 使用插槽时，可以完全自定义内容
-> - note 、rightText 属性暂时没做限制，不支持文字溢出隐藏，使用时应该控制长度显示或通过默认插槽自行扩展
-> - 支付宝小程序平台需要在支付宝小程序开发者工具里开启 component2 编译模式，开启方式： 详情 --> 项目配置 --> 启用 component2 编译
-> - 如果需要修改 `switch`、`badge` 样式，请使用插槽自定义
-> - 在 `HBuilderX` 低版本中，可能会出现组件显示 `undefined` 的问题，请升级最新的 `HBuilderX` 或者 `cli`
-> - 如使用过程中有任何问题，或者您对uni-ui有一些好的建议，欢迎加入 uni-ui 交流群：871950839
- 
-
-### 基本用法 
-
-- 设置 `title` 属性，可以显示列表标题
-- 设置 `disabled` 属性，可以禁用当前项
-
-```html
-<uni-list>
-	<uni-list-item  title="列表文字" ></uni-list-item>
-	<uni-list-item :disabled="true" title="列表禁用状态" ></uni-list-item>
-</uni-list>
-			 
-```
-
-### 多行内容显示
-
-- 设置 `note` 属性 ，可以在第二行显示描述文本信息
-
-```html
-<uni-list>
-	<uni-list-item title="列表文字" note="列表描述信息"></uni-list-item>
-	<uni-list-item :disabled="true" title="列表文字" note="列表禁用状态"></uni-list-item>
-</uni-list>
-
-```
-
-### 右侧显示角标、switch
-
-- 设置 `show-badge` 属性 ，可以显示角标内容
-- 设置 `show-switch` 属性，可以显示 switch 开关
-
-```html
-<uni-list>
-	<uni-list-item  title="列表右侧显示角标" :show-badge="true" badge-text="12" ></uni-list-item>
-	<uni-list-item title="列表右侧显示 switch"  :show-switch="true"  @switchChange="switchChange" ></uni-list-item>
-</uni-list>
-
-```
-
-### 左侧显示略缩图、图标  
-
-- 设置 `thumb` 属性 ，可以在列表左侧显示略缩图
-- 设置 `show-extra-icon` 属性，并指定 `extra-icon` 可以在左侧显示图标
-
-```html
- <uni-list>
- 	<uni-list-item title="列表左侧带略缩图" note="列表描述信息" thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"
- 	 thumb-size="lg" rightText="右侧文字"></uni-list-item>
- 	<uni-list-item :show-extra-icon="true" :extra-icon="extraIcon1" title="列表左侧带扩展图标" ></uni-list-item>
-</uni-list>
-```
-
-### 开启点击反馈和右侧箭头
-- 设置 `clickable` 为 `true` ，则表示这是一个可点击的列表，会默认给一个点击效果，并可以监听 `click` 事件
-- 设置 `link` 属性，会自动开启点击反馈，并给列表右侧添加一个箭头
-- 设置 `to` 属性，可以跳转页面，`link` 的值表示跳转方式，如果不指定，默认为 `navigateTo`
-
-```html
-
-<uni-list>
-	<uni-list-item title="开启点击反馈" clickable  @click="onClick" ></uni-list-item>
-	<uni-list-item title="默认 navigateTo 方式跳转页面" link to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item>
-	<uni-list-item title="reLaunch 方式跳转页面" link="reLaunch" to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item>
-</uni-list>
-
-```
-
-
-### 聊天列表示例
-- 设置 `clickable` 为 `true` ，则表示这是一个可点击的列表，会默认给一个点击效果，并可以监听 `click` 事件
-- 设置 `link` 属性，会自动开启点击反馈，`link` 的值表示跳转方式，如果不指定，默认为 `navigateTo`
-- 设置 `to` 属性，可以跳转页面
-- `time` 属性，通常会设置成时间显示，但是这个属性不仅仅可以设置时间，你可以传入任何文本，注意文本长度可能会影响显示
-- `avatar` 和 `avatarList` 属性同时只会有一个生效，同时设置的话，`avatarList` 属性的长度大于1 ，`avatar` 属性将失效
-- 可以通过默认插槽自定义列表右侧内容
-
-```html
-
-<uni-list>
-	<uni-list :border="true">
-		<!-- 显示圆形头像 -->
-		<uni-list-chat :avatar-circle="true" title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" ></uni-list-chat>
-		<!-- 右侧带角标 -->
-		<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-text="12" :badge-style="{backgroundColor:'#FF80AB'}"></uni-list-chat>
-		<!-- 头像显示圆点 -->
-		<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
-		<!-- 头像显示角标 -->
-		<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="99"></uni-list-chat>
-		<!-- 显示多头像 -->
-		<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
-		<!-- 自定义右侧内容 -->
-		<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot">
-			<view class="chat-custom-right">
-				<text class="chat-custom-text">刚刚</text>
-				<!-- 需要使用 uni-icons 请自行引入 -->
-				<uni-icons type="star-filled" color="#999" size="18"></uni-icons>
-			</view>
-		</uni-list-chat>
-	</uni-list>
-</uni-list>
-
-```
-
-```javascript
-
-export default {
-	components: {},
-	data() {
-		return {
-			avatarList: [{
-				url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
-			}, {
-				url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
-			}, {
-				url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
-			}]
-		}
-	}
-}
-
-```
-
-
-```css
-
-.chat-custom-right {
-	flex: 1;
-	/* #ifndef APP-NVUE */
-	display: flex;
-	/* #endif */
-	flex-direction: column;
-	justify-content: space-between;
-	align-items: flex-end;
-}
-
-.chat-custom-text {
-	font-size: 12px;
-	color: #999;
-}
-
-```
-
-## API
-
-### List Props
-
-属性名			|类型		|默认值		|	说明																									
-:-:				|:-:		|:-:		|	:-:	
-border			|Boolean	|true		|	是否显示边框
-
-
-### ListItem Props
-
-属性名			|类型		|默认值		|	说明																					
-:-:				|:-:		|:-:		|	:-:	
-title			|String		|-			|	标题
-note			|String		|-			|	描述
-ellipsis		|Number		|0			|	title 是否溢出隐藏，可选值，0:默认;  1:显示一行;	2:显示两行;【nvue 暂不支持】
-thumb			|String		|-			|	左侧缩略图，若thumb有值，则不会显示扩展图标
-thumbSize		|String 	|medium 	|	略缩图尺寸，可选值，lg:大图;  medium:一般;	sm:小图;
-showBadge		|Boolean	|false		|	是否显示数字角标	
-badgeText		|String		|-			|	数字角标内容
-badgeType		|String		|-			|	数字角标类型，参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21)	
-badgeStyle  |Object   |-      | 数字角标样式，使用uni-badge的custom-style参数
-rightText		|String		|-			|	右侧文字内容
-disabled		|Boolean	|false		|	是否禁用	
-showArrow 		|Boolean	|true		|	是否显示箭头图标			
-link			|String 	|navigateTo	|	新页面跳转方式，可选值见下表
-to				|String		|-			|	新页面跳转地址，如填写此属性，click 会返回页面是否跳转成功			
-clickable		|Boolean	|false		|	是否开启点击反馈
-showSwitch	    |Boolean	|false		|	是否显示Switch																			
-switchChecked	|Boolean	|false		|	Switch是否被选中																			
-showExtraIcon   |Boolean	|false		|	左侧是否显示扩展图标																		
-extraIcon		|Object		|-			|	扩展图标参数，格式为 ``{color: '#4cd964',size: '22',type: 'spinner'}``，参考 [uni-icons](https://ext.dcloud.net.cn/plugin?id=28)	
-direction		| String	|row		|	排版方向，可选值，row:水平排列;  column:垂直排列; 3个插槽是水平排还是垂直排，也受此属性控制
-
-
-#### Link Options
-
-属性名				|	说明
-:-:					|	:-:
-navigateTo 	| 	同 uni.navigateTo()
-redirectTo 	|	同 uni.reLaunch()
-reLaunch		|	同 uni.reLaunch()
-switchTab  	|	同 uni.switchTab()
-
-### ListItem Events
-
-事件称名			|说明									|返回参数			
-:-:				|:-:									|:-:				
-click			|点击 uniListItem 触发事件，需开启点击反馈	|-					
-switchChange	|点击切换 Switch 时触发，需显示 switch		|e={value:checked}	
-
-
-
-### ListItem Slots
-
-名称	 	|	说明					
-:-:		|	:-:						
-header	|	左/上内容插槽，可完全自定义默认显示
-body	|	中间内容插槽，可完全自定义中间内容				
-footer	|	右/下内容插槽，可完全自定义右侧内容		
-
-
-> **通过插槽扩展**
-> 需要注意的是当使用插槽时，内置样式将会失效，只保留排版样式，此时的样式需要开发者自己实现
-> 如果	`uni-list-item` 组件内置属性样式无法满足需求，可以使用插槽来自定义uni-list-item里的内容。
-> uni-list-item提供了3个可扩展的插槽：`header`、`body`、`footer`
-> - 当 `direction` 属性为 `row` 时表示水平排列，此时 `header` 表示列表的左边部分，`body` 表示列表的中间部分，`footer` 表示列表的右边部分
-> - 当 `direction` 属性为 `column` 时表示垂直排列，此时 `header` 表示列表的上边部分，`body` 表示列表的中间部分，`footer` 表示列表的下边部分
-> 开发者可以只用1个插槽，也可以3个一起使用。在插槽中可自主编写view标签，实现自己所需的效果。
-
-	
-**示例**
-
-```html
-<uni-list>
-	<uni-list-item title="自定义右侧插槽" note="列表描述信息" link>
-		<template slot="header">
-			<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
-		</template>
-	</uni-list-item>
-	<uni-list-item>
-		<!-- 自定义 header -->
-		<view slot="header" class="slot-box"><image class="slot-image" src="/static/logo.png" mode="widthFix"></image></view>
-		<!-- 自定义 body -->
-		<text slot="body" class="slot-box slot-text">自定义插槽</text>
-		<!-- 自定义 footer-->
-		<template slot="footer">
-			<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
-		</template>
-	</uni-list-item>
-</uni-list>
-```
-
-
-
-
-
-### ListItemChat Props
-
-属性名			|类型		|默认值		|	说明																		
-:-:				|:-:		|:-:		|	:-:	
-title 			|String		|-			|	标题
-note 			|String		|-			|	描述
-clickable		|Boolean	|false		|	是否开启点击反馈
-badgeText		|String		|-			|	数字角标内容，设置为 `dot` 将显示圆点
-badgePositon 	|String		|right		|	角标位置
-link			|String 	|navigateTo	|	是否展示右侧箭头并开启点击反馈，可选值见下表
-clickable		|Boolean	|false		|	是否开启点击反馈
-to				|String		|-			|	跳转页面地址，如填写此属性，click 会返回页面是否跳转成功	
-time			|String 	|-			|	右侧时间显示
-avatarCircle 	|Boolean 	|false		|	是否显示圆形头像
-avatar			|String 	|-			|	头像地址，avatarCircle 不填时生效
-avatarList 		|Array	 	|-			|	头像组，格式为 [{url:''}]
-
-#### Link Options
-
-属性名		|	说明
-:-:			|	:-:
-navigateTo 	| 	同 uni.navigateTo()
-redirectTo 	|	同 uni.reLaunch()
-reLaunch	|	同 uni.reLaunch()
-switchTab  	|	同 uni.switchTab()
-
-### ListItemChat Slots
-
-名称	 	|	说明					
-:-		|	:-						
-default	|	自定义列表右侧内容（包括时间和角标显示）
-
-### ListItemChat Events
-事件称名			|	说明						|	返回参数			
-:-:				|	:-:						|	:-:	
-@click			|	点击 uniListChat 触发事件	|	{data:{}}	，如有 to 属性，会返回页面跳转信息	
-
-
-
+### [点击查看详细文档](https://uniapp.dcloud.io/component/uniui/uni-indexed-list)
+#### 如使用过程中有任何问题，或者您对uni-ui有一些好的建议，欢迎加入 uni-ui 交流群：871950839 
 
 
 
@@ -339,8 +43,4 @@ default	|	自定义列表右侧内容（包括时间和角标显示）
 
 1. 云端一体列表/宫格视图互切：[https://ext.dcloud.net.cn/plugin?id=2651](https://ext.dcloud.net.cn/plugin?id=2651)
 2. 云端一体列表（宫格模式）：[https://ext.dcloud.net.cn/plugin?id=2671](https://ext.dcloud.net.cn/plugin?id=2671)
-3. 云端一体列表（列表模式）：[https://ext.dcloud.net.cn/plugin?id=2672](https://ext.dcloud.net.cn/plugin?id=2672)
-
-## 组件示例
-
-点击查看：[https://hellouniapp.dcloud.net.cn/pages/extUI/list/list](https://hellouniapp.dcloud.net.cn/pages/extUI/list/list)
\ No newline at end of file
+3. 云端一体列表（列表模式）：[https://ext.dcloud.net.cn/plugin?id=2672](https://ext.dcloud.net.cn/plugin?id=2672)
\ No newline at end of file
diff --git a/uni_modules/uni-load-more/changelog.md b/uni_modules/uni-load-more/changelog.md
index 8f03f1d5..667abdb9 100644
--- a/uni_modules/uni-load-more/changelog.md
+++ b/uni_modules/uni-load-more/changelog.md
@@ -1,3 +1,9 @@
+## 1.3.6（2024-10-15）
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.5（2024-10-12）
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.4（2024-10-12）
+- 修复 微信小程序中的getSystemInfo警告
 ## 1.3.3（2022-01-20）
 - 新增 showText属性 ，是否显示文本
 ## 1.3.2（2022-01-19）
diff --git a/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue b/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
index ededbc20..aa43c551 100644
--- a/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
+++ b/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
@@ -36,8 +36,13 @@
 
 <script>
 	let platform
-	setTimeout(() => {
-		platform = uni.getSystemInfoSync().platform
+	setTimeout(() => {
+		// #ifdef MP-WEIXIN
+		platform = uni.getDeviceInfo().platform
+		// #endif
+		// #ifndef MP-WEIXIN
+		platform = uni.getSystemInfoSync().platform
+		// #endif
 	}, 16)
 
 	import {
diff --git a/uni_modules/uni-load-more/package.json b/uni_modules/uni-load-more/package.json
index 2fa6f040..cf44bff3 100644
--- a/uni_modules/uni-load-more/package.json
+++ b/uni_modules/uni-load-more/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-load-more",
   "displayName": "uni-load-more 加载更多",
-  "version": "1.3.3",
+  "version": "1.3.6",
   "description": "LoadMore 组件，常用在列表里面，做滚动加载使用。",
   "keywords": [
     "uni-ui",
@@ -16,11 +16,7 @@
   "directories": {
     "example": "../../temps/example_temps"
   },
-  "dcloudext": {
-    "category": [
-      "前端组件",
-      "通用组件"
-    ],
+"dcloudext": {
     "sale": {
       "regular": {
         "price": "0.00"
@@ -37,7 +33,8 @@
       "data": "无",
       "permissions": "无"
     },
-    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
   },
   "uni_modules": {
     "dependencies": ["uni-scss"],
@@ -45,7 +42,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
@@ -83,4 +81,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/uni_modules/uni-nav-bar/changelog.md b/uni_modules/uni-nav-bar/changelog.md
index 0f9a2f1b..e3efe125 100644
--- a/uni_modules/uni-nav-bar/changelog.md
+++ b/uni_modules/uni-nav-bar/changelog.md
@@ -1,3 +1,9 @@
+## 1.3.14（2024-10-15）
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.13（2024-10-12）
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.12（2024-10-12）
+- 修复 微信小程序中的getSystemInfo警告
 ## 1.3.11（2023-03-29）
 - 修复 自定义状态栏高度闪动BUG
 ## 1.3.10（2023-03-29）
diff --git a/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue
index 92634f1e..ef257f21 100644
--- a/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue
+++ b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue
@@ -318,7 +318,7 @@
 
 	.uni-navbar--fixed {
 		position: fixed;
-		z-index: 998;
+		z-index: 99;
 		/* #ifdef H5 */
 		left: var(--window-left);
 		right: var(--window-right);
diff --git a/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue
index 0a5909d1..92aa589b 100644
--- a/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue
+++ b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue
@@ -8,8 +8,14 @@
 	export default {
 		name: 'UniStatusBar',
 		data() {
-			return {
-				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px'
+			return {
+				// #ifdef MP-WEIXIN
+				statusBarHeight: uni.getWindowInfo().statusBarHeight + 'px',
+				// #endif
+				// #ifndef MP-WEIXIN
+				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+				// #endif
+
 			}
 		}
 	}
diff --git a/uni_modules/uni-nav-bar/package.json b/uni_modules/uni-nav-bar/package.json
index 240ae959..d9f53b24 100644
--- a/uni_modules/uni-nav-bar/package.json
+++ b/uni_modules/uni-nav-bar/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-nav-bar",
   "displayName": "uni-nav-bar 自定义导航栏",
-  "version": "1.3.11",
+  "version": "1.3.14",
   "description": "自定义导航栏组件，主要用于头部导航。",
   "keywords": [
     "uni-ui",
@@ -45,7 +45,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
@@ -83,4 +84,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/uni_modules/uni-open-bridge-common/changelog.md b/uni_modules/uni-open-bridge-common/changelog.md
index e97c5353..24684372 100644
--- a/uni_modules/uni-open-bridge-common/changelog.md
+++ b/uni_modules/uni-open-bridge-common/changelog.md
@@ -1,5 +1,7 @@
+## 1.2.1（2024-09-13）
+- 修复 微信小程序平台 当微信的服务器返回`encrypt_key`的过期时间`expire_in`为`0`时特殊处理为`1`天，否者可能无法验证客户端请求携带的版本
 ## 1.2.0（2023-04-27）
-- 优化 微信小程序平台 使用微信新增 API getStableAccessToken 获取 access_token, access_token 有效期内重复调用该接口不会更新 access_token, [详情](https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html)
+- 重要 微信小程序平台 使用微信新增 API getStableAccessToken 获取 access_token, access_token 有效期内重复调用该接口不会更新 access_token, [详情](https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html)
 ## 1.1.5（2023-03-27）
 - 修复 微信小程序平台 某些情况下 encrypt_key 插入错误的问题
 ## 1.1.4（2023-03-13）
diff --git a/uni_modules/uni-open-bridge-common/package.json b/uni_modules/uni-open-bridge-common/package.json
index 30f26201..d89290f7 100644
--- a/uni_modules/uni-open-bridge-common/package.json
+++ b/uni_modules/uni-open-bridge-common/package.json
@@ -1,10 +1,9 @@
 {
   "id": "uni-open-bridge-common",
   "displayName": "uni-open-bridge-common",
-  "version": "1.2.0",
+  "version": "1.2.1",
   "description": "统一接管微信等三方平台认证凭据",
   "keywords": [
-    "uni-open-bridge-common",
     "access_token",
     "session_key",
     "ticket"
@@ -39,7 +38,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "Vue": {
diff --git a/uni_modules/uni-open-bridge-common/readme.md b/uni_modules/uni-open-bridge-common/readme.md
index de28c36e..38923847 100644
--- a/uni_modules/uni-open-bridge-common/readme.md
+++ b/uni_modules/uni-open-bridge-common/readme.md
@@ -1,5 +1,5 @@
-# uni-open-bridge-common
-
-`uni-open-bridge-common` 是统一接管微信等三方平台认证凭据（包括但不限于`access_token`、`session_key`、`encrypt_key`、`ticket`）的开源库。
-
-文档链接 [https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common](https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common)
+# uni-open-bridge-common
+
+`uni-open-bridge-common` 是统一接管微信等三方平台认证凭据（包括但不限于`access_token`、`session_key`、`encrypt_key`、`ticket`）的开源库。
+
+文档链接 [https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common](https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#common)
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js
index b6cfe661..95160a43 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js
@@ -1,4 +1,4 @@
-'use strict';
+'use strict';
 
 class BridgeError extends Error {
 
@@ -20,7 +20,7 @@ class BridgeError extends Error {
     return this.message
   }
 }
-
-module.exports = {
-  BridgeError
+
+module.exports = {
+  BridgeError
 }
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js
index 063c7469..d083f00c 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js
@@ -1,124 +1,124 @@
-'use strict';
-
-const {
-  ProviderType
-} = require('./consts.js')
-
-const configCenter = require('uni-config-center')
-
-// 多维数据为兼容uni-id以前版本配置
-const OauthConfig = {
-  'weixin-app': [
-    ['app', 'oauth', 'weixin'],
-    ['app-plus', 'oauth', 'weixin']
-  ],
-  'weixin-mp': [
-    ['mp-weixin', 'oauth', 'weixin']
-  ],
-  'weixin-h5': [
-    ['web', 'oauth', 'weixin-h5'],
-    ['h5-weixin', 'oauth', 'weixin'],
-    ['h5', 'oauth', 'weixin']
-  ],
-  'weixin-web': [
-    ['web', 'oauth', 'weixin-web']
-  ],
-  'qq-app': [
-    ['app', 'oauth', 'qq'],
-    ['app-plus', 'oauth', 'qq']
-  ],
-  'qq-mp': [
-    ['mp-qq', 'oauth', 'qq']
-  ]
-}
-
-const Support_Platforms = [
-  ProviderType.WEIXIN_MP,
-  ProviderType.WEIXIN_H5,
-  ProviderType.WEIXIN_APP,
-  ProviderType.WEIXIN_WEB,
-  ProviderType.QQ_MP,
-  ProviderType.QQ_APP
-]
-
-class ConfigBase {
-
-  constructor() {
-    const uniIdConfigCenter = configCenter({
-      pluginId: 'uni-id'
-    })
-
-    this._uniIdConfig = uniIdConfigCenter.config()
-  }
-
-  getAppConfig(appid) {
-    if (Array.isArray(this._uniIdConfig)) {
-      return this._uniIdConfig.find((item) => {
-        return (item.dcloudAppid === appid)
-      })
-    }
-    return this._uniIdConfig
-  }
-}
-
-class AppConfig extends ConfigBase {
-
-  constructor() {
-    super()
-  }
-
-  get(appid, platform) {
-    if (!this.isSupport(platform)) {
-      return null
-    }
-
-    let appConfig = this.getAppConfig(appid)
-    if (!appConfig) {
-      return null
-    }
-
-    return this.getOauthConfig(appConfig, platform)
-  }
-
-  isSupport(platformName) {
-    return (Support_Platforms.indexOf(platformName) >= 0)
-  }
-
-  getOauthConfig(appConfig, platformName) {
-    let treePath = OauthConfig[platformName]
-    let node = this.findNode(appConfig, treePath)
-    if (node && node.appid && node.appsecret) {
-      return {
-        appid: node.appid,
-        secret: node.appsecret
-      }
-    }
-    return null
-  }
-
-  findNode(treeNode, arrayPath) {
-    let node = treeNode
-    for (let treePath of arrayPath) {
-      for (let name of treePath) {
-        const currentNode = node[name]
-        if (currentNode) {
-          node = currentNode
-        } else {
-          node = null
-          break
-        }
-      }
-      if (node === null) {
-        node = treeNode
-      } else {
-        break
-      }
-    }
-    return node
-  }
-}
-
-
-module.exports = {
-  AppConfig
+'use strict';
+
+const {
+  ProviderType
+} = require('./consts.js')
+
+const configCenter = require('uni-config-center')
+
+// 多维数据为兼容uni-id以前版本配置
+const OauthConfig = {
+  'weixin-app': [
+    ['app', 'oauth', 'weixin'],
+    ['app-plus', 'oauth', 'weixin']
+  ],
+  'weixin-mp': [
+    ['mp-weixin', 'oauth', 'weixin']
+  ],
+  'weixin-h5': [
+    ['web', 'oauth', 'weixin-h5'],
+    ['h5-weixin', 'oauth', 'weixin'],
+    ['h5', 'oauth', 'weixin']
+  ],
+  'weixin-web': [
+    ['web', 'oauth', 'weixin-web']
+  ],
+  'qq-app': [
+    ['app', 'oauth', 'qq'],
+    ['app-plus', 'oauth', 'qq']
+  ],
+  'qq-mp': [
+    ['mp-qq', 'oauth', 'qq']
+  ]
+}
+
+const Support_Platforms = [
+  ProviderType.WEIXIN_MP,
+  ProviderType.WEIXIN_H5,
+  ProviderType.WEIXIN_APP,
+  ProviderType.WEIXIN_WEB,
+  ProviderType.QQ_MP,
+  ProviderType.QQ_APP
+]
+
+class ConfigBase {
+
+  constructor() {
+    const uniIdConfigCenter = configCenter({
+      pluginId: 'uni-id'
+    })
+
+    this._uniIdConfig = uniIdConfigCenter.config()
+  }
+
+  getAppConfig(appid) {
+    if (Array.isArray(this._uniIdConfig)) {
+      return this._uniIdConfig.find((item) => {
+        return (item.dcloudAppid === appid)
+      })
+    }
+    return this._uniIdConfig
+  }
+}
+
+class AppConfig extends ConfigBase {
+
+  constructor() {
+    super()
+  }
+
+  get(appid, platform) {
+    if (!this.isSupport(platform)) {
+      return null
+    }
+
+    let appConfig = this.getAppConfig(appid)
+    if (!appConfig) {
+      return null
+    }
+
+    return this.getOauthConfig(appConfig, platform)
+  }
+
+  isSupport(platformName) {
+    return (Support_Platforms.indexOf(platformName) >= 0)
+  }
+
+  getOauthConfig(appConfig, platformName) {
+    let treePath = OauthConfig[platformName]
+    let node = this.findNode(appConfig, treePath)
+    if (node && node.appid && node.appsecret) {
+      return {
+        appid: node.appid,
+        secret: node.appsecret
+      }
+    }
+    return null
+  }
+
+  findNode(treeNode, arrayPath) {
+    let node = treeNode
+    for (let treePath of arrayPath) {
+      for (let name of treePath) {
+        const currentNode = node[name]
+        if (currentNode) {
+          node = currentNode
+        } else {
+          node = null
+          break
+        }
+      }
+      if (node === null) {
+        node = treeNode
+      } else {
+        break
+      }
+    }
+    return node
+  }
+}
+
+
+module.exports = {
+  AppConfig
 };
\ No newline at end of file
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js
index d89a5c12..4c666e93 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/consts.js
@@ -1,30 +1,30 @@
-'use strict';
-
-const TAG = "UNI_OPEN_BRIDGE"
-
-const HTTP_STATUS = {
-  SUCCESS: 200
-}
-
-const ProviderType = {
-  WEIXIN_MP: 'weixin-mp',
-  WEIXIN_H5: 'weixin-h5',
-  WEIXIN_APP: 'weixin-app',
-  WEIXIN_WEB: 'weixin-web',
-  QQ_MP: 'qq-mp',
-  QQ_APP: 'qq-app'
-}
-
-// old
-const PlatformType = ProviderType
-
-const ErrorCodeType = {
-  SYSTEM_ERROR: TAG + "_SYSTEM_ERROR"
-}
-
-module.exports = {
-  HTTP_STATUS,
-  ProviderType,
-  PlatformType,
-  ErrorCodeType
+'use strict';
+
+const TAG = "UNI_OPEN_BRIDGE"
+
+const HTTP_STATUS = {
+  SUCCESS: 200
+}
+
+const ProviderType = {
+  WEIXIN_MP: 'weixin-mp',
+  WEIXIN_H5: 'weixin-h5',
+  WEIXIN_APP: 'weixin-app',
+  WEIXIN_WEB: 'weixin-web',
+  QQ_MP: 'qq-mp',
+  QQ_APP: 'qq-app'
+}
+
+// old
+const PlatformType = ProviderType
+
+const ErrorCodeType = {
+  SYSTEM_ERROR: TAG + "_SYSTEM_ERROR"
+}
+
+module.exports = {
+  HTTP_STATUS,
+  ProviderType,
+  PlatformType,
+  ErrorCodeType
 }
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js
index a8dba4b3..1b5a340b 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js
@@ -1,317 +1,317 @@
-'use strict';
-
-const {
-  PlatformType,
-  ProviderType,
-  ErrorCodeType
-} = require('./consts.js')
-
-const {
-  AppConfig
-} = require('./config.js')
-
-const {
-  Storage
-} = require('./storage.js')
-
-const {
-  BridgeError
-} = require('./bridge-error.js')
-
-const {
-  WeixinServer
-} = require('./weixin-server.js')
-
-const appConfig = new AppConfig()
-
-class AccessToken extends Storage {
-
-  constructor() {
-    super('access-token', ['provider', 'appid'])
-  }
-
-  async update(key) {
-    super.update(key)
-
-    const result = await this.getByWeixinServer(key)
-
-    return this.set(key, result.value, result.duration)
-  }
-
-  async fallback(key) {
-    return this.getByWeixinServer(key)
-  }
-
-  async getByWeixinServer(key) {
-    const oauthConfig = appConfig.get(key.dcloudAppid, key.provider)
-    let methodName
-    if (key.provider === ProviderType.WEIXIN_MP) {
-      methodName = 'GetMPAccessTokenData'
-    } else if (key.provider === ProviderType.WEIXIN_H5) {
-      methodName = 'GetH5AccessTokenData'
-    } else {
-      throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, "provider invalid")
-    }
-
-    const responseData = await WeixinServer[methodName](oauthConfig)
-
-    const duration = responseData.expires_in || (60 * 60 * 2)
-    delete responseData.expires_in
-
-    return {
-      value: responseData,
-      duration
-    }
-  }
-}
-
-class UserAccessToken extends Storage {
-
-  constructor() {
-    super('user-access-token', ['provider', 'appid', 'openid'])
-  }
-}
-
-class SessionKey extends Storage {
-
-  constructor() {
-    super('session-key', ['provider', 'appid', 'openid'])
-  }
-}
-
-class Encryptkey extends Storage {
-
-  constructor() {
-    super('encrypt-key', ['provider', 'appid', 'openid'])
-  }
-
-  async update(key) {
-    super.update(key)
-
-    const result = await this.getByWeixinServer(key)
-
-    return this.set(key, result.value, result.duration)
-  }
-
-  getKeyString(key) {
-    return `${super.getKeyString(key)}-${key.version}`
-  }
-
-  getExpiresIn(value) {
-    if (value <= 0) {
-      return 60
-    }
-    return value
-  }
-
-  async fallback(key) {
-    return this.getByWeixinServer(key)
-  }
-
-  async getByWeixinServer(key) {
-    const accessToken = await Factory.Get(AccessToken, key)
-    const userSession = await Factory.Get(SessionKey, key)
-
-    const responseData = await WeixinServer.GetUserEncryptKeyData({
-      openid: key.openid,
-      access_token: accessToken.access_token,
-      session_key: userSession.session_key
-    })
-
-    const keyInfo = responseData.key_info_list.find((item) => {
-      return item.version === key.version
-    })
-
-    if (!keyInfo) {
-      throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'key version invalid')
-    }
-
-    const value = {
-      encrypt_key: keyInfo.encrypt_key,
-      iv: keyInfo.iv
-    }
-
-    return {
-      value,
-      duration: keyInfo.expire_in
-    }
-  }
-}
-
-class Ticket extends Storage {
-
-  constructor() {
-    super('ticket', ['provider', 'appid'])
-  }
-
-  async update(key) {
-    super.update(key)
-
-    const result = await this.getByWeixinServer(key)
-
-    return this.set(key, result.value, result.duration)
-  }
-
-  async fallback(key) {
-    return this.getByWeixinServer(key)
-  }
-
-  async getByWeixinServer(key) {
-    const accessToken = await Factory.Get(AccessToken, {
-      dcloudAppid: key.dcloudAppid,
-      provider: ProviderType.WEIXIN_H5
-    })
-
-    const responseData = await WeixinServer.GetH5TicketData(accessToken)
-
-    const duration = responseData.expires_in || (60 * 60 * 2)
-    delete responseData.expires_in
-    delete responseData.errcode
-    delete responseData.errmsg
-
-    return {
-      value: responseData,
-      duration
-    }
-  }
-}
-
-
-const Factory = {
-
-  async Get(T, key, fallback) {
-    Factory.FixOldKey(key)
-    return Factory.MakeUnique(T).get(key, fallback)
-  },
-
-  async Set(T, key, value, expiresIn) {
-    Factory.FixOldKey(key)
-    return Factory.MakeUnique(T).set(key, value, expiresIn)
-  },
-
-  async Remove(T, key) {
-    Factory.FixOldKey(key)
-    return Factory.MakeUnique(T).remove(key)
-  },
-
-  async Update(T, key) {
-    Factory.FixOldKey(key)
-    return Factory.MakeUnique(T).update(key)
-  },
-
-  FixOldKey(key) {
-    if (!key.provider) {
-      key.provider = key.platform
-    }
-
-    const configData = appConfig.get(key.dcloudAppid, key.provider)
-    if (!configData) {
-      throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'appid or provider invalid')
-    }
-    key.appid = configData.appid
-  },
-
-  MakeUnique(T) {
-    return new T()
-  }
-}
-
-
-// exports
-
-async function getAccessToken(key, fallback) {
-  return Factory.Get(AccessToken, key, fallback)
-}
-
-async function setAccessToken(key, value, expiresIn) {
-  return Factory.Set(AccessToken, key, value, expiresIn)
-}
-
-async function removeAccessToken(key) {
-  return Factory.Remove(AccessToken, key)
-}
-
-async function updateAccessToken(key) {
-  return Factory.Update(AccessToken, key)
-}
-
-async function getUserAccessToken(key, fallback) {
-  return Factory.Get(UserAccessToken, key, fallback)
-}
-
-async function setUserAccessToken(key, value, expiresIn) {
-  return Factory.Set(UserAccessToken, key, value, expiresIn)
-}
-
-async function removeUserAccessToken(key) {
-  return Factory.Remove(UserAccessToken, key)
-}
-
-async function getSessionKey(key, fallback) {
-  return Factory.Get(SessionKey, key, fallback)
-}
-
-async function setSessionKey(key, value, expiresIn) {
-  return Factory.Set(SessionKey, key, value, expiresIn)
-}
-
-async function removeSessionKey(key) {
-  return Factory.Remove(SessionKey, key)
-}
-
-async function getEncryptKey(key, fallback) {
-  return Factory.Get(Encryptkey, key, fallback)
-}
-
-async function setEncryptKey(key, value, expiresIn) {
-  return Factory.Set(Encryptkey, key, value, expiresIn)
-}
-
-async function removeEncryptKey(key) {
-  return Factory.Remove(Encryptkey, key)
-}
-
-async function updateEncryptKey(key) {
-  return Factory.Update(Encryptkey, key)
-}
-
-async function getTicket(key, fallback) {
-  return Factory.Get(Ticket, key, fallback)
-}
-
-async function setTicket(key, value, expiresIn) {
-  return Factory.Set(Ticket, key, value, expiresIn)
-}
-
-async function removeTicket(key) {
-  return Factory.Remove(Ticket, key)
-}
-
-async function updateTicket(key) {
-  return Factory.Update(Ticket, key)
-}
-
-module.exports = {
-  getAccessToken,
-  setAccessToken,
-  removeAccessToken,
-  updateAccessToken,
-  getUserAccessToken,
-  setUserAccessToken,
-  removeUserAccessToken,
-  getSessionKey,
-  setSessionKey,
-  removeSessionKey,
-  getEncryptKey,
-  setEncryptKey,
-  removeEncryptKey,
-  updateEncryptKey,
-  getTicket,
-  setTicket,
-  removeTicket,
-  updateTicket,
-  ProviderType,
-  PlatformType,
-  WeixinServer,
-  ErrorCodeType
+'use strict';
+
+const {
+  PlatformType,
+  ProviderType,
+  ErrorCodeType
+} = require('./consts.js')
+
+const {
+  AppConfig
+} = require('./config.js')
+
+const {
+  Storage
+} = require('./storage.js')
+
+const {
+  BridgeError
+} = require('./bridge-error.js')
+
+const {
+  WeixinServer
+} = require('./weixin-server.js')
+
+const appConfig = new AppConfig()
+
+class AccessToken extends Storage {
+
+  constructor() {
+    super('access-token', ['provider', 'appid'])
+  }
+
+  async update(key) {
+    super.update(key)
+
+    const result = await this.getByWeixinServer(key)
+
+    return this.set(key, result.value, result.duration)
+  }
+
+  async fallback(key) {
+    return this.getByWeixinServer(key)
+  }
+
+  async getByWeixinServer(key) {
+    const oauthConfig = appConfig.get(key.dcloudAppid, key.provider)
+    let methodName
+    if (key.provider === ProviderType.WEIXIN_MP) {
+      methodName = 'GetMPAccessTokenData'
+    } else if (key.provider === ProviderType.WEIXIN_H5) {
+      methodName = 'GetH5AccessTokenData'
+    } else {
+      throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, "provider invalid")
+    }
+
+    const responseData = await WeixinServer[methodName](oauthConfig)
+
+    const duration = responseData.expires_in || (60 * 60 * 2)
+    delete responseData.expires_in
+
+    return {
+      value: responseData,
+      duration
+    }
+  }
+}
+
+class UserAccessToken extends Storage {
+
+  constructor() {
+    super('user-access-token', ['provider', 'appid', 'openid'])
+  }
+}
+
+class SessionKey extends Storage {
+
+  constructor() {
+    super('session-key', ['provider', 'appid', 'openid'])
+  }
+}
+
+class Encryptkey extends Storage {
+
+  constructor() {
+    super('encrypt-key', ['provider', 'appid', 'openid'])
+  }
+
+  async update(key) {
+    super.update(key)
+
+    const result = await this.getByWeixinServer(key)
+
+    return this.set(key, result.value, result.duration)
+  }
+
+  getKeyString(key) {
+    return `${super.getKeyString(key)}-${key.version}`
+  }
+
+  getExpiresIn(value) {
+    if (value <= 0) {
+      return 60
+    }
+    return value
+  }
+
+  async fallback(key) {
+    return this.getByWeixinServer(key)
+  }
+
+  async getByWeixinServer(key) {
+    const accessToken = await Factory.Get(AccessToken, key)
+    const userSession = await Factory.Get(SessionKey, key)
+
+    const responseData = await WeixinServer.GetUserEncryptKeyData({
+      openid: key.openid,
+      access_token: accessToken.access_token,
+      session_key: userSession.session_key
+    })
+
+    const keyInfo = responseData.key_info_list.find((item) => {
+      return item.version === key.version
+    })
+
+    if (!keyInfo) {
+      throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'key version invalid')
+    }
+
+    const value = {
+      encrypt_key: keyInfo.encrypt_key,
+      iv: keyInfo.iv
+    }
+
+    return {
+      value,
+      duration: keyInfo.expire_in || (24 * 60 * 60)
+    }
+  }
+}
+
+class Ticket extends Storage {
+
+  constructor() {
+    super('ticket', ['provider', 'appid'])
+  }
+
+  async update(key) {
+    super.update(key)
+
+    const result = await this.getByWeixinServer(key)
+
+    return this.set(key, result.value, result.duration)
+  }
+
+  async fallback(key) {
+    return this.getByWeixinServer(key)
+  }
+
+  async getByWeixinServer(key) {
+    const accessToken = await Factory.Get(AccessToken, {
+      dcloudAppid: key.dcloudAppid,
+      provider: ProviderType.WEIXIN_H5
+    })
+
+    const responseData = await WeixinServer.GetH5TicketData(accessToken)
+
+    const duration = responseData.expires_in || (60 * 60 * 2)
+    delete responseData.expires_in
+    delete responseData.errcode
+    delete responseData.errmsg
+
+    return {
+      value: responseData,
+      duration
+    }
+  }
+}
+
+
+const Factory = {
+
+  async Get(T, key, fallback) {
+    Factory.FixOldKey(key)
+    return Factory.MakeUnique(T).get(key, fallback)
+  },
+
+  async Set(T, key, value, expiresIn) {
+    Factory.FixOldKey(key)
+    return Factory.MakeUnique(T).set(key, value, expiresIn)
+  },
+
+  async Remove(T, key) {
+    Factory.FixOldKey(key)
+    return Factory.MakeUnique(T).remove(key)
+  },
+
+  async Update(T, key) {
+    Factory.FixOldKey(key)
+    return Factory.MakeUnique(T).update(key)
+  },
+
+  FixOldKey(key) {
+    if (!key.provider) {
+      key.provider = key.platform
+    }
+
+    const configData = appConfig.get(key.dcloudAppid, key.provider)
+    if (!configData) {
+      throw new BridgeError(ErrorCodeType.SYSTEM_ERROR, 'appid or provider invalid')
+    }
+    key.appid = configData.appid
+  },
+
+  MakeUnique(T) {
+    return new T()
+  }
+}
+
+
+// exports
+
+async function getAccessToken(key, fallback) {
+  return Factory.Get(AccessToken, key, fallback)
+}
+
+async function setAccessToken(key, value, expiresIn) {
+  return Factory.Set(AccessToken, key, value, expiresIn)
+}
+
+async function removeAccessToken(key) {
+  return Factory.Remove(AccessToken, key)
+}
+
+async function updateAccessToken(key) {
+  return Factory.Update(AccessToken, key)
+}
+
+async function getUserAccessToken(key, fallback) {
+  return Factory.Get(UserAccessToken, key, fallback)
+}
+
+async function setUserAccessToken(key, value, expiresIn) {
+  return Factory.Set(UserAccessToken, key, value, expiresIn)
+}
+
+async function removeUserAccessToken(key) {
+  return Factory.Remove(UserAccessToken, key)
+}
+
+async function getSessionKey(key, fallback) {
+  return Factory.Get(SessionKey, key, fallback)
+}
+
+async function setSessionKey(key, value, expiresIn) {
+  return Factory.Set(SessionKey, key, value, expiresIn)
+}
+
+async function removeSessionKey(key) {
+  return Factory.Remove(SessionKey, key)
+}
+
+async function getEncryptKey(key, fallback) {
+  return Factory.Get(Encryptkey, key, fallback)
+}
+
+async function setEncryptKey(key, value, expiresIn) {
+  return Factory.Set(Encryptkey, key, value, expiresIn)
+}
+
+async function removeEncryptKey(key) {
+  return Factory.Remove(Encryptkey, key)
+}
+
+async function updateEncryptKey(key) {
+  return Factory.Update(Encryptkey, key)
+}
+
+async function getTicket(key, fallback) {
+  return Factory.Get(Ticket, key, fallback)
+}
+
+async function setTicket(key, value, expiresIn) {
+  return Factory.Set(Ticket, key, value, expiresIn)
+}
+
+async function removeTicket(key) {
+  return Factory.Remove(Ticket, key)
+}
+
+async function updateTicket(key) {
+  return Factory.Update(Ticket, key)
+}
+
+module.exports = {
+  getAccessToken,
+  setAccessToken,
+  removeAccessToken,
+  updateAccessToken,
+  getUserAccessToken,
+  setUserAccessToken,
+  removeUserAccessToken,
+  getSessionKey,
+  setSessionKey,
+  removeSessionKey,
+  getEncryptKey,
+  setEncryptKey,
+  removeEncryptKey,
+  updateEncryptKey,
+  getTicket,
+  setTicket,
+  removeTicket,
+  updateTicket,
+  ProviderType,
+  PlatformType,
+  WeixinServer,
+  ErrorCodeType
 }
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/package.json b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/package.json
index a017b49a..e2770618 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/package.json
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/package.json
@@ -1,15 +1,19 @@
 {
-  "name": "uni-open-bridge-common",
-  "version": "1.0.0",
-  "description": "",
-  "main": "index.js",
-  "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
-  },
-  "keywords": [],
-  "author": "",
-  "license": "ISC",
-  "dependencies": {
-    "uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
-  }
+    "name": "uni-open-bridge-common",
+    "version": "1.0.0",
+    "description": "",
+    "main": "index.js",
+    "scripts": {
+        "test": "echo \"Error: no test specified\" && exit 1"
+    },
+    "keywords": [],
+    "author": "",
+    "license": "ISC",
+    "dependencies": {
+        "uni-config-center": "file:..\/..\/..\/..\/..\/uni-config-center\/uniCloud\/cloudfunctions\/common\/uni-config-center"
+    },
+    "origin-plugin-dev-name": "uni-open-bridge-common",
+    "origin-plugin-version": "1.2.1",
+    "plugin-dev-name": "uni-open-bridge-common",
+    "plugin-version": "1.2.1"
 }
\ No newline at end of file
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js
index 61e2fb30..b1665cc8 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/storage.js
@@ -1,111 +1,116 @@
-'use strict';
-
-const {
-  Validator
-} = require('./validator.js')
-
-const {
-  CacheKeyCascade
-} = require('./uni-cloud-cache.js')
-
-const {
-  BridgeError
-} = require('./bridge-error.js')
-
-class Storage {
-
-  constructor(type, keys) {
-    this._type = type || null
-    this._keys = keys || []
-  }
-
-  async get(key, fallback) {
-    this.validateKey(key)
-    const result = await this.create(key, fallback).get()
-    return result.value
-  }
-
-  async set(key, value, expiresIn) {
-    this.validateKey(key)
-    this.validateValue(value)
-    const expires_in = this.getExpiresIn(expiresIn)
-    if (expires_in !== 0) {
-      await this.create(key).set(this.getValue(value), expires_in)
-    }
-  }
-
-  async remove(key) {
-    this.validateKey(key)
-    await this.create(key).remove()
-  }
-
-  // virtual
-  async update(key) {
-    this.validateKey(key)
-  }
-
-  async ttl(key) {
-    this.validateKey(key)
-    // 后续考虑支持
-  }
-
-  async fallback(key) {}
-
-  getKeyString(key) {
-    const keyArray = [Storage.Prefix]
-    this._keys.forEach((name) => {
-      keyArray.push(key[name])
-    })
-    keyArray.push(this._type)
-    return keyArray.join(':')
-  }
-
-  getValue(value) {
-    return value
-  }
-
-  getExpiresIn(value) {
-    if (value !== undefined) {
-      return value
-    }
-    return -1
-  }
-
-  validateKey(key) {
-    Validator.Key(this._keys, key)
-  }
-
-  validateValue(value) {
-    Validator.Value(value)
-  }
-
-  create(key, fallback) {
-    const keyString = this.getKeyString(key)
-    const options = {
-      layers: [{
-        type: 'database',
-        key: keyString
-      }, {
-        type: 'redis',
-        key: keyString
-      }]
-    }
-
-    const _this = this
-    return new CacheKeyCascade({
-      ...options,
-      fallback: async function() {
-        if (fallback) {
-          return fallback(key)
-        } else if (_this.fallback) {
-          return _this.fallback(key)
-        }
-      }
-    })
-  }
-}
-Storage.Prefix = "uni-id"
-
-module.exports = {
-  Storage
+'use strict';
+
+const {
+  Validator
+} = require('./validator.js')
+
+const {
+  CacheKeyCascade
+} = require('./uni-cloud-cache.js')
+
+const {
+  BridgeError
+} = require('./bridge-error.js')
+
+class Storage {
+
+  constructor(type, keys) {
+    this._type = type || null
+    this._keys = keys || []
+  }
+
+  async get(key, fallback) {
+    this.validateKey(key)
+    const result = await this.create(key, fallback).get()
+    return result.value
+  }
+
+  async set(key, value, expiresIn) {
+    this.validateKey(key)
+    this.validateValue(value)
+    const expires_in = this.getExpiresIn(expiresIn)
+    if (expires_in !== 0) {
+      await this.create(key).set(this.getValue(value), expires_in)
+    }
+  }
+
+  async remove(key) {
+    this.validateKey(key)
+    await this.create(key).remove()
+  }
+
+  // virtual
+  async update(key) {
+    this.validateKey(key)
+  }
+
+  async ttl(key) {
+    this.validateKey(key)
+    // 后续考虑支持
+  }
+
+  async fallback(key) {
+    return {
+      value: null,
+      duration: -1
+    }
+  }
+
+  getKeyString(key) {
+    const keyArray = [Storage.Prefix]
+    this._keys.forEach((name) => {
+      keyArray.push(key[name])
+    })
+    keyArray.push(this._type)
+    return keyArray.join(':')
+  }
+
+  getValue(value) {
+    return value
+  }
+
+  getExpiresIn(value) {
+    if (value !== undefined) {
+      return value
+    }
+    return -1
+  }
+
+  validateKey(key) {
+    Validator.Key(this._keys, key)
+  }
+
+  validateValue(value) {
+    Validator.Value(value)
+  }
+
+  create(key, fallback) {
+    const keyString = this.getKeyString(key)
+    const options = {
+      layers: [{
+        type: 'database',
+        key: keyString
+      }, {
+        type: 'redis',
+        key: keyString
+      }]
+    }
+
+    const _this = this
+    return new CacheKeyCascade({
+      ...options,
+      fallback: async function() {
+        if (fallback) {
+          return fallback(key)
+        } else if (_this.fallback) {
+          return _this.fallback(key)
+        }
+      }
+    })
+  }
+}
+Storage.Prefix = "uni-id"
+
+module.exports = {
+  Storage
 };
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js
index bde572ea..2e4286be 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/uni-cloud-cache.js
@@ -1,324 +1,324 @@
-const db = uniCloud.database()
-
-function getType(value) {
-  return Object.prototype.toString.call(value).slice(8, -1).toLowerCase()
-}
-
-const validator = {
-  key: function(value) {
-    const err = new Error('Invalid key')
-    if (typeof value !== 'string') {
-      throw err
-    }
-    const valueTrim = value.trim()
-    if (!valueTrim || valueTrim !== value) {
-      throw err
-    }
-  },
-  value: function(value) {
-    // 仅作简单校验
-    const type = getType(value)
-    const validValueType = ['null', 'number', 'string', 'array', 'object']
-    if (validValueType.indexOf(type) === -1) {
-      throw new Error('Invalid value type')
-    }
-  },
-  duration: function(value) {
-    const err = new Error('Invalid duration')
-    if (value === undefined) {
-      return
-    }
-    if (typeof value !== 'number' || value === 0) {
-      throw err
-    }
-  }
-}
-
-/**
- * 入库时 expired 为过期时间对应的时间戳，永不过期用-1表示
- * 返回结果时 与redis对齐，-1表示永不过期，-2表示已过期或不存在
- */
-class DatabaseCache {
-  constructor({
-    collection = 'opendb-open-data'
-  } = {}) {
-    this.type = 'db'
-    this.collection = db.collection(collection)
-  }
-
-  _serializeValue(value) {
-    return value === undefined ? null : JSON.stringify(value)
-  }
-
-  _deserializeValue(value) {
-    return value ? JSON.parse(value) : value
-  }
-
-  async set(key, value, duration) {
-    validator.key(key)
-    validator.value(value)
-    validator.duration(duration)
-    value = this._serializeValue(value)
-    await this.collection.doc(key).set({
-      value,
-      expired: duration && duration !== -1 ? Date.now() + (duration * 1000) : -1
-    })
-  }
-
-  async _getWithDuration(key) {
-    const getKeyRes = await this.collection.doc(key).get()
-    const record = getKeyRes.data[0]
-    if (!record) {
-      return {
-        value: null,
-        duration: -2
-      }
-    }
-    const value = this._deserializeValue(record.value)
-    const expired = record.expired
-    if (expired === -1) {
-      return {
-        value,
-        duration: -1
-      }
-    }
-    const duration = expired - Date.now()
-    if (duration <= 0) {
-      await this.remove(key)
-      return {
-        value: null,
-        duration: -2
-      }
-    }
-    return {
-      value,
-      duration: Math.floor(duration / 1000)
-    }
-  }
-
-  async get(key, {
-    withDuration = true
-  } = {}) {
-    const result = await this._getWithDuration(key)
-    if (!withDuration) {
-      delete result.duration
-    }
-    return result
-  }
-
-  async remove(key) {
-    await this.collection.doc(key).remove()
-  }
-}
-
-class RedisCache {
-  constructor() {
-    this.type = 'redis'
-    this.redis = uniCloud.redis()
-  }
-
-  _serializeValue(value) {
-    return value === undefined ? null : JSON.stringify(value)
-  }
-
-  _deserializeValue(value) {
-    return value ? JSON.parse(value) : value
-  }
-
-  async set(key, value, duration) {
-    validator.key(key)
-    validator.value(value)
-    validator.duration(duration)
-    value = this._serializeValue(value)
-    if (!duration || duration === -1) {
-      await this.redis.set(key, value)
-    } else {
-      await this.redis.set(key, value, 'EX', duration)
-    }
-  }
-
-  async get(key, {
-    withDuration = false
-  } = {}) {
-    let value = await this.redis.get(key)
-    value = this._deserializeValue(value)
-    if (!withDuration) {
-      return {
-        value
-      }
-    }
-    const durationSecond = await this.redis.ttl(key)
-    let duration
-    switch (durationSecond) {
-      case -1:
-        duration = -1
-        break
-      case -2:
-        duration = -2
-        break
-      default:
-        duration = durationSecond
-        break
-    }
-    return {
-      value,
-      duration
-    }
-  }
-
-  async remove(key) {
-    await this.redis.del(key)
-  }
-}
-
-class Cache {
-  constructor({
-    type,
-    collection
-  } = {}) {
-    if (type === 'database') {
-      return new DatabaseCache({
-        collection
-      })
-    } else if (type === 'redis') {
-      return new RedisCache()
-    } else {
-      throw new Error('Invalid cache type')
-    }
-  }
-}
-
-class CacheKey {
-  constructor({
-    type,
-    collection,
-    cache,
-    key,
-    fallback
-  } = {}) {
-    this.cache = cache || new Cache({
-      type,
-      collection
-    })
-    this.key = key
-    this.fallback = fallback
-  }
-
-  async set(value, duration) {
-    await this.cache.set(this.key, value, duration)
-  }
-
-  async setWithSync(value, duration, syncMethod) {
-    await Promise.all([
-      this.set(this.key, value, duration),
-      syncMethod(value, duration)
-    ])
-  }
-
-  async get() {
-    let {
-      value,
-      duration
-    } = await this.cache.get(this.key)
-    if (value !== null && value !== undefined) {
-      return {
-        value,
-        duration
-      }
-    }
-    if (!this.fallback) {
-      return {
-        value: null,
-        duration: -2
-      }
-    }
-    const fallbackResult = await this.fallback()
-    value = fallbackResult.value
-    duration = fallbackResult.duration
-    if (value !== null && duration !== undefined) {
-      await this.cache.set(this.key, value, duration)
-    }
-    return {
-      value,
-      duration
-    }
-  }
-
-  async remove() {
-    await this.cache.remove(this.key)
-  }
-}
-
-class CacheKeyCascade {
-  constructor({
-    layers, // [{cache, type, collection, key}] 从低级到高级排序，[DbCacheKey, RedisCacheKey]
-    fallback
-  } = {}) {
-    this.layers = layers
-    this.cacheLayers = []
-    let lastCacheKey
-    for (let i = 0; i < layers.length; i++) {
-      const {
-        type,
-        cache,
-        collection,
-        key
-      } = layers[i]
-      const lastCacheKeyTemp = lastCacheKey
-      try {
-        const currentCacheKey = new CacheKey({
-          type,
-          collection,
-          cache,
-          key,
-          fallback: i === 0 ? fallback : function() {
-            return lastCacheKeyTemp.get()
-          }
-        })
-        this.cacheLayers.push(currentCacheKey)
-        lastCacheKey = currentCacheKey
-      } catch (e) {}
-    }
-    this.highLevelCache = lastCacheKey
-  }
-
-  async set(value, duration) {
-    return Promise.all(
-      this.cacheLayers.map(item => {
-        return item.set(value, duration)
-      })
-    )
-  }
-
-  async setWithSync(value, duration, syncMethod) {
-    const setPromise = this.cacheLayers.map(item => {
-      return item.set(value, duration)
-    })
-    return Promise.all(
-      [
-        ...setPromise,
-        syncMethod(value, duration)
-      ]
-    )
-  }
-
-  async get() {
-    return this.highLevelCache.get()
-  }
-
-  async remove() {
-    await Promise.all(
-      this.cacheLayers.map(cacheKeyItem => {
-        return cacheKeyItem.remove()
-      })
-    )
-  }
-}
-
-module.exports = {
-  Cache,
-  DatabaseCache,
-  RedisCache,
-  CacheKey,
-  CacheKeyCascade
+const db = uniCloud.database()
+
+function getType(value) {
+  return Object.prototype.toString.call(value).slice(8, -1).toLowerCase()
+}
+
+const validator = {
+  key: function(value) {
+    const err = new Error('Invalid key')
+    if (typeof value !== 'string') {
+      throw err
+    }
+    const valueTrim = value.trim()
+    if (!valueTrim || valueTrim !== value) {
+      throw err
+    }
+  },
+  value: function(value) {
+    // 仅作简单校验
+    const type = getType(value)
+    const validValueType = ['null', 'number', 'string', 'array', 'object']
+    if (validValueType.indexOf(type) === -1) {
+      throw new Error('Invalid value type')
+    }
+  },
+  duration: function(value) {
+    const err = new Error('Invalid duration')
+    if (value === undefined) {
+      return
+    }
+    if (typeof value !== 'number' || value === 0) {
+      throw err
+    }
+  }
+}
+
+/**
+ * 入库时 expired 为过期时间对应的时间戳，永不过期用-1表示
+ * 返回结果时 与redis对齐，-1表示永不过期，-2表示已过期或不存在
+ */
+class DatabaseCache {
+  constructor({
+    collection = 'opendb-open-data'
+  } = {}) {
+    this.type = 'db'
+    this.collection = db.collection(collection)
+  }
+
+  _serializeValue(value) {
+    return value === undefined ? null : JSON.stringify(value)
+  }
+
+  _deserializeValue(value) {
+    return value ? JSON.parse(value) : value
+  }
+
+  async set(key, value, duration) {
+    validator.key(key)
+    validator.value(value)
+    validator.duration(duration)
+    value = this._serializeValue(value)
+    await this.collection.doc(key).set({
+      value,
+      expired: duration && duration !== -1 ? Date.now() + (duration * 1000) : -1
+    })
+  }
+
+  async _getWithDuration(key) {
+    const getKeyRes = await this.collection.doc(key).get()
+    const record = getKeyRes.data[0]
+    if (!record) {
+      return {
+        value: null,
+        duration: -2
+      }
+    }
+    const value = this._deserializeValue(record.value)
+    const expired = record.expired
+    if (expired === -1) {
+      return {
+        value,
+        duration: -1
+      }
+    }
+    const duration = expired - Date.now()
+    if (duration <= 0) {
+      await this.remove(key)
+      return {
+        value: null,
+        duration: -2
+      }
+    }
+    return {
+      value,
+      duration: Math.floor(duration / 1000)
+    }
+  }
+
+  async get(key, {
+    withDuration = true
+  } = {}) {
+    const result = await this._getWithDuration(key)
+    if (!withDuration) {
+      delete result.duration
+    }
+    return result
+  }
+
+  async remove(key) {
+    await this.collection.doc(key).remove()
+  }
+}
+
+class RedisCache {
+  constructor() {
+    this.type = 'redis'
+    this.redis = uniCloud.redis()
+  }
+
+  _serializeValue(value) {
+    return value === undefined ? null : JSON.stringify(value)
+  }
+
+  _deserializeValue(value) {
+    return value ? JSON.parse(value) : value
+  }
+
+  async set(key, value, duration) {
+    validator.key(key)
+    validator.value(value)
+    validator.duration(duration)
+    value = this._serializeValue(value)
+    if (!duration || duration === -1) {
+      await this.redis.set(key, value)
+    } else {
+      await this.redis.set(key, value, 'EX', duration)
+    }
+  }
+
+  async get(key, {
+    withDuration = false
+  } = {}) {
+    let value = await this.redis.get(key)
+    value = this._deserializeValue(value)
+    if (!withDuration) {
+      return {
+        value
+      }
+    }
+    const durationSecond = await this.redis.ttl(key)
+    let duration
+    switch (durationSecond) {
+      case -1:
+        duration = -1
+        break
+      case -2:
+        duration = -2
+        break
+      default:
+        duration = durationSecond
+        break
+    }
+    return {
+      value,
+      duration
+    }
+  }
+
+  async remove(key) {
+    await this.redis.del(key)
+  }
+}
+
+class Cache {
+  constructor({
+    type,
+    collection
+  } = {}) {
+    if (type === 'database') {
+      return new DatabaseCache({
+        collection
+      })
+    } else if (type === 'redis') {
+      return new RedisCache()
+    } else {
+      throw new Error('Invalid cache type')
+    }
+  }
+}
+
+class CacheKey {
+  constructor({
+    type,
+    collection,
+    cache,
+    key,
+    fallback
+  } = {}) {
+    this.cache = cache || new Cache({
+      type,
+      collection
+    })
+    this.key = key
+    this.fallback = fallback
+  }
+
+  async set(value, duration) {
+    await this.cache.set(this.key, value, duration)
+  }
+
+  async setWithSync(value, duration, syncMethod) {
+    await Promise.all([
+      this.set(this.key, value, duration),
+      syncMethod(value, duration)
+    ])
+  }
+
+  async get() {
+    let {
+      value,
+      duration
+    } = await this.cache.get(this.key)
+    if (value !== null && value !== undefined) {
+      return {
+        value,
+        duration
+      }
+    }
+    if (!this.fallback) {
+      return {
+        value: null,
+        duration: -2
+      }
+    }
+    const fallbackResult = await this.fallback()
+    value = fallbackResult.value
+    duration = fallbackResult.duration
+    if (value !== null && duration !== undefined) {
+      await this.cache.set(this.key, value, duration)
+    }
+    return {
+      value,
+      duration
+    }
+  }
+
+  async remove() {
+    await this.cache.remove(this.key)
+  }
+}
+
+class CacheKeyCascade {
+  constructor({
+    layers, // [{cache, type, collection, key}] 从低级到高级排序，[DbCacheKey, RedisCacheKey]
+    fallback
+  } = {}) {
+    this.layers = layers
+    this.cacheLayers = []
+    let lastCacheKey
+    for (let i = 0; i < layers.length; i++) {
+      const {
+        type,
+        cache,
+        collection,
+        key
+      } = layers[i]
+      const lastCacheKeyTemp = lastCacheKey
+      try {
+        const currentCacheKey = new CacheKey({
+          type,
+          collection,
+          cache,
+          key,
+          fallback: i === 0 ? fallback : function() {
+            return lastCacheKeyTemp.get()
+          }
+        })
+        this.cacheLayers.push(currentCacheKey)
+        lastCacheKey = currentCacheKey
+      } catch (e) {}
+    }
+    this.highLevelCache = lastCacheKey
+  }
+
+  async set(value, duration) {
+    return Promise.all(
+      this.cacheLayers.map(item => {
+        return item.set(value, duration)
+      })
+    )
+  }
+
+  async setWithSync(value, duration, syncMethod) {
+    const setPromise = this.cacheLayers.map(item => {
+      return item.set(value, duration)
+    })
+    return Promise.all(
+      [
+        ...setPromise,
+        syncMethod(value, duration)
+      ]
+    )
+  }
+
+  async get() {
+    return this.highLevelCache.get()
+  }
+
+  async remove() {
+    await Promise.all(
+      this.cacheLayers.map(cacheKeyItem => {
+        return cacheKeyItem.remove()
+      })
+    )
+  }
+}
+
+module.exports = {
+  Cache,
+  DatabaseCache,
+  RedisCache,
+  CacheKey,
+  CacheKeyCascade
 }
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js
index 231dc8b1..47a455b1 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/validator.js
@@ -1,31 +1,31 @@
-const Validator = {
-
-  Key(keyArray, parameters) {
-    for (let i = 0; i < keyArray.length; i++) {
-      const keyName = keyArray[i]
-      if (typeof parameters[keyName] !== 'string') {
-        Validator.ThrowNewError(`Invalid ${keyName}`)
-      }
-      if (parameters[keyName].length < 1) {
-        Validator.ThrowNewError(`Invalid ${keyName}`)
-      }
-    }
-  },
-
-  Value(value) {
-    if (value === undefined) {
-      Validator.ThrowNewError('Invalid Value')
-    }
-    if (typeof value !== 'object') {
-      Validator.ThrowNewError('Invalid Value Type')
-    }
-  },
-
-  ThrowNewError(message) {
-    throw new Error(message)
-  }
-}
-
-module.exports = {
-  Validator
+const Validator = {
+
+  Key(keyArray, parameters) {
+    for (let i = 0; i < keyArray.length; i++) {
+      const keyName = keyArray[i]
+      if (typeof parameters[keyName] !== 'string') {
+        Validator.ThrowNewError(`Invalid ${keyName}`)
+      }
+      if (parameters[keyName].length < 1) {
+        Validator.ThrowNewError(`Invalid ${keyName}`)
+      }
+    }
+  },
+
+  Value(value) {
+    if (value === undefined) {
+      Validator.ThrowNewError('Invalid Value')
+    }
+    if (typeof value !== 'object') {
+      Validator.ThrowNewError('Invalid Value Type')
+    }
+  },
+
+  ThrowNewError(message) {
+    throw new Error(message)
+  }
+}
+
+module.exports = {
+  Validator
 }
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js
index d45e9064..ef476f16 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js
+++ b/uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js
@@ -1,203 +1,203 @@
-'use strict';
-
-const crypto = require('crypto')
-
-const {
-  HTTP_STATUS
-} = require('./consts.js')
-
-const {
-  BridgeError
-} = require('./bridge-error.js')
-
-class WeixinServer {
-
-  constructor(options = {}) {
-    this._appid = options.appid
-    this._secret = options.secret
-  }
-
-  getAccessToken() {
-    return uniCloud.httpclient.request(WeixinServer.AccessToken_Url, {
-      dataType: 'json',
-      method: 'POST',
-      contentType: 'json',
-      data: {
-        appid: this._appid,
-        secret: this._secret,
-        grant_type: "client_credential"
-      }
-    })
-  }
-
-  // 使用客户端获取的 code 从微信服务器换取 openid，code 仅可使用一次
-  codeToSession(code) {
-    return uniCloud.httpclient.request(WeixinServer.Code2Session_Url, {
-      dataType: 'json',
-      data: {
-        appid: this._appid,
-        secret: this._secret,
-        js_code: code,
-        grant_type: 'authorization_code'
-      }
-    })
-  }
-
-  getUserEncryptKey({
-    access_token,
-    openid,
-    session_key
-  }) {
-    console.log(access_token, openid, session_key);
-    const signature = crypto.createHmac('sha256', session_key).update('').digest('hex')
-    return uniCloud.httpclient.request(WeixinServer.User_Encrypt_Key_Url, {
-      dataType: 'json',
-      method: 'POST',
-      dataAsQueryString: true,
-      data: {
-        access_token,
-        openid: openid,
-        signature: signature,
-        sig_method: 'hmac_sha256'
-      }
-    })
-  }
-
-  getH5AccessToken() {
-    return uniCloud.httpclient.request(WeixinServer.AccessToken_H5_Url, {
-      dataType: 'json',
-      method: 'GET',
-      data: {
-        appid: this._appid,
-        secret: this._secret,
-        grant_type: "client_credential"
-      }
-    })
-  }
-
-  getH5Ticket(access_token) {
-    return uniCloud.httpclient.request(WeixinServer.Ticket_Url, {
-      dataType: 'json',
-      dataAsQueryString: true,
-      method: 'POST',
-      data: {
-        access_token
-      }
-    })
-  }
-
-  getH5AccessTokenForEip() {
-    return uniCloud.httpProxyForEip.postForm(WeixinServer.AccessToken_H5_Url, {
-      appid: this._appid,
-      secret: this._secret,
-      grant_type: "client_credential"
-    }, {
-      dataType: 'json'
-    })
-  }
-
-  getH5TicketForEip(access_token) {
-    return uniCloud.httpProxyForEip.postForm(WeixinServer.Ticket_Url, {
-      access_token
-    }, {
-      dataType: 'json',
-      dataAsQueryString: true
-    })
-  }
-}
-
-WeixinServer.AccessToken_Url = 'https://api.weixin.qq.com/cgi-bin/stable_token'
-WeixinServer.Code2Session_Url = 'https://api.weixin.qq.com/sns/jscode2session'
-WeixinServer.User_Encrypt_Key_Url = 'https://api.weixin.qq.com/wxa/business/getuserencryptkey'
-WeixinServer.AccessToken_H5_Url = 'https://api.weixin.qq.com/cgi-bin/token'
-WeixinServer.Ticket_Url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi'
-
-WeixinServer.GetMPAccessToken = function(options) {
-  return new WeixinServer(options).getAccessToken()
-}
-
-WeixinServer.GetCodeToSession = function(options) {
-  return new WeixinServer(options).codeToSession(options.code)
-}
-
-WeixinServer.GetUserEncryptKey = function(options) {
-  return new WeixinServer(options).getUserEncryptKey(options)
-}
-
-WeixinServer.GetH5AccessToken = function(options) {
-  return new WeixinServer(options).getH5AccessToken()
-}
-
-WeixinServer.GetH5Ticket = function(options) {
-  return new WeixinServer(options).getH5Ticket(options.access_token)
-}
-
-////////////////////////////////////////////////////////////////
-
-function isAliyun() {
-  return (uniCloud.getCloudInfos()[0].provider === 'aliyun')
-}
-
-WeixinServer.GetResponseData = function(response) {
-  console.log("WeixinServer::response", response)
-
-  if (!(response.status === HTTP_STATUS.SUCCESS || response.statusCodeValue === HTTP_STATUS.SUCCESS)) {
-    throw new BridgeError(response.status || response.statusCodeValue, response.status || response.statusCodeValue)
-  }
-
-  const responseData = response.data || response.body
-
-  if (responseData.errcode !== undefined && responseData.errcode !== 0) {
-    throw new BridgeError(responseData.errcode, responseData.errmsg)
-  }
-
-  return responseData
-}
-
-WeixinServer.GetMPAccessTokenData = async function(options) {
-  const response = await new WeixinServer(options).getAccessToken()
-  return WeixinServer.GetResponseData(response)
-}
-
-WeixinServer.GetCodeToSessionData = async function(options) {
-  const response = await new WeixinServer(options).codeToSession(options.code)
-  return WeixinServer.GetResponseData(response)
-}
-
-WeixinServer.GetUserEncryptKeyData = async function(options) {
-  const response = await new WeixinServer(options).getUserEncryptKey(options)
-  return WeixinServer.GetResponseData(response)
-}
-
-WeixinServer.GetH5AccessTokenData = async function(options) {
-  const ws = new WeixinServer(options)
-  let response
-  if (isAliyun()) {
-    response = await ws.getH5AccessTokenForEip()
-    if (typeof response === 'string') {
-      response = JSON.parse(response)
-    }
-  } else {
-    response = await ws.getH5AccessToken()
-  }
-  return WeixinServer.GetResponseData(response)
-}
-
-WeixinServer.GetH5TicketData = async function(options) {
-  const ws = new WeixinServer(options)
-  let response
-  if (isAliyun()) {
-    response = await ws.getH5TicketForEip(options.access_token)
-    if (typeof response === 'string') {
-      response = JSON.parse(response)
-    }
-  } else {
-    response = await ws.getH5Ticket(options.access_token)
-  }
-  return WeixinServer.GetResponseData(response)
-}
-
-
-module.exports = {
-  WeixinServer
+'use strict';
+
+const crypto = require('crypto')
+
+const {
+  HTTP_STATUS
+} = require('./consts.js')
+
+const {
+  BridgeError
+} = require('./bridge-error.js')
+
+class WeixinServer {
+
+  constructor(options = {}) {
+    this._appid = options.appid
+    this._secret = options.secret
+  }
+
+  getAccessToken() {
+    return uniCloud.httpclient.request(WeixinServer.AccessToken_Url, {
+      dataType: 'json',
+      method: 'POST',
+      contentType: 'json',
+      data: {
+        appid: this._appid,
+        secret: this._secret,
+        grant_type: "client_credential"
+      }
+    })
+  }
+
+  // 使用客户端获取的 code 从微信服务器换取 openid，code 仅可使用一次
+  codeToSession(code) {
+    return uniCloud.httpclient.request(WeixinServer.Code2Session_Url, {
+      dataType: 'json',
+      data: {
+        appid: this._appid,
+        secret: this._secret,
+        js_code: code,
+        grant_type: 'authorization_code'
+      }
+    })
+  }
+
+  getUserEncryptKey({
+    access_token,
+    openid,
+    session_key
+  }) {
+    console.log(access_token, openid, session_key);
+    const signature = crypto.createHmac('sha256', session_key).update('').digest('hex')
+    return uniCloud.httpclient.request(WeixinServer.User_Encrypt_Key_Url, {
+      dataType: 'json',
+      method: 'POST',
+      dataAsQueryString: true,
+      data: {
+        access_token,
+        openid: openid,
+        signature: signature,
+        sig_method: 'hmac_sha256'
+      }
+    })
+  }
+
+  getH5AccessToken() {
+    return uniCloud.httpclient.request(WeixinServer.AccessToken_H5_Url, {
+      dataType: 'json',
+      method: 'GET',
+      data: {
+        appid: this._appid,
+        secret: this._secret,
+        grant_type: "client_credential"
+      }
+    })
+  }
+
+  getH5Ticket(access_token) {
+    return uniCloud.httpclient.request(WeixinServer.Ticket_Url, {
+      dataType: 'json',
+      dataAsQueryString: true,
+      method: 'POST',
+      data: {
+        access_token
+      }
+    })
+  }
+
+  getH5AccessTokenForEip() {
+    return uniCloud.httpProxyForEip.postForm(WeixinServer.AccessToken_H5_Url, {
+      appid: this._appid,
+      secret: this._secret,
+      grant_type: "client_credential"
+    }, {
+      dataType: 'json'
+    })
+  }
+
+  getH5TicketForEip(access_token) {
+    return uniCloud.httpProxyForEip.postForm(WeixinServer.Ticket_Url, {
+      access_token
+    }, {
+      dataType: 'json',
+      dataAsQueryString: true
+    })
+  }
+}
+
+WeixinServer.AccessToken_Url = 'https://api.weixin.qq.com/cgi-bin/stable_token'
+WeixinServer.Code2Session_Url = 'https://api.weixin.qq.com/sns/jscode2session'
+WeixinServer.User_Encrypt_Key_Url = 'https://api.weixin.qq.com/wxa/business/getuserencryptkey'
+WeixinServer.AccessToken_H5_Url = 'https://api.weixin.qq.com/cgi-bin/token'
+WeixinServer.Ticket_Url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi'
+
+WeixinServer.GetMPAccessToken = function(options) {
+  return new WeixinServer(options).getAccessToken()
+}
+
+WeixinServer.GetCodeToSession = function(options) {
+  return new WeixinServer(options).codeToSession(options.code)
+}
+
+WeixinServer.GetUserEncryptKey = function(options) {
+  return new WeixinServer(options).getUserEncryptKey(options)
+}
+
+WeixinServer.GetH5AccessToken = function(options) {
+  return new WeixinServer(options).getH5AccessToken()
+}
+
+WeixinServer.GetH5Ticket = function(options) {
+  return new WeixinServer(options).getH5Ticket(options.access_token)
+}
+
+////////////////////////////////////////////////////////////////
+
+function isAliyun() {
+  return (uniCloud.getCloudInfos()[0].provider === 'aliyun')
+}
+
+WeixinServer.GetResponseData = function(response) {
+  console.log("WeixinServer::response", response)
+
+  if (!(response.status === HTTP_STATUS.SUCCESS || response.statusCodeValue === HTTP_STATUS.SUCCESS)) {
+    throw new BridgeError(response.status || response.statusCodeValue, response.status || response.statusCodeValue)
+  }
+
+  const responseData = response.data || response.body
+
+  if (responseData.errcode !== undefined && responseData.errcode !== 0) {
+    throw new BridgeError(responseData.errcode, responseData.errmsg)
+  }
+
+  return responseData
+}
+
+WeixinServer.GetMPAccessTokenData = async function(options) {
+  const response = await new WeixinServer(options).getAccessToken()
+  return WeixinServer.GetResponseData(response)
+}
+
+WeixinServer.GetCodeToSessionData = async function(options) {
+  const response = await new WeixinServer(options).codeToSession(options.code)
+  return WeixinServer.GetResponseData(response)
+}
+
+WeixinServer.GetUserEncryptKeyData = async function(options) {
+  const response = await new WeixinServer(options).getUserEncryptKey(options)
+  return WeixinServer.GetResponseData(response)
+}
+
+WeixinServer.GetH5AccessTokenData = async function(options) {
+  const ws = new WeixinServer(options)
+  let response
+  if (isAliyun()) {
+    response = await ws.getH5AccessTokenForEip()
+    if (typeof response === 'string') {
+      response = JSON.parse(response)
+    }
+  } else {
+    response = await ws.getH5AccessToken()
+  }
+  return WeixinServer.GetResponseData(response)
+}
+
+WeixinServer.GetH5TicketData = async function(options) {
+  const ws = new WeixinServer(options)
+  let response
+  if (isAliyun()) {
+    response = await ws.getH5TicketForEip(options.access_token)
+    if (typeof response === 'string') {
+      response = JSON.parse(response)
+    }
+  } else {
+    response = await ws.getH5Ticket(options.access_token)
+  }
+  return WeixinServer.GetResponseData(response)
+}
+
+
+module.exports = {
+  WeixinServer
 }
diff --git a/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json b/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json
index e7774df7..bc250988 100644
--- a/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json
+++ b/uni_modules/uni-open-bridge-common/uniCloud/database/opendb-open-data.schema.json
@@ -1,19 +1,19 @@
-// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema
-{
-  "bsonType": "object",
-  "required": ["_id", "value"],
-  "properties": {
-    "_id": {
-      "bsonType": "string",
-      "description": "key，格式：uni-id:[provider]:[appid]:[openid]:[access-token|user-access-token|session-key|encrypt-key-version|ticket]"
-    },
-    "value": {
-      "bsonType": "object",
-      "description": "字段_id对应的值"
-    },
-    "expired": {
-      "bsonType": "date",
-      "description": "过期时间"
-    }
-  }
+// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema
+{
+  "bsonType": "object",
+  "required": ["_id", "value"],
+  "properties": {
+    "_id": {
+      "bsonType": "string",
+      "description": "key，格式：uni-id:[provider]:[appid]:[openid]:[access-token|user-access-token|session-key|encrypt-key-version|ticket]"
+    },
+    "value": {
+      "bsonType": "object",
+      "description": "字段_id对应的值"
+    },
+    "expired": {
+      "bsonType": "date",
+      "description": "过期时间"
+    }
+  }
 }
diff --git a/uni_modules/uni-popup/changelog.md b/uni_modules/uni-popup/changelog.md
index decd775a..505fc70c 100644
--- a/uni_modules/uni-popup/changelog.md
+++ b/uni_modules/uni-popup/changelog.md
@@ -1,3 +1,9 @@
+## 1.9.6（2025-01-08）
+- 修复 示例中过期图片地址
+## 1.9.5（2024-10-15）
+- 修复 微信小程序中的getSystemInfo警告
+## 1.9.2（2024-09-21）
+- 修复 uni-popup在android上的重复点击弹出位置不正确的bug
 ## 1.9.1（2024-04-02）
 - 修复 uni-popup-dialog vue3下使用value无法进行绑定的bug(双向绑定兼容旧写法)
 ## 1.9.0（2024-03-28）
diff --git a/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue b/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
index 7a98a31b..049cd5cf 100644
--- a/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
+++ b/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
@@ -38,25 +38,26 @@
 			}
 		},
 		data() {
-			return {
+			return {
+				// TODO 替换为自己的图标
 				bottomData: [{
 						text: '微信',
-						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
+						icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
 						name: 'wx'
 					},
 					{
 						text: '支付宝',
-						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png',
+						icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
 						name: 'ali'
 					},
 					{
 						text: 'QQ',
-						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
+						icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
 						name: 'qq'
 					},
 					{
 						text: '新浪',
-						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
+						icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
 						name: 'sina'
 					},
 					// {
diff --git a/uni_modules/uni-popup/components/uni-popup/uni-popup.vue b/uni_modules/uni-popup/components/uni-popup/uni-popup.vue
index 8349e994..5af55e01 100644
--- a/uni_modules/uni-popup/components/uni-popup/uni-popup.vue
+++ b/uni_modules/uni-popup/components/uni-popup/uni-popup.vue
@@ -192,6 +192,17 @@
 		},
 		mounted() {
 			const fixSize = () => {
+				// #ifdef MP-WEIXIN
+				const {
+					windowWidth,
+					windowHeight,
+					windowTop,
+					safeArea,
+					screenHeight,
+					safeAreaInsets
+				} = uni.getWindowInfo()
+				// #endif
+				// #ifndef MP-WEIXIN
 				const {
 					windowWidth,
 					windowHeight,
@@ -200,6 +211,7 @@
 					screenHeight,
 					safeAreaInsets
 				} = uni.getSystemInfoSync()
+				// #endif
 				this.popupWidth = windowWidth
 				this.popupHeight = windowHeight + (windowTop || 0)
 				// TODO fix by mehaotian 是否适配底部安全区 ,目前微信ios 、和 app ios 计算有差异，需要框架修复
@@ -350,6 +362,7 @@
 				this.showPopup = true
 				this.showTrans = true
 				this.$nextTick(() => {
+					this.showPoptrans()
 					if (this.messageChild && this.type === 'message') {
 						this.messageChild.timerClose()
 					}
@@ -372,8 +385,7 @@
 				}
 				// TODO 兼容 type 属性 ，后续会废弃
 				if (type) return
-				this.showPopup = true
-				this.showTrans = true
+				this.showPoptrans()
 			},
 			/**
 			 * 中间弹出样式处理
@@ -403,8 +415,7 @@
 				}
 				// TODO 兼容 type 属性 ，后续会废弃
 				if (type) return
-				this.showPopup = true
-				this.showTrans = true
+				this.showPoptrans()
 			},
 			left(type) {
 				this.popupstyle = 'left'
@@ -423,8 +434,7 @@
 				}
 				// TODO 兼容 type 属性 ，后续会废弃
 				if (type) return
-				this.showPopup = true
-				this.showTrans = true
+				this.showPoptrans()
 			},
 			right(type) {
 				this.popupstyle = 'right'
@@ -443,8 +453,13 @@
 				}
 				// TODO 兼容 type 属性 ，后续会废弃
 				if (type) return
-				this.showPopup = true
-				this.showTrans = true
+				this.showPoptrans()
+			},
+			showPoptrans(){
+				this.$nextTick(()=>{
+					this.showPopup = true
+					this.showTrans = true
+				})
 			}
 		}
 	}
diff --git a/uni_modules/uni-popup/package.json b/uni_modules/uni-popup/package.json
index 3cfa3844..da485a45 100644
--- a/uni_modules/uni-popup/package.json
+++ b/uni_modules/uni-popup/package.json
@@ -1,7 +1,7 @@
 {
 	"id": "uni-popup",
 	"displayName": "uni-popup 弹出层",
-	"version": "1.9.1",
+	"version": "1.9.6",
 	"description": " Popup 组件，提供常用的弹层",
 	"keywords": [
         "uni-ui",
@@ -51,9 +51,11 @@
 			},
 			"client": {
 				"App": {
-					"app-vue": "y",
-					"app-nvue": "y"
-				},
+                    "app-vue": "y",
+                    "app-nvue": "y",
+                    "app-harmony": "u",
+                    "app-uvue": "u"
+                },
 				"H5-mobile": {
 					"Safari": "y",
 					"Android Browser": "y",
diff --git a/uni_modules/uni-swipe-action/changelog.md b/uni_modules/uni-swipe-action/changelog.md
index 2bd523e8..5f5ed938 100644
--- a/uni_modules/uni-swipe-action/changelog.md
+++ b/uni_modules/uni-swipe-action/changelog.md
@@ -1,3 +1,10 @@
+## 1.3.13（2025-04-15）
+- 修复 app 端 缺少leftOptions 或 rightOptions 时无法滑动的问题
+## 1.3.12（2025-04-14）
+- 修复 由上一个兼容版本引发的 安卓运行报错且无法回弹的问题
+## 1.3.11（2025-04-08）
+- 优化 兼容鸿蒙平台
+- 修复 WEB 平台控制台报错
 ## 1.3.10（2024-01-17）
 - 修复 点击按钮时，按钮会被点击穿透导致自动收缩的 bug(兼容阿里/百度/抖音小程序)
 ## 1.3.9（2024-01-17）
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js
index c751a328..bfea96e7 100644
--- a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js
@@ -6,7 +6,7 @@ import {
 } from "./isPC"
 is_pc = isPC()
 // #endif
-// #ifdef APP-VUE|| MP-WEIXIN || H5
+// #ifdef APP-VUE || APP-HARMONY || MP-WEIXIN || H5
 
 mpMixins = {
 	data() {
@@ -15,11 +15,11 @@ mpMixins = {
 		}
 	},
 	watch: {
-		show(newVal) {
+		show(newVal) {
 			this.is_show = this.show
 		}
 	},
-	created() {
+	created() {
 		this.swipeaction = this.getSwipeAction()
 		if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
 			this.swipeaction.children.push(this)
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js
index 5b3fe176..2fb81a40 100644
--- a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js
@@ -1,7 +1,7 @@
 const MIN_DISTANCE = 10;
 export default {
 	showWatch(newVal, oldVal, ownerInstance, instance, self) {
-		var state = self.state
+		var state = self.state || {}
 		var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el
 		if (!$el) return
 		this.getDom(instance, ownerInstance, self)
@@ -24,7 +24,7 @@ export default {
 	touchstart(e, ownerInstance, self) {
 		let instance = e.instance;
 		let disabled = instance.getDataset().disabled
-		let state = self.state;
+		let state = self.state || {};
 		this.getDom(instance, ownerInstance, self)
 		// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
 		disabled = this.getDisabledType(disabled)
@@ -51,7 +51,7 @@ export default {
 		// 删除之后已经那不到实例了
 		if (!instance) return;
 		let disabled = instance.getDataset().disabled
-		let state = self.state
+		let state = self.state || {}
 		// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
 		disabled = this.getDisabledType(disabled)
 		if (disabled) return
@@ -76,7 +76,7 @@ export default {
 	touchend(e, ownerInstance, self) {
 		let instance = e.instance;
 		let disabled = instance.getDataset().disabled
-		let state = self.state
+		let state = self.state || {}
 		// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
 		disabled = this.getDisabledType(disabled)
 
@@ -95,7 +95,7 @@ export default {
 	 */
 	move(value, instance, ownerInstance, self) {
 		value = value || 0
-		let state = self.state
+		let state = self.state || {}
 		let leftWidth = state.leftWidth
 		let rightWidth = state.rightWidth
 		// 获取可滑动范围
@@ -115,13 +115,20 @@ export default {
 	 * @param {Object} ownerInstance
 	 */
 	getDom(instance, ownerInstance, self) {
-		var state = self.state
+		var state = self.state || {}
 		var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el
 		var leftDom = $el.querySelector('.button-group--left')
 		var rightDom = $el.querySelector('.button-group--right')
-
-		state.leftWidth = leftDom.offsetWidth || 0
-		state.rightWidth = rightDom.offsetWidth || 0
+		if (leftDom && leftDom.offsetWidth) {
+			state.leftWidth = leftDom.offsetWidth || 0
+		} else {
+			state.leftWidth = 0
+		}
+		if (rightDom && rightDom.offsetWidth) {
+			state.rightWidth = rightDom.offsetWidth || 0
+		} else {
+			state.rightWidth = 0
+		}
 		state.threshold = instance.getDataset().threshold
 	},
 
@@ -148,7 +155,7 @@ export default {
 	 * @param {Object} ins
 	 */
 	moveDirection(left, ins, ownerInstance, self) {
-		var state = self.state
+		var state = self.state || {}
 		var threshold = state.threshold
 		var position = state.position
 		var isopen = state.isopen || 'none'
@@ -181,7 +188,7 @@ export default {
 	 * @param {Object} ownerInstance
 	 */
 	openState(type, ins, ownerInstance, self) {
-		let state = self.state
+		let state = self.state || {}
 		let leftWidth = state.leftWidth
 		let rightWidth = state.rightWidth
 		let left = ''
@@ -231,7 +238,7 @@ export default {
 	 * @param {Object} event
 	 */
 	resetTouchStatus(instance, self) {
-		let state = self.state;
+		let state = self.state || {};
 		state.direction = '';
 		state.deltaX = 0;
 		state.deltaY = 0;
@@ -245,7 +252,7 @@ export default {
 	 */
 	stopTouchStart(event, ownerInstance, self) {
 		let instance = event.instance;
-		let state = self.state
+		let state = self.state || {}
 		this.resetTouchStatus(instance, self);
 		var touch = event.touches[0];
 		state.startX = touch.clientX;
@@ -258,7 +265,7 @@ export default {
 	 */
 	stopTouchMove(event, self) {
 		let instance = event.instance;
-		let state = self.state;
+		let state = self.state || {};
 		let touch = event.touches[0];
 
 		state.deltaX = touch.clientX - state.startX;
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue
index e4340dee..a62c95bf 100644
--- a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue
@@ -1,13 +1,13 @@
 <template>
 	<!-- 在微信小程序 app vue端 h5 使用wxs 实现-->
-	<!-- #ifdef APP-VUE || MP-WEIXIN || H5 -->
-	<view class="uni-swipe">
-		<!--  #ifdef MP-WEIXIN || VUE3 -->
+	<!-- #ifdef APP-VUE || APP-HARMONY || MP-WEIXIN || H5 -->
+	<view class="uni-swipe">
+		<!--  #ifdef MP-WEIXIN || H5 -->
 		<view class="uni-swipe_box" :change:prop="wxsswipe.showWatch" :prop="is_show" :data-threshold="threshold"
 			:data-disabled="disabled" @touchstart="wxsswipe.touchstart" @touchmove="wxsswipe.touchmove"
 			@touchend="wxsswipe.touchend">
-		<!-- #endif -->
-			<!--  #ifndef MP-WEIXIN || VUE3 -->
+			<!-- #endif -->
+			<!--  #ifndef MP-WEIXIN || H5 -->
 			<view class="uni-swipe_box" :change:prop="renderswipe.showWatch" :prop="is_show" :data-threshold="threshold"
 				:data-disabled="disabled+''" @touchstart="renderswipe.touchstart" @touchmove="renderswipe.touchmove"
 				@touchend="renderswipe.touchend">
@@ -142,7 +142,7 @@
 	 * @property {Boolean} autoClose = [true|false] 	滑动打开当前组件，是否关闭其他组件
 	 * @property {Number}  threshold 					滑动缺省值
 	 * @property {Array} leftOptions 					左侧选项内容及样式
-	 * @property {Array} rgihtOptions 					右侧选项内容及样式
+	 * @property {Array} rightOptions 					右侧选项内容及样式
 	 * @event {Function} click 							点击选项按钮时触发事件，e = {content,index} ，content（点击内容）、index（下标)
 	 * @event {Function} change 						组件打开或关闭时触发，left\right\none
 	 */
@@ -345,4 +345,4 @@
 	}
 
 	/* #endif */
-</style>
+</style>
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs
index 3968d370..c5bc1f85 100644
--- a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs
@@ -133,10 +133,15 @@ function getDom(instance, ownerInstance) {
 	}
 	var rightStyles = {
 		width: 0
-	}
-	leftStyles = leftDom.getBoundingClientRect()
-	rightStyles = rightDom.getBoundingClientRect()
+	}
+
+	if (leftDom) {
+		leftStyles = leftDom.getBoundingClientRect()
+	}
 
+	if (rightDom) {
+		rightStyles = rightDom.getBoundingClientRect()
+	}
 	state.leftWidth = leftStyles.width || 0
 	state.rightWidth = rightStyles.width || 0
 	state.threshold = instance.getDataset().threshold
diff --git a/uni_modules/uni-swipe-action/package.json b/uni_modules/uni-swipe-action/package.json
index 9a0c7bc1..9eeb5bc7 100644
--- a/uni_modules/uni-swipe-action/package.json
+++ b/uni_modules/uni-swipe-action/package.json
@@ -1,7 +1,7 @@
 {
 	"id": "uni-swipe-action",
 	"displayName": "uni-swipe-action 滑动操作",
-	"version": "1.3.10",
+	"version": "1.3.13",
 	"description": "SwipeAction 滑动操作操作组件",
 	"keywords": [
         "",
@@ -43,13 +43,16 @@
 		"platforms": {
 			"cloud": {
 				"tcb": "y",
-				"aliyun": "y"
+                "aliyun": "y",
+                "alipay": "n"
 			},
 			"client": {
 				"App": {
-					"app-vue": "y",
-					"app-nvue": "y"
-				},
+                    "app-vue": "y",
+                    "app-nvue": "y",
+                    "app-harmony": "u",
+                    "app-uvue": "u"
+                },
 				"H5-mobile": {
 					"Safari": "y",
 					"Android Browser": "y",
@@ -57,11 +60,11 @@
 					"QQ浏览器(Android)": "y"
 				},
 				"H5-pc": {
-					"Chrome": "y",
-					"IE": "y",
-					"Edge": "y",
-					"Firefox": "y",
-					"Safari": "y"
+					"Chrome": "u",
+					"IE": "u",
+					"Edge": "u",
+					"Firefox": "u",
+					"Safari": "u"
 				},
 				"小程序": {
 					"微信": "y",
diff --git a/uni_modules/uni-table/changelog.md b/uni_modules/uni-table/changelog.md
index 842211cc..943707bf 100644
--- a/uni_modules/uni-table/changelog.md
+++ b/uni_modules/uni-table/changelog.md
@@ -1,3 +1,7 @@
+## 1.2.8（2024-10-15）
+- 修复 运行到抖音小程序上出现的问题
+## 1.2.7（2024-10-15）
+- 修复 微信小程序中的getSystemInfo警告
 ## 1.2.4（2023-12-19）
 - 修复 uni-tr只有一列时minWidth计算错误，列变化实时计算更新
 ## 1.2.3（2023-03-28）
diff --git a/uni_modules/uni-table/components/uni-table/uni-table.vue b/uni_modules/uni-table/components/uni-table/uni-table.vue
index 9fe681d3..b37e0672 100644
--- a/uni_modules/uni-table/components/uni-table/uni-table.vue
+++ b/uni_modules/uni-table/components/uni-table/uni-table.vue
@@ -35,8 +35,13 @@
  */
 export default {
 	name: 'uniTable',
-	options: {
-		virtualHost: true
+	options: {
+		// #ifdef MP-TOUTIAO
+		virtualHost: false,
+		// #endif
+		// #ifndef MP-TOUTIAO
+		virtualHost: true
+		// #endif
 	},
 	emits:['selection-change'],
 	props: {
@@ -90,10 +95,10 @@ export default {
 			if (this.theadChildren) {
 				rowspan = this.theadChildren.rowspan
 			}
-			
+
 			// this.trChildren.length - rowspan
 			this.noData = false
-			// this.noData = newVal.length === 0 
+			// this.noData = newVal.length === 0
 		}
 	},
 	created() {
@@ -247,9 +252,9 @@ export default {
 			if (!this.theadChildren) {
 				theadChildren = this.trChildren[0]
 			}
-			
-			
-			
+
+
+
 			let childDomIndex = this.trChildren.findIndex((item, index) => child === item)
 			if(childDomIndex < 0){
 				childDomIndex = this.data.findIndex(v=>v[this.rowKey] === keyValue) + 1
diff --git a/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue b/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue
index 1d808b3b..d7cb129c 100644
--- a/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue
+++ b/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue
@@ -12,12 +12,17 @@
 <script>
 export default {
 	name: 'uniBody',
-	options: {
-		virtualHost: true
+	options: {
+		// #ifdef MP-TOUTIAO
+		virtualHost: false,
+		// #endif
+		// #ifndef MP-TOUTIAO
+		virtualHost: true
+		// #endif
 	},
 	data() {
 		return {
-			
+
 		}
 	},
 	created() {},
diff --git a/uni_modules/uni-table/components/uni-td/uni-td.vue b/uni_modules/uni-table/components/uni-td/uni-td.vue
index e0d743be..0f01f65f 100644
--- a/uni_modules/uni-table/components/uni-td/uni-td.vue
+++ b/uni_modules/uni-table/components/uni-td/uni-td.vue
@@ -10,7 +10,7 @@
 		<slot></slot>
 	</view>
 	<!-- #endif -->
-	
+
 </template>
 
 <script>
@@ -22,8 +22,13 @@
 	 */
 	export default {
 		name: 'uniTd',
-		options: {
-			virtualHost: true
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
 		},
 		props: {
 			width: {
diff --git a/uni_modules/uni-table/components/uni-th/uni-th.vue b/uni_modules/uni-table/components/uni-th/uni-th.vue
index 75fa42a8..d2c27c3d 100644
--- a/uni_modules/uni-table/components/uni-th/uni-th.vue
+++ b/uni_modules/uni-table/components/uni-th/uni-th.vue
@@ -40,8 +40,13 @@
  */
 export default {
 	name: 'uniTh',
-	options: {
-		virtualHost: true
+	options: {
+		// #ifdef MP-TOUTIAO
+		virtualHost: false,
+		// #endif
+		// #ifndef MP-TOUTIAO
+		virtualHost: true
+		// #endif
 	},
 	components: {
 		// #ifdef H5
@@ -106,8 +111,13 @@ export default {
 				if (this.width.match(regexHaveUnitPx) !== null) { // 携带了 px
 					return this.width.replace('px', '')
 				} else if (this.width.match(regexHaveUnitRpx) !== null) { // 携带了 rpx
-					let numberRpx = Number(this.width.replace('rpx', ''))
-					let widthCoe = uni.getSystemInfoSync().screenWidth / 750
+					let numberRpx = Number(this.width.replace('rpx', ''))
+					// #ifdef MP-WEIXIN
+					let widthCoe = uni.getWindowInfo().screenWidth / 750
+					// #endif
+					// #ifndef MP-WEIXIN
+					let widthCoe = uni.getSystemInfoSync().screenWidth / 750
+					// #endif
 					return Math.round(numberRpx * widthCoe)
 				} else if (this.width.match(regexHaveNotUnit) !== null) { // 未携带 rpx或px 的纯数字 String
 					return this.width
diff --git a/uni_modules/uni-table/components/uni-thead/uni-thead.vue b/uni_modules/uni-table/components/uni-thead/uni-thead.vue
index a12078aa..dea6e2b1 100644
--- a/uni_modules/uni-table/components/uni-thead/uni-thead.vue
+++ b/uni_modules/uni-table/components/uni-thead/uni-thead.vue
@@ -3,127 +3,135 @@
 	<thead class="uni-table-thead">
 		<tr class="uni-table-tr">
 			<th :rowspan="rowspan" colspan="1" class="checkbox" :class="{ 'tr-table--border': border }">
-				<table-checkbox :indeterminate="indeterminate" :checked="checked" @checkboxSelected="checkboxSelected"></table-checkbox>
+				<table-checkbox :indeterminate="indeterminate" :checked="checked"
+					@checkboxSelected="checkboxSelected"></table-checkbox>
 			</th>
 		</tr>
 		<slot></slot>
 	</thead>
 	<!-- #endif -->
 	<!-- #ifndef H5 -->
-	<view class="uni-table-thead"><slot></slot></view>
+	<view class="uni-table-thead">
+		<slot></slot>
+	</view>
 	<!-- #endif -->
 </template>
 
 <script>
-import tableCheckbox from '../uni-tr/table-checkbox.vue'
-export default {
-	name: 'uniThead',
-	components: {
-		tableCheckbox
-	},
-	options: {
-		virtualHost: true
-	},
-	data() {
-		return {
-			border: false,
-			selection: false,
-			rowspan: 1,
-			indeterminate: false,
-			checked: false
-		}
-	},
-	created() {
-		this.root = this.getTable()
-		// #ifdef H5
-		this.root.theadChildren = this
-		// #endif
-		this.border = this.root.border
-		this.selection = this.root.type
-	},
-	methods: {
-		init(self) {
-			this.rowspan++
+	import tableCheckbox from '../uni-tr/table-checkbox.vue'
+	export default {
+		name: 'uniThead',
+		components: {
+			tableCheckbox
+		},
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
 		},
-		checkboxSelected(e) {
-			this.indeterminate = false
-			const backIndexData = this.root.backIndexData
-			const data = this.root.trChildren.filter(v => !v.disabled && v.keyValue)
-			if (backIndexData.length === data.length) {
-				this.checked = false
-				this.root.clearSelection()
-			} else {
-				this.checked = true
-				this.root.selectionAll()
+		data() {
+			return {
+				border: false,
+				selection: false,
+				rowspan: 1,
+				indeterminate: false,
+				checked: false
 			}
 		},
-		/**
-		 * 获取父元素实例
-		 */
-		getTable(name = 'uniTable') {
-			let parent = this.$parent
-			let parentName = parent.$options.name
-			while (parentName !== name) {
-				parent = parent.$parent
-				if (!parent) return false
-				parentName = parent.$options.name
+		created() {
+			this.root = this.getTable()
+			// #ifdef H5
+			this.root.theadChildren = this
+			// #endif
+			this.border = this.root.border
+			this.selection = this.root.type
+		},
+		methods: {
+			init(self) {
+				this.rowspan++
+			},
+			checkboxSelected(e) {
+				this.indeterminate = false
+				const backIndexData = this.root.backIndexData
+				const data = this.root.trChildren.filter(v => !v.disabled && v.keyValue)
+				if (backIndexData.length === data.length) {
+					this.checked = false
+					this.root.clearSelection()
+				} else {
+					this.checked = true
+					this.root.selectionAll()
+				}
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getTable(name = 'uniTable') {
+				let parent = this.$parent
+				let parentName = parent.$options.name
+				while (parentName !== name) {
+					parent = parent.$parent
+					if (!parent) return false
+					parentName = parent.$options.name
+				}
+				return parent
 			}
-			return parent
 		}
 	}
-}
 </script>
 
 <style lang="scss">
-$border-color: #ebeef5;
+	$border-color: #ebeef5;
 
-.uni-table-thead {
-	display: table-header-group;
-}
+	.uni-table-thead {
+		display: table-header-group;
+	}
 
-.uni-table-tr {
-	/* #ifndef APP-NVUE */
-	display: table-row;
-	transition: all 0.3s;
-	box-sizing: border-box;
-	/* #endif */
-	border: 1px red solid;
-	background-color: #fafafa;
-}
+	.uni-table-tr {
+		/* #ifndef APP-NVUE */
+		display: table-row;
+		transition: all 0.3s;
+		box-sizing: border-box;
+		/* #endif */
+		border: 1px red solid;
+		background-color: #fafafa;
+	}
 
-.checkbox {
-	padding: 0 8px;
-	width: 26px;
-	padding-left: 12px;
-	/* #ifndef APP-NVUE */
-	display: table-cell;
-	vertical-align: middle;
-	/* #endif */
-	color: #333;
-	font-weight: 500;
-	border-bottom: 1px $border-color solid;
-	font-size: 14px;
-	// text-align: center;
-}
+	.checkbox {
+		padding: 0 8px;
+		width: 26px;
+		padding-left: 12px;
+		/* #ifndef APP-NVUE */
+		display: table-cell;
+		vertical-align: middle;
+		/* #endif */
+		color: #333;
+		font-weight: 500;
+		border-bottom: 1px $border-color solid;
+		font-size: 14px;
+		// text-align: center;
+	}
 
-.tr-table--border {
-	border-right: 1px $border-color solid;
-}
+	.tr-table--border {
+		border-right: 1px $border-color solid;
+	}
 
-/* #ifndef APP-NVUE */
-.uni-table-tr {
-	::v-deep .uni-table-th {
-		&.table--border:last-child {
-			// border-right: none;
+	/* #ifndef APP-NVUE */
+	.uni-table-tr {
+		::v-deep .uni-table-th {
+			&.table--border:last-child {
+				// border-right: none;
+			}
 		}
-	}
 
-	::v-deep .uni-table-td {
-		&.table--border:last-child {
-			// border-right: none;
+		::v-deep .uni-table-td {
+			&.table--border:last-child {
+				// border-right: none;
+			}
 		}
 	}
-}
 
-/* #endif */
+	/* #endif */
 </style>
diff --git a/uni_modules/uni-table/components/uni-tr/uni-tr.vue b/uni_modules/uni-table/components/uni-tr/uni-tr.vue
index a3b20900..56abd4bc 100644
--- a/uni_modules/uni-table/components/uni-tr/uni-tr.vue
+++ b/uni_modules/uni-table/components/uni-tr/uni-tr.vue
@@ -2,16 +2,18 @@
 	<!-- #ifdef H5 -->
 	<tr class="uni-table-tr">
 		<th v-if="selection === 'selection' && ishead" class="checkbox" :class="{ 'tr-table--border': border }">
-			<table-checkbox :checked="checked" :indeterminate="indeterminate" :disabled="disabled" @checkboxSelected="checkboxSelected"></table-checkbox>
+			<table-checkbox :checked="checked" :indeterminate="indeterminate" :disabled="disabled"
+				@checkboxSelected="checkboxSelected"></table-checkbox>
 		</th>
-		<slot></slot>
+		<slot></slot>
 		<!-- <uni-th class="th-fixed">123</uni-th> -->
 	</tr>
 	<!-- #endif -->
 	<!-- #ifndef H5 -->
 	<view class="uni-table-tr">
-		<view v-if="selection === 'selection' " class="checkbox" :class="{ 'tr-table--border': border }">
-			<table-checkbox :checked="checked" :indeterminate="indeterminate" :disabled="disabled" @checkboxSelected="checkboxSelected"></table-checkbox>
+		<view v-if="selection === 'selection' " class="checkbox" :class="{ 'tr-table--border': border }">
+			<table-checkbox :checked="checked" :indeterminate="indeterminate" :disabled="disabled"
+				@checkboxSelected="checkboxSelected"></table-checkbox>
 		</view>
 		<slot></slot>
 	</view>
@@ -20,156 +22,163 @@
 
 <script>
 	import tableCheckbox from './table-checkbox.vue'
-/**
- * Tr 表格行组件
- * @description 表格行组件 仅包含 th,td 组件
- * @tutorial https://ext.dcloud.net.cn/plugin?id=
- */
-export default {
-	name: 'uniTr',
-	components: { tableCheckbox },
-	props: {
-		disabled: {
-			type: Boolean,
-			default: false
+	/**
+	 * Tr 表格行组件
+	 * @description 表格行组件 仅包含 th,td 组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=
+	 */
+	export default {
+		name: 'uniTr',
+		components: {
+			tableCheckbox
 		},
-		keyValue: {
-			type: [String, Number],
-			default: ''
-		}
-	},
-	options: {
-		virtualHost: true
-	},
-	data() {
-		return {
-			value: false,
-			border: false,
-			selection: false,
-			widthThArr: [],
-			ishead: true,
-			checked: false,
-			indeterminate:false
-		}
-	},
-	created() {
-		this.root = this.getTable()
-		this.head = this.getTable('uniThead')
-		if (this.head) {
-			this.ishead = false
-			this.head.init(this)
-		}
-		this.border = this.root.border
-		this.selection = this.root.type
-		this.root.trChildren.push(this)
-		const rowData = this.root.data.find(v => v[this.root.rowKey] === this.keyValue)
-		if(rowData){
-			this.rowData = rowData
-		}
-		this.root.isNodata()
-	},
-	mounted() {
-		if (this.widthThArr.length > 0) {
-			const selectionWidth = this.selection === 'selection' ? 50 : 0
-			this.root.minWidth = Number(this.widthThArr.reduce((a, b) => Number(a) + Number(b))) + selectionWidth;
-		}
-	},
-	// #ifndef VUE3
-	destroyed() {
-		const index = this.root.trChildren.findIndex(i => i === this)
-		this.root.trChildren.splice(index, 1)
-		this.root.isNodata()
-	},
-	// #endif
-	// #ifdef VUE3
-	unmounted() {
-		const index = this.root.trChildren.findIndex(i => i === this)
-		this.root.trChildren.splice(index, 1)
-		this.root.isNodata()
-	},
-	// #endif
-	methods: {
-		minWidthUpdate(width) {
-			this.widthThArr.push(width)
-			if (this.widthThArr.length > 0) {
-				const selectionWidth = this.selection === 'selection' ? 50 : 0;
-				this.root.minWidth = Number(this.widthThArr.reduce((a, b) => Number(a) + Number(b))) + selectionWidth;
+		props: {
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			keyValue: {
+				type: [String, Number],
+				default: ''
 			}
 		},
-		// 选中
-		checkboxSelected(e) {
-			let rootData = this.root.data.find(v => v[this.root.rowKey] === this.keyValue)
-			this.checked = e.checked
-			this.root.check(rootData||this, e.checked,rootData? this.keyValue:null)
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
 		},
-		change(e) {
-			this.root.trChildren.forEach(item => {
-				if (item === this) {
-					this.root.check(this, e.detail.value.length > 0 ? true : false)
-				}
-			})
+		data() {
+			return {
+				value: false,
+				border: false,
+				selection: false,
+				widthThArr: [],
+				ishead: true,
+				checked: false,
+				indeterminate: false
+			}
 		},
-		/**
-		 * 获取父元素实例
-		 */
-		getTable(name = 'uniTable') {
-			let parent = this.$parent
-			let parentName = parent.$options.name
-			while (parentName !== name) {
-				parent = parent.$parent
-				if (!parent) return false
-				parentName = parent.$options.name
+		created() {
+			this.root = this.getTable()
+			this.head = this.getTable('uniThead')
+			if (this.head) {
+				this.ishead = false
+				this.head.init(this)
+			}
+			this.border = this.root.border
+			this.selection = this.root.type
+			this.root.trChildren.push(this)
+			const rowData = this.root.data.find(v => v[this.root.rowKey] === this.keyValue)
+			if (rowData) {
+				this.rowData = rowData
+			}
+			this.root.isNodata()
+		},
+		mounted() {
+			if (this.widthThArr.length > 0) {
+				const selectionWidth = this.selection === 'selection' ? 50 : 0
+				this.root.minWidth = Number(this.widthThArr.reduce((a, b) => Number(a) + Number(b))) + selectionWidth;
+			}
+		},
+		// #ifndef VUE3
+		destroyed() {
+			const index = this.root.trChildren.findIndex(i => i === this)
+			this.root.trChildren.splice(index, 1)
+			this.root.isNodata()
+		},
+		// #endif
+		// #ifdef VUE3
+		unmounted() {
+			const index = this.root.trChildren.findIndex(i => i === this)
+			this.root.trChildren.splice(index, 1)
+			this.root.isNodata()
+		},
+		// #endif
+		methods: {
+			minWidthUpdate(width) {
+				this.widthThArr.push(width)
+				if (this.widthThArr.length > 0) {
+					const selectionWidth = this.selection === 'selection' ? 50 : 0;
+					this.root.minWidth = Number(this.widthThArr.reduce((a, b) => Number(a) + Number(b))) + selectionWidth;
+				}
+			},
+			// 选中
+			checkboxSelected(e) {
+				let rootData = this.root.data.find(v => v[this.root.rowKey] === this.keyValue)
+				this.checked = e.checked
+				this.root.check(rootData || this, e.checked, rootData ? this.keyValue : null)
+			},
+			change(e) {
+				this.root.trChildren.forEach(item => {
+					if (item === this) {
+						this.root.check(this, e.detail.value.length > 0 ? true : false)
+					}
+				})
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getTable(name = 'uniTable') {
+				let parent = this.$parent
+				let parentName = parent.$options.name
+				while (parentName !== name) {
+					parent = parent.$parent
+					if (!parent) return false
+					parentName = parent.$options.name
+				}
+				return parent
 			}
-			return parent
 		}
 	}
-}
 </script>
 
 <style lang="scss">
-$border-color: #ebeef5;
+	$border-color: #ebeef5;
 
-.uni-table-tr {
-	/* #ifndef APP-NVUE */
-	display: table-row;
-	transition: all 0.3s;
-	box-sizing: border-box;
-	/* #endif */
-}
+	.uni-table-tr {
+		/* #ifndef APP-NVUE */
+		display: table-row;
+		transition: all 0.3s;
+		box-sizing: border-box;
+		/* #endif */
+	}
 
-.checkbox {
-	padding: 0 8px;
-	width: 26px;
-	padding-left: 12px;
-	/* #ifndef APP-NVUE */
-	display: table-cell;
-	vertical-align: middle;
-	/* #endif */
-	color: #333;
-	font-weight: 500;
-	border-bottom: 1px $border-color solid;
-	font-size: 14px;
-	// text-align: center;
-}
+	.checkbox {
+		padding: 0 8px;
+		width: 26px;
+		padding-left: 12px;
+		/* #ifndef APP-NVUE */
+		display: table-cell;
+		vertical-align: middle;
+		/* #endif */
+		color: #333;
+		font-weight: 500;
+		border-bottom: 1px $border-color solid;
+		font-size: 14px;
+		// text-align: center;
+	}
 
-.tr-table--border {
-	border-right: 1px $border-color solid;
-}
+	.tr-table--border {
+		border-right: 1px $border-color solid;
+	}
 
-/* #ifndef APP-NVUE */
-.uni-table-tr {
-	::v-deep .uni-table-th {
-		&.table--border:last-child {
-			// border-right: none;
+	/* #ifndef APP-NVUE */
+	.uni-table-tr {
+		::v-deep .uni-table-th {
+			&.table--border:last-child {
+				// border-right: none;
+			}
 		}
-	}
 
-	::v-deep .uni-table-td {
-		&.table--border:last-child {
-			// border-right: none;
+		::v-deep .uni-table-td {
+			&.table--border:last-child {
+				// border-right: none;
+			}
 		}
 	}
-}
 
-/* #endif */
+	/* #endif */
 </style>
diff --git a/uni_modules/uni-table/package.json b/uni_modules/uni-table/package.json
index a52821ba..19454c71 100644
--- a/uni_modules/uni-table/package.json
+++ b/uni_modules/uni-table/package.json
@@ -1,7 +1,7 @@
 {
   "id": "uni-table",
   "displayName": "uni-table 表格",
-  "version": "1.2.4",
+  "version": "1.2.8",
   "description": "表格组件，多用于展示多条结构类似的数据，如",
   "keywords": [
     "uni-ui",
@@ -42,7 +42,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
@@ -80,4 +81,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
