wangguoyu 1 ay önce
ebeveyn
işleme
f11391dfb9
100 değiştirilmiş dosya ile 5640 ekleme ve 1595 silme
  1. 1 1
      config.js
  2. 28 0
      project.config.json
  3. 7 0
      project.private.config.json
  4. 4 0
      uni_modules/uni-calendar/changelog.md
  5. 0 2
      uni_modules/uni-calendar/components/uni-calendar/calendar.js
  6. 2 1
      uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue
  7. 1 1
      uni_modules/uni-calendar/components/uni-calendar/util.js
  8. 4 3
      uni_modules/uni-calendar/package.json
  9. 1 3
      uni_modules/uni-card/components/uni-card/uni-card.vue
  10. 2 0
      uni_modules/uni-collapse/changelog.md
  11. 1 1
      uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue
  12. 4 7
      uni_modules/uni-collapse/package.json
  13. 2 0
      uni_modules/uni-combox/changelog.md
  14. 20 30
      uni_modules/uni-combox/components/uni-combox/uni-combox.vue
  15. 7 9
      uni_modules/uni-combox/package.json
  16. 6 0
      uni_modules/uni-config-center/changelog.md
  17. 81 0
      uni_modules/uni-config-center/package.json
  18. 93 0
      uni_modules/uni-config-center/readme.md
  19. 0 0
      uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js
  20. 13 0
      uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json
  21. 4 0
      uni_modules/uni-countdown/changelog.md
  22. 24 15
      uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
  23. 7 9
      uni_modules/uni-countdown/package.json
  24. 6 0
      uni_modules/uni-data-checkbox/changelog.md
  25. 316 0
      uni_modules/uni-data-checkbox/components/uni-data-checkbox/clientdb.js
  26. 80 48
      uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
  27. 7 4
      uni_modules/uni-data-checkbox/package.json
  28. 4 0
      uni_modules/uni-data-picker/changelog.md
  29. 381 0
      uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
  30. 692 0
      uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
  31. 76 0
      uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
  32. 69 0
      uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
  33. 4 3
      uni_modules/uni-data-picker/package.json
  34. 1 1
      uni_modules/uni-data-picker/readme.md
  35. 4 0
      uni_modules/uni-data-select/changelog.md
  36. 77 32
      uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue
  37. 3 2
      uni_modules/uni-data-select/package.json
  38. 38 3
      uni_modules/uni-datetime-picker/changelog.md
  39. 91 72
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue
  40. 22 16
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue
  41. 233 195
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
  42. 103 85
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
  43. 3 2
      uni_modules/uni-datetime-picker/package.json
  44. 1 1
      uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue
  45. 18 0
      uni_modules/uni-easyinput/changelog.md
  46. 0 2
      uni_modules/uni-easyinput/components/uni-easyinput/common.js
  47. 627 608
      uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
  48. 3 2
      uni_modules/uni-easyinput/package.json
  49. 2 0
      uni_modules/uni-fab/changelog.md
  50. 1 1
      uni_modules/uni-fab/components/uni-fab/uni-fab.vue
  51. 3 2
      uni_modules/uni-fab/package.json
  52. 14 0
      uni_modules/uni-file-picker/changelog.md
  53. 67 4
      uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js
  54. 12 11
      uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue
  55. 1 0
      uni_modules/uni-file-picker/components/uni-file-picker/utils.js
  56. 3 2
      uni_modules/uni-file-picker/package.json
  57. 8 0
      uni_modules/uni-forms/changelog.md
  58. 10 5
      uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue
  59. 9 2
      uni_modules/uni-forms/components/uni-forms/uni-forms.vue
  60. 3 2
      uni_modules/uni-forms/package.json
  61. 1 1
      uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue
  62. 1 1
      uni_modules/uni-grid/components/uni-grid/uni-grid.vue
  63. 20 0
      uni_modules/uni-icons/changelog.md
  64. 91 0
      uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
  65. 31 17
      uni_modules/uni-icons/components/uni-icons/uni-icons.vue
  66. 32 31
      uni_modules/uni-icons/components/uni-icons/uniicons.css
  67. BIN
      uni_modules/uni-icons/components/uni-icons/uniicons.ttf
  68. 664 0
      uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
  69. 649 0
      uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
  70. 16 13
      uni_modules/uni-icons/package.json
  71. 121 0
      uni_modules/uni-id/changelog.md
  72. 88 0
      uni_modules/uni-id/package.json
  73. 33 0
      uni_modules/uni-id/readme.md
  74. 201 0
      uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/LICENSE.md
  75. 0 0
      uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js
  76. 20 0
      uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json
  77. 1 1
      uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue
  78. 2 2
      uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue
  79. 2 0
      uni_modules/uni-list/changelog.md
  80. 1 1
      uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
  81. 7 4
      uni_modules/uni-list/package.json
  82. 3 303
      uni_modules/uni-list/readme.md
  83. 6 0
      uni_modules/uni-load-more/changelog.md
  84. 5 0
      uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
  85. 7 9
      uni_modules/uni-load-more/package.json
  86. 6 0
      uni_modules/uni-nav-bar/changelog.md
  87. 1 1
      uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue
  88. 7 1
      uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue
  89. 4 3
      uni_modules/uni-nav-bar/package.json
  90. 2 0
      uni_modules/uni-notice-bar/changelog.md
  91. 5 0
      uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue
  92. 1 1
      uni_modules/uni-notice-bar/package.json
  93. 14 0
      uni_modules/uni-number-box/changelog.md
  94. 22 11
      uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue
  95. 6 8
      uni_modules/uni-number-box/package.json
  96. 27 0
      uni_modules/uni-open-bridge-common/changelog.md
  97. 84 0
      uni_modules/uni-open-bridge-common/package.json
  98. 5 0
      uni_modules/uni-open-bridge-common/readme.md
  99. 26 0
      uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js
  100. 124 0
      uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js

+ 1 - 1
config.js

@@ -1,6 +1,6 @@
 // 应用全局配置
 export default   {
-  baseUrl: 'https://kf179.mtavip.com/api',
+  baseUrl: 'https://kf2.mtavip.com/api',
   // baseUrl: 'http://localhost:8080',
   // 应用信息
   appInfo: {

+ 28 - 0
project.config.json

@@ -0,0 +1,28 @@
+{
+  "appid": "wx26e9660e568f39d8",
+  "compileType": "miniprogram",
+  "libVersion": "3.7.11",
+  "packOptions": {
+    "ignore": [],
+    "include": []
+  },
+  "setting": {
+    "coverView": true,
+    "es6": true,
+    "postcss": true,
+    "minified": true,
+    "enhance": true,
+    "showShadowRootInWxmlPanel": true,
+    "packNpmRelationList": [],
+    "babelSetting": {
+      "ignore": [],
+      "disablePlugins": [],
+      "outputPath": ""
+    }
+  },
+  "condition": {},
+  "editorSetting": {
+    "tabIndent": "insertSpaces",
+    "tabSize": 2
+  }
+}

+ 7 - 0
project.private.config.json

@@ -0,0 +1,7 @@
+{
+  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+  "projectname": "uniProjectMain",
+  "setting": {
+    "compileHotReLoad": true
+  }
+}

+ 4 - 0
uni_modules/uni-calendar/changelog.md

@@ -1,3 +1,7 @@
+## 1.4.12(2024-09-21)
+- 修复 calendar在选择日期范围后重新选择日期需要点两次的Bug
+## 1.4.11(2024-01-10)
+- 修复 回到今天时,月份显示不一致问题
 ## 1.4.10(2023-04-10)
 - 修复 某些情况 monthSwitch 未触发的Bug
 ## 1.4.9(2023-02-02)

+ 0 - 2
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]

+ 2 - 1
uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue

@@ -328,11 +328,12 @@
 				const date = this.cale.getDate(new Date())
         const todayYearMonth = `${date.year}-${date.month}`
 
+				this.init(date.fullDate)
+
         if(nowYearMonth !== todayYearMonth) {
           this.monthSwitch()
         }
 
-				this.init(date.fullDate)
 				this.change()
 			},
 			/**

+ 1 - 1
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 {

+ 4 - 3
uni_modules/uni-calendar/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-calendar",
   "displayName": "uni-calendar 日历",
-  "version": "1.4.10",
+  "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 @@
       }
     }
   }
-}
+}

+ 1 - 3
uni_modules/uni-card/components/uni-card/uni-card.vue

@@ -21,9 +21,7 @@
 					</view>
 				</view>
 				<view class="uni-card__header-extra" @click="onClick('extra')">
-					<slot name="extra">
-						<text class="uni-card__header-extra-text">{{ extra }}</text>
-					</slot>
+					<text class="uni-card__header-extra-text">{{ extra }}</text>
 				</view>
 			</view>
 		</slot>

+ 2 - 0
uni_modules/uni-collapse/changelog.md

@@ -1,3 +1,5 @@
+## 1.4.4(2024-03-20)
+- 修复 titleBorder类型修正
 ## 1.4.3(2022-01-25)
 - 修复 初始化的时候 ,open 属性失效的bug
 ## 1.4.2(2022-01-21)

+ 1 - 1
uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue

@@ -40,7 +40,7 @@
 	 * @property {String} name 唯一标志符
 	 * @property {Boolean} open = [true|false] 是否展开组件
 	 * @property {Boolean} titleBorder = [true|false] 是否显示标题分隔线
-	 * @property {Boolean} border = [true|false] 是否显示分隔线
+	 * @property {String} border = ['auto'|'show'|'none'] 是否显示分隔线
 	 * @property {Boolean} disabled = [true|false] 是否展开面板
 	 * @property {Boolean} showAnimation = [true|false] 开启动画
 	 * @property {Boolean} showArrow = [true|false] 是否显示右侧箭头

+ 4 - 7
uni_modules/uni-collapse/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-collapse",
   "displayName": "uni-collapse 折叠面板",
-  "version": "1.4.3",
+  "version": "1.4.4",
   "description": "Collapse 组件,可以折叠 / 展开的内容区域。",
   "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": [

+ 2 - 0
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)

+ 20 - 30
uni_modules/uni-combox/components/uni-combox/uni-combox.vue

@@ -4,24 +4,25 @@
 			<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">
 			<view class="uni-popper__arrow"></view>
-			<scroll-view scroll-y="true" class="uni-combox__selector-scroll" @scroll="onScroll">
+			<scroll-view scroll-y="true" class="uni-combox__selector-scroll">
 				<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>
 		</view>
-		<!-- 新增蒙层,点击蒙层时关闭选项显示 -->
-		<view class="uni-combox__mask" v-show="showSelector" @click="showSelector = false"></view>
 	</view>
 </template>
 
@@ -41,6 +42,10 @@
 		name: 'uniCombox',
 		emits: ['input', 'update:modelValue'],
 		props: {
+			clearAble: {
+				type: Boolean,
+				default: false
+			},
 			border: {
 				type: Boolean,
 				default: true
@@ -83,8 +88,7 @@
 		data() {
 			return {
 				showSelector: false,
-				inputVal: '',
-				blurTimer:null,
+				inputVal: ''
 			}
 		},
 		computed: {
@@ -95,9 +99,6 @@
 				return `width: ${this.labelWidth}`
 			},
 			filterCandidates() {
-				if (this.inputVal !== 0 && !this.inputVal) {
-					return this.candidates
-				}
 				return this.candidates.filter((item) => {
 					return item.toString().indexOf(this.inputVal) > -1
 				})
@@ -132,16 +133,10 @@
 				this.showSelector = true
 			},
 			onBlur() {
-				this.blurTimer = setTimeout(() => {
+				setTimeout(() => {
 					this.showSelector = false
 				}, 153)
 			},
-			onScroll(){ // 滚动时将blur的定时器关掉
-				if(this.blurTimer) {
-					clearTimeout(this.blurTimer)
-					this.blurTimer = null
-				}
-			},
 			onSelectorClick(index) {
 				this.inputVal = this.filterCandidates[index]
 				this.showSelector = false
@@ -153,12 +148,16 @@
 					this.$emit('input', this.inputVal)
 					this.$emit('update:modelValue', this.inputVal)
 				})
+			},
+			clean() {
+				this.inputVal = ''
+				this.onInput()
 			}
 		}
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 	.uni-combox {
 		font-size: 14px;
 		border: 1px solid #DCDFE6;
@@ -215,7 +214,7 @@
 		border: 1px solid #EBEEF5;
 		border-radius: 6px;
 		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-		z-index: 3;
+		z-index: 2;
 		padding: 4px 0;
 	}
 
@@ -282,13 +281,4 @@
 	.uni-combox__no-border {
 		border: none;
 	}
-
-	.uni-combox__mask {
-		width:100%;
-		height:100%;
-		position: fixed;
-		top: 0;
-		left: 0;
-    z-index: 1;
-	}
 </style>

+ 7 - 9
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 @@
       }
     }
   }
-}
+}

+ 6 - 0
uni_modules/uni-config-center/changelog.md

@@ -0,0 +1,6 @@
+## 0.0.3(2022-11-11)
+- 修复 config 方法获取根节点为数组格式配置时错误的转化为了对象的Bug
+## 0.0.2(2021-04-16)
+- 修改插件package信息
+## 0.0.1(2021-03-15)
+- 初始化项目

+ 81 - 0
uni_modules/uni-config-center/package.json

@@ -0,0 +1,81 @@
+{
+  "id": "uni-config-center",
+  "displayName": "uni-config-center",
+  "version": "0.0.3",
+  "description": "uniCloud 配置中心",
+  "keywords": [
+    "配置",
+    "配置中心"
+],
+  "repository": "",
+  "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"
+  },
+  "directories": {
+    "example": "../../../scripts/dist"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "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"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "u"
+        }
+      }
+    }
+  }
+}

+ 93 - 0
uni_modules/uni-config-center/readme.md

@@ -0,0 +1,93 @@
+# 为什么使用uni-config-center
+
+实际开发中很多插件需要配置文件才可以正常运行,如果每个插件都单独进行配置的话就会产生下面这样的目录结构
+
+```bash
+cloudfunctions
+└─────common 公共模块
+        ├─plugin-a // 插件A对应的目录
+        │  ├─index.js
+        │  ├─config.json // plugin-a对应的配置文件
+        │  └─other-file.cert  // plugin-a依赖的其他文件
+        └─plugin-b // plugin-b对应的目录
+           ├─index.js
+           └─config.json // plugin-b对应的配置文件
+```
+
+假设插件作者要发布一个项目模板,里面使用了很多需要配置的插件,无论是作者发布还是用户使用都是一个大麻烦。
+
+uni-config-center就是用了统一管理这些配置文件的,使用uni-config-center后的目录结构如下
+
+```bash
+cloudfunctions
+└─────common 公共模块
+        ├─plugin-a // 插件A对应的目录
+        │  └─index.js
+        ├─plugin-b // plugin-b对应的目录
+        │  └─index.js
+        └─uni-config-center
+           ├─index.js // config-center入口文件
+           ├─plugin-a
+           │  ├─config.json  // plugin-a对应的配置文件
+           │  └─other-file.cert  // plugin-a依赖的其他文件
+           └─plugin-b
+              └─config.json  // plugin-b对应的配置文件
+```
+
+使用uni-config-center后的优势
+
+- 配置文件统一管理,分离插件主体和配置信息,更新插件更方便
+- 支持对config.json设置schema,插件使用者在HBuilderX内编写config.json文件时会有更好的提示(后续HBuilderX会提供支持)
+
+# 用法
+
+在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖,请参考:[使用公共模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common)
+
+```js
+const createConfig = require('uni-config-center')
+
+const uniIdConfig = createConfig({
+    pluginId: 'uni-id', // 插件id
+    defaultConfig: { // 默认配置
+        tokenExpiresIn: 7200,
+        tokenExpiresThreshold: 600,
+    },
+    customMerge: function(defaultConfig, userConfig) { // 自定义默认配置和用户配置的合并规则,不设置的情况侠会对默认配置和用户配置进行深度合并
+        // defaudltConfig 默认配置
+        // userConfig 用户配置
+        return Object.assign(defaultConfig, userConfig)
+    }
+})
+
+
+// 以如下配置为例
+// {
+//   "tokenExpiresIn": 7200,
+//   "passwordErrorLimit": 6,
+//   "bindTokenToDevice": false,
+//   "passwordErrorRetryTime": 3600,
+//   "app-plus": {
+//     "tokenExpiresIn": 2592000
+//   },
+//   "service": {
+//     "sms": {
+//       "codeExpiresIn": 300
+//     }
+//   }
+// }
+
+// 获取配置
+uniIdConfig.config() // 获取全部配置,注意:uni-config-center内不存在对应插件目录时会返回空对象
+uniIdConfig.config('tokenExpiresIn') // 指定键值获取配置,返回:7200
+uniIdConfig.config('service.sms.codeExpiresIn') // 指定键值获取配置,返回:300
+uniIdConfig.config('tokenExpiresThreshold', 600) // 指定键值获取配置,如果不存在则取传入的默认值,返回:600
+
+// 获取文件绝对路径
+uniIdConfig.resolve('custom-token.js') // 获取uni-config-center/uni-id/custom-token.js文件的路径
+
+// 引用文件(require)
+uniIDConfig.requireFile('custom-token.js') // 使用require方式引用uni-config-center/uni-id/custom-token.js文件。文件不存在时返回undefined,文件内有其他错误导致require失败时会抛出错误。
+
+// 判断是否包含某文件
+uniIDConfig.hasFile('custom-token.js') // 配置目录是否包含某文件,true: 文件存在,false: 文件不存在
+```

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js


+ 13 - 0
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json

@@ -0,0 +1,13 @@
+{
+    "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"
+}

+ 4 - 0
uni_modules/uni-countdown/changelog.md

@@ -1,3 +1,7 @@
+## 1.2.4(2024-09-21)
+- 新增 支持控制显示位数 默认显示2位
+## 1.2.3(2024-02-20)
+- 新增 支持控制小时,分钟的显隐:showHour showMinute
 ## 1.2.2(2022-01-19)
 - 修复 在微信小程序中样式不生效的bug
 ## 1.2.1(2022-01-18)

+ 24 - 15
uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue

@@ -2,10 +2,10 @@
 	<view class="uni-countdown">
 		<text v-if="showDay" :style="[timeStyle]" class="uni-countdown__number">{{ d }}</text>
 		<text v-if="showDay" :style="[splitorStyle]" class="uni-countdown__splitor">{{dayText}}</text>
-		<text :style="[timeStyle]" class="uni-countdown__number">{{ h }}</text>
-		<text :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : hourText }}</text>
-		<text :style="[timeStyle]" class="uni-countdown__number">{{ i }}</text>
-		<text :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : minuteText }}</text>
+		<text v-if="showHour" :style="[timeStyle]" class="uni-countdown__number">{{ h }}</text>
+		<text v-if="showHour" :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : hourText }}</text>
+		<text v-if="showMinute" :style="[timeStyle]" class="uni-countdown__number">{{ i }}</text>
+		<text v-if="showMinute" :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : minuteText }}</text>
 		<text :style="[timeStyle]" class="uni-countdown__number">{{ s }}</text>
 		<text v-if="!showColon" :style="[splitorStyle]" class="uni-countdown__splitor">{{secondText}}</text>
 	</view>
@@ -30,6 +30,8 @@
 	 * @property {Number} second 秒
 	 * @property {Number} timestamp 时间戳
 	 * @property {Boolean} showDay = [true|false] 是否显示天数
+	 * @property {Boolean} showHour = [true|false] 是否显示小时
+	 * @property {Boolean} showMinute = [true|false] 是否显示分钟
 	 * @property {Boolean} show-colon = [true|false] 是否以冒号为分隔符
 	 * @property {String} splitorColor 分割符号颜色
 	 * @event {Function} timeup 倒计时时间到触发事件
@@ -43,6 +45,14 @@
 				type: Boolean,
 				default: true
 			},
+			showHour: {
+				type: Boolean,
+				default: true
+			},
+			showMinute: {
+				type: Boolean,
+				default: true
+			},
 			showColon: {
 				type: Boolean,
 				default: true
@@ -87,9 +97,9 @@
 				type: Number,
 				default: 0
 			},
-      zeroPad: {
-				type: Boolean,
-				default: true
+			filterShow : {
+				type:Object,
+				default:{}
 			}
 		},
 		data() {
@@ -203,14 +213,13 @@
 				} else {
 					this.timeUp()
 				}
-        day = (day < 10 && this.zeroPad) ? `0${day}` : day
-				hour = (hour < 10 && this.zeroPad) ? `0${hour}` : hour
-				minute = (minute < 10 && this.zeroPad) ? `0${minute}` : minute
-				second = (second < 10 && this.zeroPad) ? `0${second}` : 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)

+ 7 - 9
uni_modules/uni-countdown/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-countdown",
   "displayName": "uni-countdown 倒计时",
-  "version": "1.2.2",
+  "version": "1.2.4",
   "description": "CountDown 倒计时组件",
   "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 @@
       }
     }
   }
-}
+}

+ 6 - 0
uni_modules/uni-data-checkbox/changelog.md

@@ -1,3 +1,9 @@
+## 1.0.6(2024-10-22)
+- 新增 当 multiple 为 false 且传递的 value 为 数组时,使用数组第一项用作反显
+## 1.0.5(2024-03-20)
+- 修复 单选模式下选中样式不生效的bug
+## 1.0.4(2024-01-27)
+- 修复 修复错别字chagne为change
 ## 1.0.3(2022-09-16)
 - 可以使用 uni-scss 控制主题色
 ## 1.0.2(2022-06-30)

+ 316 - 0
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)
+			}
+		}
+	}
+}

+ 80 - 48
uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue

@@ -2,16 +2,21 @@
 	<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>
+				<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="chagne">
-				<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">
+			<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'}">
@@ -20,13 +25,14 @@
 					</view>
 				</label>
 			</checkbox-group>
-			<radio-group v-else class="checklist-group" :class="{'is-list':mode==='list','is-wrap':wrap}" @change="chagne">
-				<!-- -->
-				<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" />
+			<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">
+						:style="item.styleBackgroud">
 						<view class="radio__inner-icon" :style="item.styleIcon"></view>
 					</view>
 					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
@@ -68,7 +74,7 @@
 	export default {
 		name: 'uniDataChecklist',
 		mixins: [uniCloud.mixinDatacom || {}],
-		emits:['input','update:modelValue','change'],
+		emits: ['input', 'update:modelValue', 'change'],
 		props: {
 			mode: {
 				type: String,
@@ -88,7 +94,7 @@
 			// TODO vue3
 			modelValue: {
 				type: [Array, String, Number],
-				default() {
+				default () {
 					return '';
 				}
 			},
@@ -122,20 +128,20 @@
 				type: String,
 				default: ''
 			},
-			emptyText:{
+			emptyText: {
 				type: String,
 				default: '暂无数据'
 			},
-			disabled:{
+			disabled: {
 				type: Boolean,
 				default: false
 			},
-			map:{
+			map: {
 				type: Object,
-				default(){
+				default () {
 					return {
-						text:'text',
-						value:'value'
+						text: 'text',
+						value: 'value'
 					}
 				}
 			}
@@ -177,18 +183,18 @@
 					contentrefresh: '加载中',
 					contentnomore: '没有更多'
 				},
-				isLocal:true,
+				isLocal: true,
 				styles: {
 					selectedColor: '#2979ff',
 					selectedTextColor: '#666',
 				},
-				isTop:0
+				isTop: 0
 			};
 		},
-		computed:{
-			dataValue(){
-				if(this.value === '')return this.modelValue
-				if(this.modelValue === '') return this.value
+		computed: {
+			dataValue() {
+				if (this.value === '') return this.modelValue
+				if (this.modelValue === '') return this.value
 				return this.value
 			}
 		},
@@ -223,15 +229,15 @@
 		},
 		methods: {
 			loadData() {
-				this.mixinDatacomGet().then(res=>{
+				this.mixinDatacomGet().then(res => {
 					this.mixinDatacomResData = res.result.data
-					if(this.mixinDatacomResData.length === 0){
+					if (this.mixinDatacomResData.length === 0) {
 						this.isLocal = false
 						this.mixinDatacomErrorMessage = this.emptyText
-					}else{
+					} else {
 						this.isLocal = true
 					}
-				}).catch(err=>{
+				}).catch(err => {
 					this.mixinDatacomErrorMessage = err.message
 				})
 			},
@@ -248,7 +254,7 @@
 				}
 				return parent;
 			},
-			chagne(e) {
+			change(e) {
 				const values = e.detail.value
 
 				let detail = {
@@ -303,6 +309,10 @@
 					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
@@ -383,13 +393,13 @@
 			 */
 			setStyleBackgroud(item) {
 				let styles = {}
-				let selectedColor = this.selectedColor?this.selectedColor:'#2979ff'
+				let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
 				if (this.selectedColor) {
 					if (this.mode !== 'list') {
-						styles['border-color'] = item.selected?selectedColor:'#DCDFE6'
+						styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
 					}
 					if (this.mode === 'tag') {
-						styles['background-color'] = item.selected? selectedColor:'#f5f5f5'
+						styles['background-color'] = item.selected ? selectedColor : '#f5f5f5'
 					}
 				}
 				let classles = ''
@@ -402,13 +412,13 @@
 				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){
+					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'
+						styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
 					}
 				}
 				for (let i in styles) {
@@ -420,13 +430,13 @@
 				let styles = {}
 				let classles = ''
 				if (this.selectedColor) {
-					let selectedColor = this.selectedColor?this.selectedColor:'#2979ff'
+					let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
 					if (this.mode === 'tag') {
-						styles.color = item.selected?(this.selectedTextColor?this.selectedTextColor:'#fff'):'#666'
+						styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : '#fff') : '#666'
 					} else {
-						styles.color = item.selected?(this.selectedTextColor?this.selectedTextColor:selectedColor):'#666'
+						styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : selectedColor) : '#666'
 					}
-					if(!item.selected && item.disabled){
+					if (!item.selected && item.disabled) {
 						styles.color = '#999'
 					}
 				}
@@ -439,7 +449,7 @@
 				let styles = {}
 				let classles = ''
 				if (this.mode === 'list') {
-					styles['border-color'] = item.selected?this.styles.selectedColor:'#DCDFE6'
+					styles['border-color'] = item.selected ? this.styles.selectedColor : '#DCDFE6'
 				}
 				for (let i in styles) {
 					classles += `${i}:${styles[i]};`
@@ -454,7 +464,7 @@
 <style lang="scss">
 	$uni-primary: #2979ff !default;
 	$border-color: #DCDFE6;
-	$disable:0.4;
+	$disable: 0.4;
 
 	@mixin flex {
 		/* #ifndef APP-NVUE */
@@ -476,6 +486,7 @@
 		position: relative;
 		z-index: 0;
 		flex: 1;
+
 		// 多选样式
 		.checklist-group {
 			@include flex;
@@ -506,6 +517,7 @@
 					flex-direction: row;
 					align-items: center;
 					justify-content: space-between;
+
 					.checklist-text {
 						font-size: 14px;
 						color: #666;
@@ -517,7 +529,7 @@
 						border-right-width: 1px;
 						border-right-color: #007aff;
 						border-right-style: solid;
-						border-bottom-width:1px;
+						border-bottom-width: 1px;
 						border-bottom-color: #007aff;
 						border-bottom-style: solid;
 						height: 12px;
@@ -542,6 +554,7 @@
 					border-radius: 4px;
 					background-color: #fff;
 					z-index: 1;
+
 					.checkbox__inner-icon {
 						position: absolute;
 						/* #ifdef APP-NVUE */
@@ -556,7 +569,7 @@
 						border-right-width: 1px;
 						border-right-color: #fff;
 						border-right-style: solid;
-						border-bottom-width:1px ;
+						border-bottom-width: 1px;
 						border-bottom-color: #fff;
 						border-bottom-style: solid;
 						opacity: 0;
@@ -597,6 +610,7 @@
 					&.is-disable {
 						/* #ifdef H5 */
 						cursor: not-allowed;
+
 						/* #endif */
 						.checkbox__inner {
 							background-color: #F2F6FC;
@@ -610,6 +624,7 @@
 							background-color: #F2F6FC;
 							border-color: $border-color;
 						}
+
 						.checklist-text {
 							color: #999;
 						}
@@ -626,16 +641,20 @@
 								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 {
@@ -645,6 +664,7 @@
 							.checklist-text {
 								opacity: $disable;
 							}
+
 							.radio__inner {
 								opacity: $disable;
 							}
@@ -667,6 +687,7 @@
 						/* #endif */
 						border: 1px #eee solid;
 						opacity: $disable;
+
 						.checkbox__inner {
 							background-color: #F2F6FC;
 							border-color: $border-color;
@@ -674,6 +695,7 @@
 							cursor: not-allowed;
 							/* #endif */
 						}
+
 						.radio__inner {
 							background-color: #F2F6FC;
 							border-color: $border-color;
@@ -681,6 +703,7 @@
 							cursor: not-allowed;
 							/* #endif */
 						}
+
 						.checklist-text {
 							color: #999;
 						}
@@ -688,9 +711,11 @@
 
 					&.is-checked {
 						border-color: $uni-primary;
+
 						.checkbox__inner {
 							border-color: $uni-primary;
 							background-color: $uni-primary;
+
 							.checkbox__inner-icon {
 								opacity: 1;
 								transform: rotate(45deg);
@@ -747,6 +772,7 @@
 						}
 					}
 				}
+
 				// 列表样式
 				&.is--list {
 					/* #ifndef APP-NVUE */
@@ -764,6 +790,7 @@
 					&.is-disable {
 						/* #ifdef H5 */
 						cursor: not-allowed;
+
 						/* #endif */
 						.checkbox__inner {
 							background-color: #F2F6FC;
@@ -772,6 +799,7 @@
 							cursor: not-allowed;
 							/* #endif */
 						}
+
 						.checklist-text {
 							color: #999;
 						}
@@ -787,11 +815,15 @@
 								transform: rotate(45deg);
 							}
 						}
+
 						.radio__inner {
+							border-color: $uni-primary;
 							.radio__inner-icon {
 								opacity: 1;
+								background-color: $uni-primary;
 							}
 						}
+
 						.checklist-text {
 							color: $uni-primary;
 						}

+ 7 - 4
uni_modules/uni-data-checkbox/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-data-checkbox",
   "displayName": "uni-data-checkbox 数据选择器",
-  "version": "1.0.3",
+  "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",

+ 4 - 0
uni_modules/uni-data-picker/changelog.md

@@ -1,3 +1,7 @@
+## 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

+ 381 - 0
uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue

@@ -0,0 +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('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>

+ 692 - 0
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts

@@ -0,0 +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,
+        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.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)
+      }
+    }
+  }
+})

+ 76 - 0
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css

@@ -0,0 +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);
+}

+ 69 - 0
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue

@@ -0,0 +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>

+ 4 - 3
uni_modules/uni-data-picker/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-data-picker",
   "displayName": "uni-data-picker 数据驱动的picker选择器",
-  "version": "1.1.2",
+  "version": "2.0.1",
   "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景",
   "keywords": [
     "uni-ui",
@@ -48,12 +48,13 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
           "app-vue": "y",
-          "app-nvue": "u"
+          "app-nvue": "y"
         },
         "H5-mobile": {
           "Safari": "y",

+ 1 - 1
uni_modules/uni-data-picker/readme.md

@@ -19,4 +19,4 @@
 在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 
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839

+ 4 - 0
uni_modules/uni-data-select/changelog.md

@@ -1,3 +1,7 @@
+## 1.0.8(2024-03-28)
+- 修复 在vue2下:style动态绑定导致编译失败的bug
+## 1.0.7(2024-01-20)
+- 修复 长文本回显超过容器的bug,超过容器部分显示省略号
 ## 1.0.6(2023-04-12)
 - 修复 微信小程序点击时会改变背景颜色的 bug
 ## 1.0.5(2023-02-03)

+ 77 - 32
uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue

@@ -4,18 +4,18 @@
 		<view class="uni-stat-box" :class="{'uni-stat__actived': current}">
 			<view class="uni-select" :class="{'uni-select--disabled':disabled}">
 				<view class="uni-select__input-box" @click="toggleSelector">
-					<view v-if="current" class="uni-select__input-text">{{current}}</view>
+					<view v-if="current" class="uni-select__input-text">{{textShow}}</view>
 					<view v-else class="uni-select__input-text uni-select__input-placeholder">{{typePlaceholder}}</view>
-					<view v-if="current && clear && !disabled" @click.stop="clearVal" >
-						<uni-icons type="clear" color="#c0c4cc" size="24"/>
+					<view v-if="current && clear && !disabled" @click.stop="clearVal">
+						<uni-icons type="clear" color="#c0c4cc" size="24" />
 					</view>
 					<view v-else>
 						<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#999" />
 					</view>
 				</view>
 				<view class="uni-select--mask" v-if="showSelector" @click="toggleSelector" />
-				<view class="uni-select__selector" v-if="showSelector">
-					<view class="uni-popper__arrow"></view>
+				<view class="uni-select__selector" :style="getOffsetByPlacement" v-if="showSelector">
+					<view :class="placement=='bottom'?'uni-popper__arrow_bottom':'uni-popper__arrow_top'"></view>
 					<scroll-view scroll-y="true" class="uni-select__selector-scroll">
 						<view class="uni-select__selector-empty" v-if="mixinDatacomResData.length === 0">
 							<text>{{emptyTips}}</text>
@@ -43,6 +43,9 @@
 	 * @property {String} label 左侧标题
 	 * @property {String} placeholder 输入框的提示文字
 	 * @property {Boolean} disabled 是否禁用
+	 * @property {String} placement 弹出位置
+	 * 	@value top   		顶部弹出
+	 * 	@value bottom		底部弹出(default)
 	 * @event {Function} change  选中发生变化触发
 	 */
 
@@ -93,6 +96,10 @@
 				type: String,
 				default: ''
 			},
+			placement: {
+				type: String,
+				default: 'bottom'
+			}
 		},
 		data() {
 			return {
@@ -125,15 +132,32 @@
 					common + placeholder :
 					common
 			},
-			valueCom(){
+			valueCom() {
 				// #ifdef VUE3
 				return this.modelValue;
 				// #endif
 				// #ifndef VUE3
 				return this.value;
 				// #endif
+			},
+			textShow() {
+				// 长文本显示
+				let text = this.current;
+				if (text.length > 10) {
+					return text.slice(0, 25) + '...';
+				}
+				return text;
+			},
+			getOffsetByPlacement() {
+				switch (this.placement) {
+					case 'top':
+						return "bottom:calc(100% + 12px);";
+					case 'bottom':
+						return "top:calc(100% + 12px);";
+				}
 			}
 		},
+
 		watch: {
 			localdata: {
 				immediate: true,
@@ -153,10 +177,11 @@
 						this.initDefVal()
 					}
 				}
-			}
+			},
+
 		},
 		methods: {
-			debounce(fn, time = 100){
+			debounce(fn, time = 100) {
 				let timer = null
 				return function(...args) {
 					if (timer) clearTimeout(timer)
@@ -166,11 +191,11 @@
 				}
 			},
 			// 执行数据库查询
-			query(){
+			query() {
 				this.mixinDatacomEasyGet();
 			},
 			// 监听查询条件变更事件
-			onMixinDatacomPropsChange(){
+			onMixinDatacomPropsChange() {
 				if (this.collection) {
 					this.debounceGet();
 				}
@@ -193,9 +218,9 @@
 						}
 						defValue = defItem
 					}
-          if (defValue || defValue === 0) {
-					  this.emit(defValue)
-          }
+					if (defValue || defValue === 0) {
+						this.emit(defValue)
+					}
 				}
 				const def = this.mixinDatacomResData.find(item => item.value === defValue)
 				this.current = def ? this.formatItemName(def) : ''
@@ -258,7 +283,7 @@
 					let str = "";
 					str = this.format;
 					for (let key in item) {
-						str = str.replace(new RegExp(`{${key}}`,"g"),item[key]);
+						str = str.replace(new RegExp(`{${key}}`, "g"), item[key]);
 					}
 					return str;
 				} else {
@@ -272,26 +297,26 @@
 				}
 			},
 			// 获取当前加载的数据
-			getLoadData(){
+			getLoadData() {
 				return this.mixinDatacomResData;
 			},
 			// 获取当前缓存key
-			getCurrentCacheKey(){
+			getCurrentCacheKey() {
 				return this.collection;
 			},
 			// 获取缓存
-			getCache(name=this.getCurrentCacheKey()){
+			getCache(name = this.getCurrentCacheKey()) {
 				let cacheData = uni.getStorageSync(this.cacheKey) || {};
 				return cacheData[name];
 			},
 			// 设置缓存
-			setCache(value, name=this.getCurrentCacheKey()){
+			setCache(value, name = this.getCurrentCacheKey()) {
 				let cacheData = uni.getStorageSync(this.cacheKey) || {};
 				cacheData[name] = value;
 				uni.setStorageSync(this.cacheKey, cacheData);
 			},
 			// 删除缓存
-			removeCache(name=this.getCurrentCacheKey()){
+			removeCache(name = this.getCurrentCacheKey()) {
 				let cacheData = uni.getStorageSync(this.cacheKey) || {};
 				delete cacheData[name];
 				uni.setStorageSync(this.cacheKey, cacheData);
@@ -306,7 +331,6 @@
 	$uni-secondary-color: #909399 !default;
 	$uni-border-3: #e5e5e5;
 
-
 	/* #ifndef APP-NVUE */
 	@media screen and (max-width: 500px) {
 		.hide-on-phone {
@@ -407,7 +431,6 @@
 		box-sizing: border-box;
 		/* #endif */
 		position: absolute;
-		top: calc(100% + 12px);
 		left: 0;
 		width: 100%;
 		background-color: #FFFFFF;
@@ -431,6 +454,7 @@
 			max-height: 600px;
 		}
 	}
+
 	/* #endif */
 
 	.uni-select__selector-empty,
@@ -463,18 +487,21 @@
 	}
 
 	/* picker 弹出层通用的指示小三角 */
-	.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_bottom,
+	.uni-popper__arrow_bottom::after,
+	.uni-popper__arrow_top,
+	.uni-popper__arrow_top::after,
+	{
+	position: absolute;
+	display: block;
+	width: 0;
+	height: 0;
+	border-color: transparent;
+	border-style: solid;
+	border-width: 6px;
 	}
 
-	.uni-popper__arrow {
+	.uni-popper__arrow_bottom {
 		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
 		top: -6px;
 		left: 10%;
@@ -483,7 +510,7 @@
 		border-bottom-color: #EBEEF5;
 	}
 
-	.uni-popper__arrow::after {
+	.uni-popper__arrow_bottom::after {
 		content: " ";
 		top: 1px;
 		margin-left: -6px;
@@ -491,6 +518,24 @@
 		border-bottom-color: #fff;
 	}
 
+	.uni-popper__arrow_top {
+		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+		bottom: -6px;
+		left: 10%;
+		margin-right: 3px;
+		border-bottom-width: 0;
+		border-top-color: #EBEEF5;
+	}
+
+	.uni-popper__arrow_top::after {
+		content: " ";
+		bottom: 1px;
+		margin-left: -6px;
+		border-bottom-width: 0;
+		border-top-color: #fff;
+	}
+
+
 	.uni-select__input-text {
 		// width: 280px;
 		width: 100%;

+ 3 - 2
uni_modules/uni-data-select/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-data-select",
   "displayName": "uni-data-select 下拉框选择器",
-  "version": "1.0.6",
+  "version": "1.0.8",
   "description": "通过数据驱动的下拉框选择器",
   "keywords": [
     "uni-ui",
@@ -43,7 +43,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {

+ 38 - 3
uni_modules/uni-datetime-picker/changelog.md

@@ -1,13 +1,48 @@
+## 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)
+- 修复 抖音小程序事件传递失效bug
+## 2.2.32(2024-02-20)
+- 修复 日历的close事件触发异常的bug [详情](https://github.com/dcloudio/uni-ui/issues/844)
+## 2.2.31(2024-02-20)
+- 修复 h5平台 右边日历的月份默认+1的bug [详情](https://github.com/dcloudio/uni-ui/issues/841)
+## 2.2.30(2024-01-31)
+- 修复 隐藏“秒”时,在IOS15及以下版本时出现 结束时间在开始时间之前 的bug [详情](https://github.com/dcloudio/uni-ui/issues/788)
+## 2.2.29(2024-01-20)
+- 新增 show事件,弹窗弹出时触发该事件 [详情](https://github.com/dcloudio/uni-app/issues/4694)
+## 2.2.28(2024-01-18)
+- 去除 noChange事件,当进行日期范围选择时,若只选了一天,则开始结束日期都为同一天 [详情](https://github.com/dcloudio/uni-ui/issues/815)
+## 2.2.27(2024-01-10)
+- 优化 增加noChange事件,当进行日期范围选择时,若有空值,则触发该事件 [详情](https://github.com/dcloudio/uni-ui/issues/815)
+## 2.2.26(2024-01-08)
+- 修复 字节小程序时间选择范围器失效问题 [详情](https://github.com/dcloudio/uni-ui/issues/834)
+## 2.2.25(2023-10-18)
+- 修复 PC端初次修改时间,开始时间未更新的Bug [详情](https://github.com/dcloudio/uni-ui/issues/737)
+## 2.2.24(2023-06-02)
+- 修复 部分情况修改时间,开始、结束时间显示异常的Bug [详情](https://ask.dcloud.net.cn/question/171146)
+- 优化 当前月可以选择上月、下月的日期的Bug
+## 2.2.23(2023-05-02)
+- 修复 部分情况修改时间,开始时间未更新的Bug [详情](https://github.com/dcloudio/uni-ui/issues/737)
+- 修复 部分平台及设备第一次点击无法显示弹框的Bug
+- 修复 ios 日期格式未补零显示及使用异常的Bug [详情](https://ask.dcloud.net.cn/question/162979)
 ## 2.2.22(2023-03-30)
-- 修复 日历 picker 修改年月后,自动选中当月1日 [详情](https://ask.dcloud.net.cn/question/165937)
-- 修复 小程序端 低版本 ios NaN [详情](https://ask.dcloud.net.cn/question/162979)
+- 修复 日历 picker 修改年月后,自动选中当月1日的Bug [详情](https://ask.dcloud.net.cn/question/165937)
+- 修复 小程序端 低版本 ios NaN的Bug [详情](https://ask.dcloud.net.cn/question/162979)
 ## 2.2.21(2023-02-20)
 - 修复 firefox 浏览器显示区域点击无法拉起日历弹框的Bug [详情](https://ask.dcloud.net.cn/question/163362)
 ## 2.2.20(2023-02-17)
 - 优化 值为空依然选中当天问题
 - 优化 提供 default-value 属性支持配置选择器打开时默认显示的时间
 - 优化 非范围选择未选择日期时间,点击确认按钮选中当前日期时间
-- 优化 字节小程序日期时间范围选择,底部日期换行问题
+- 优化 字节小程序日期时间范围选择,底部日期换行的Bug
 ## 2.2.19(2023-02-09)
 - 修复 2.2.18 引起范围选择配置 end 选择无效的Bug [详情](https://github.com/dcloudio/uni-ui/issues/686)
 ## 2.2.18(2023-02-08)

+ 91 - 72
uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue

@@ -21,7 +21,7 @@
 					<view class="uni-calendar__header-btn uni-calendar--right"></view>
 				</view>
 
-				<view v-if="!insert" class="dialog-close" @click="close">
+				<view v-if="!insert" class="dialog-close" @click="maskClick">
 					<view class="dialog-close-plus" data-id="close"></view>
 					<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
 				</view>
@@ -58,9 +58,8 @@
 
 				<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
 					<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
-						<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar"
-							:selected="selected" :checkHover="range" @change="choiceDate"
-							@handleMouse="handleMouse">
+						<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" :selected="selected"
+							:checkHover="range" @change="choiceDate" @handleMouse="handleMouse">
 						</calendar-item>
 					</view>
 				</view>
@@ -101,13 +100,21 @@
 </template>
 
 <script>
-	import { Calendar, getDate, getTime } from './util.js';
+	import {
+		Calendar,
+		getDate,
+		getTime
+	} from './util.js';
 	import calendarItem from './calendar-item.vue'
 	import timePicker from './time-picker.vue'
 
-	import { initVueI18n } from '@dcloudio/uni-i18n'
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
 	import i18nMessages from './i18n/index.js'
-	const { t } = initVueI18n(i18nMessages)
+	const {
+		t
+	} = initVueI18n(i18nMessages)
 
 	/**
 	 * Calendar 日历
@@ -134,6 +141,15 @@
 			calendarItem,
 			timePicker
 		},
+
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
 		props: {
 			date: {
 				type: String,
@@ -163,8 +179,8 @@
 				type: String,
 				default: ''
 			},
-      startPlaceholder: {
-        type: String,
+			startPlaceholder: {
+				type: String,
 				default: ''
 			},
 			endPlaceholder: {
@@ -210,10 +226,10 @@
 					}
 				}
 			},
-      defaultValue: {
-        type: [String, Object, Array],
-        default: ''
-      }
+			defaultValue: {
+				type: [String, Object, Array],
+				default: ''
+			}
 		},
 		data() {
 			return {
@@ -260,7 +276,7 @@
 			},
 			startDate(val) {
 				// 字节小程序 watch 早于 created
-				if(!this.cale){
+				if (!this.cale) {
 					return
 				}
 				this.cale.setStartDate(val)
@@ -269,7 +285,7 @@
 			},
 			endDate(val) {
 				// 字节小程序 watch 早于 created
-				if(!this.cale){
+				if (!this.cale) {
 					return
 				}
 				this.cale.setEndDate(val)
@@ -278,7 +294,7 @@
 			},
 			selected(newVal) {
 				// 字节小程序 watch 早于 created
-				if(!this.cale){
+				if (!this.cale) {
 					return
 				}
 				this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
@@ -309,16 +325,16 @@
 								this.cale.lastHover = false
 							}
 						} else {
-              // 字节小程序 watch 早于 created
-              if(!this.cale){
-                return
-              }
+							// 字节小程序 watch 早于 created
+							if (!this.cale) {
+								return
+							}
 
 							this.cale.setDefaultMultiple(before, after)
 							if (which === 'left' && before) {
 								this.setDate(before)
 								this.weeks = this.cale.weeks
-							} else if(after) {
+							} else if (after) {
 								this.setDate(after)
 								this.weeks = this.cale.weeks
 							}
@@ -423,7 +439,7 @@
 			},
 			// 蒙版点击事件
 			maskClick() {
-        this.close()
+				this.close()
 				this.$emit('maskClose')
 			},
 
@@ -454,36 +470,38 @@
 			 * @param {Object} date
 			 */
 			init(date) {
-        // 字节小程序 watch 早于 created
-				if(!this.cale){
+				// 字节小程序 watch 早于 created
+				if (!this.cale) {
 					return
 				}
 				this.cale.setDate(date || new Date())
 				this.weeks = this.cale.weeks
 				this.nowDate = this.cale.getInfo(date)
-        this.calendar = {...this.nowDate}
-        if(!date){
-          // 优化date为空默认不选中今天
-          this.calendar.fullDate = ''
-          if(this.defaultValue && !this.range){
-            // 暂时只支持移动端非范围选择
-            const defaultDate = new Date(this.defaultValue)
-            const fullDate = getDate(defaultDate)
-            const year = defaultDate.getFullYear()
-            const month = defaultDate.getMonth()+1
-            const date = defaultDate.getDate()
-            const day = defaultDate.getDay()
-            this.calendar = {
-              fullDate,
-              year,
-              month,
-              date,
-              day
-            },
-            this.tempSingleDate = fullDate
-            this.time = getTime(defaultDate, this.hideSecond)
-          }
-        }
+				this.calendar = {
+					...this.nowDate
+				}
+				if (!date) {
+					// 优化date为空默认不选中今天
+					this.calendar.fullDate = ''
+					if (this.defaultValue && !this.range) {
+						// 暂时只支持移动端非范围选择
+						const defaultDate = new Date(this.defaultValue)
+						const fullDate = getDate(defaultDate)
+						const year = defaultDate.getFullYear()
+						const month = defaultDate.getMonth() + 1
+						const date = defaultDate.getDate()
+						const day = defaultDate.getDay()
+						this.calendar = {
+								fullDate,
+								year,
+								month,
+								date,
+								day
+							},
+							this.tempSingleDate = fullDate
+						this.time = getTime(defaultDate, this.hideSecond)
+					}
+				}
 			},
 			/**
 			 * 打开日历弹窗
@@ -523,8 +541,8 @@
 			/**
 			 * 变化触发
 			 */
-			change() {
-				if (!this.insert) return
+			change(isSingleChange) {
+				if (!this.insert && !isSingleChange) return
 				this.setEmit('change')
 			},
 			/**
@@ -545,13 +563,13 @@
 			 * @param {Object} name
 			 */
 			setEmit(name) {
-        if(!this.range){
-					if(!this.calendar.fullDate){
-					  this.calendar = this.cale.getInfo(new Date())
-					  this.tempSingleDate = this.calendar.fullDate
+				if (!this.range) {
+					if (!this.calendar.fullDate) {
+						this.calendar = this.cale.getInfo(new Date())
+						this.tempSingleDate = this.calendar.fullDate
 					}
-					if(this.hasTime && !this.time) {
-					  this.time = getTime(new Date(), this.hideSecond)
+					if (this.hasTime && !this.time) {
+						this.time = getTime(new Date(), this.hideSecond)
 					}
 				}
 				let {
@@ -593,19 +611,19 @@
 					this.tempRange.before = this.cale.multipleStatus.before
 					this.tempRange.after = this.cale.multipleStatus.after
 				}
-				this.change()
-			},
-      changeMonth(type) {
-        let newDate
-        if(type === 'pre') {
-          newDate = this.cale.getPreMonthObj(this.nowDate.fullDate).fullDate
-        } else if(type === 'next') {
-          newDate = this.cale.getNextMonthObj(this.nowDate.fullDate).fullDate
-        }
+				this.change(true)
+			},
+			changeMonth(type) {
+				let newDate
+				if (type === 'pre') {
+					newDate = this.cale.getPreMonthObj(this.nowDate.fullDate).fullDate
+				} else if (type === 'next') {
+					newDate = this.cale.getNextMonthObj(this.nowDate.fullDate).fullDate
+				}
 
-        this.setDate(newDate)
+				this.setDate(newDate)
 				this.monthSwitch()
-      },
+			},
 			/**
 			 * 设置日期
 			 * @param {Object} date
@@ -619,7 +637,7 @@
 	}
 </script>
 
-<style lang="scss" >
+<style lang="scss">
 	$uni-primary: #007aff !default;
 
 	.uni-calendar {
@@ -855,17 +873,17 @@
 
 	.uni-date-changed--time-end {
 		/* #ifndef APP-NVUE */
-    display: flex;
+		display: flex;
 		/* #endif */
 		align-items: center;
 	}
 
 	.uni-date-changed--time-date {
-    color: #999;
+		color: #999;
 		line-height: 50px;
-    /* #ifdef MP-TOUTIAO */
-    font-size: 16px;
-    /* #endif */
+		/* #ifdef MP-TOUTIAO */
+		font-size: 16px;
+		/* #endif */
 		margin-right: 5px;
 		// opacity: 0.6;
 	}
@@ -924,5 +942,6 @@
 	.uni-datetime-picker--btn:active {
 		opacity: 0.7;
 	}
+
 	/* #endif */
 </style>

+ 22 - 16
uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue

@@ -81,10 +81,16 @@
 </template>
 
 <script>
-	import { initVueI18n } from '@dcloudio/uni-i18n'
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
 	import i18nMessages from './i18n/index.js'
-	const {	t	} = initVueI18n(i18nMessages)
-  import { fixIosDateFormat } from './util'
+	const {
+		t
+	} = initVueI18n(i18nMessages)
+	import {
+		fixIosDateFormat
+	} from './util'
 
 	/**
 	 * DatetimePicker 时间选择器
@@ -134,6 +140,14 @@
 				endSecond: 59,
 			}
 		},
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
 		props: {
 			type: {
 				type: String,
@@ -176,11 +190,11 @@
 			// #ifndef VUE3
 			value: {
 				handler(newVal) {
-          if (newVal) {
-            this.parseValue(fixIosDateFormat(newVal))
+					if (newVal) {
+						this.parseValue(fixIosDateFormat(newVal))
 						this.initTime(false)
 					} else {
-            this.time = ''
+						this.time = ''
 						this.parseValue(Date.now())
 					}
 				},
@@ -189,8 +203,8 @@
 			// #endif
 			// #ifdef VUE3
 			modelValue: {
-        handler(newVal) {
-          if (newVal) {
+				handler(newVal) {
+					if (newVal) {
 						this.parseValue(fixIosDateFormat(newVal))
 						this.initTime(false)
 					} else {
@@ -649,14 +663,6 @@
 				return new Date(year, month, 0).getDate();
 			},
 
-			//兼容 iOS、safari 日期格式
-			fixIosDateFormat(value) {
-				if (typeof value === 'string') {
-					value = value.replace(/-/g, '/')
-				}
-				return value
-			},
-
 			/**
 			 * 生成时间戳
 			 * @param {Object} time

+ 233 - 195
uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue

@@ -2,22 +2,20 @@
 	<view class="uni-date">
 		<view class="uni-date-editor" @click="show">
 			<slot>
-				<view
-          class="uni-date-editor--x"
-          :class="{'uni-date-editor--x__disabled': disabled,'uni-date-x--border': border}"
-        >
+				<view class="uni-date-editor--x"
+					:class="{'uni-date-editor--x__disabled': disabled,'uni-date-x--border': border}">
 					<view v-if="!isRange" class="uni-date-x uni-date-single">
 						<uni-icons class="icon-calendar" type="calendar" color="#c0c4cc" size="22"></uni-icons>
 						<view class="uni-date__x-input">{{ displayValue || singlePlaceholderText }}</view>
 					</view>
 
 					<view v-else class="uni-date-x uni-date-range">
-            <uni-icons class="icon-calendar" type="calendar" color="#c0c4cc" size="22"></uni-icons>
-            <view class="uni-date__x-input text-center">{{ displayRangeValue.startDate || startPlaceholderText }}</view>
+						<uni-icons class="icon-calendar" type="calendar" color="#c0c4cc" size="22"></uni-icons>
+						<view class="uni-date__x-input text-center">{{ displayRangeValue.startDate || startPlaceholderText }}</view>
 
-            <view class="range-separator">{{rangeSeparator}}</view>
+						<view class="range-separator">{{rangeSeparator}}</view>
 
-            <view class="uni-date__x-input text-center">{{ displayRangeValue.endDate || endPlaceholderText }}</view>
+						<view class="uni-date__x-input text-center">{{ displayRangeValue.endDate || endPlaceholderText }}</view>
 					</view>
 
 					<view v-if="showClearIcon" class="uni-date__icon-clear" @click.stop="clear">
@@ -34,8 +32,7 @@
 				<view class="uni-popper__arrow"></view>
 
 				<view v-if="hasTime" class="uni-date-changed popup-x-header">
-					<input class="uni-date__input text-center" type="text" v-model="inputDate"
-						:placeholder="selectDateText" />
+					<input class="uni-date__input text-center" type="text" v-model="inputDate" :placeholder="selectDateText" />
 
 					<time-picker type="time" v-model="pickerTime" :border="false" :disabled="!inputDate"
 						:start="timepickerStartTime" :end="timepickerEndTime" :hideSecond="hideSecond" style="width: 100%;">
@@ -45,8 +42,7 @@
 				</view>
 
 				<Calendar ref="pcSingle" :showMonth="false" :start-date="calendarRange.startDate"
-					:end-date="calendarRange.endDate" :date="calendarDate" @change="singleChange"
-          :default-value="defaultValue"
+					:end-date="calendarRange.endDate" :date="calendarDate" @change="singleChange" :default-value="defaultValue"
 					style="padding: 0 8px;" />
 
 				<view v-if="hasTime" class="popup-x-footer">
@@ -58,18 +54,17 @@
 				<view class="uni-popper__arrow"></view>
 				<view v-if="hasTime" class="popup-x-header uni-date-changed">
 					<view class="popup-x-header--datetime">
-            <input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.startDate"
-            :placeholder="startDateText" />
+						<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.startDate"
+							:placeholder="startDateText" />
 
 						<time-picker type="time" v-model="tempRange.startTime" :start="timepickerStartTime" :border="false"
-            :disabled="!tempRange.startDate" :hideSecond="hideSecond">
-            <input class="uni-date__input uni-date-range__input" type="text"
-            v-model="tempRange.startTime" :placeholder="startTimeText"
-            :disabled="!tempRange.startDate" />
-          </time-picker>
-        </view>
+							:disabled="!tempRange.startDate" :hideSecond="hideSecond">
+							<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.startTime"
+								:placeholder="startTimeText" :disabled="!tempRange.startDate" />
+						</time-picker>
+					</view>
 
-        <uni-icons type="arrowthinright" color="#999" style="line-height: 40px;"></uni-icons>
+					<uni-icons type="arrowthinright" color="#999" style="line-height: 40px;"></uni-icons>
 
 					<view class="popup-x-header--datetime">
 						<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.endDate"
@@ -85,12 +80,11 @@
 
 				<view class="popup-x-body">
 					<Calendar ref="left" :showMonth="false" :start-date="calendarRange.startDate"
-            :end-date="calendarRange.endDate" :range="true" :pleStatus="endMultipleStatus"
-            @change="leftChange" @firstEnterCale="updateRightCale" style="padding: 0 8px;" />
+						:end-date="calendarRange.endDate" :range="true" :pleStatus="endMultipleStatus" @change="leftChange"
+						@firstEnterCale="updateRightCale" style="padding: 0 8px;"/>
 					<Calendar ref="right" :showMonth="false" :start-date="calendarRange.startDate"
-						:end-date="calendarRange.endDate" :range="true" @change="rightChange"
-						:pleStatus="startMultipleStatus" @firstEnterCale="updateLeftCale"
-						style="padding: 0 8px;border-left: 1px solid #F1F1F1;" />
+						:end-date="calendarRange.endDate" :range="true" @change="rightChange" :pleStatus="startMultipleStatus"
+						@firstEnterCale="updateLeftCale" style="padding: 0 8px;border-left: 1px solid #F1F1F1;" />
 				</view>
 
 				<view v-if="hasTime" class="popup-x-footer">
@@ -102,10 +96,9 @@
 
 		<Calendar v-if="isPhone" ref="mobile" :clearDate="false" :date="calendarDate" :defTime="mobileCalendarTime"
 			:start-date="calendarRange.startDate" :end-date="calendarRange.endDate" :selectableTimes="mobSelectableTime"
-      :startPlaceholder="startPlaceholder" :endPlaceholder="endPlaceholder"
-      :default-value="defaultValue"
+			:startPlaceholder="startPlaceholder" :endPlaceholder="endPlaceholder" :default-value="defaultValue"
 			:pleStatus="endMultipleStatus" :showMonth="false" :range="isRange" :hasTime="hasTime" :insert="false"
-			:hideSecond="hideSecond" @confirm="mobileChange" @maskClose="close" />
+			:hideSecond="hideSecond" @confirm="mobileChange" @maskClose="close" @change="calendarClick"/>
 	</view>
 </template>
 <script>
@@ -133,14 +126,30 @@
 	 **/
 	import Calendar from './calendar.vue'
 	import TimePicker from './time-picker.vue'
-	import { initVueI18n } from '@dcloudio/uni-i18n'
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
 	import i18nMessages from './i18n/index.js'
-  import { getDateTime, getDate, getTime, getDefaultSecond, dateCompare, checkDate, fixIosDateFormat } from './util'
+	import {
+		getDateTime,
+		getDate,
+		getTime,
+		getDefaultSecond,
+		dateCompare,
+		checkDate,
+		fixIosDateFormat
+	} from './util'
 
 	export default {
 		name: 'UniDatetimePicker',
+
 		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
 			virtualHost: true
+			// #endif
 		},
 		components: {
 			Calendar,
@@ -188,7 +197,7 @@
 				isEmitValue: false,
 				isPhone: false,
 				isFirstShow: true,
-        i18nT: () => {}
+				i18nT: () => {}
 			}
 		},
 		props: {
@@ -221,7 +230,7 @@
 				default: ''
 			},
 			startPlaceholder: {
-        type: String,
+				type: String,
 				default: ''
 			},
 			endPlaceholder: {
@@ -248,16 +257,16 @@
 				type: [Boolean],
 				default: false
 			},
-      defaultValue: {
-        type: [String, Object, Array],
-        default: ''
-      }
+			defaultValue: {
+				type: [String, Object, Array],
+				default: ''
+			}
 		},
 		watch: {
 			type: {
 				immediate: true,
 				handler(newVal) {
-          this.hasTime = newVal.indexOf('time') !== -1
+					this.hasTime = newVal.indexOf('time') !== -1
 					this.isRange = newVal.indexOf('range') !== -1
 				}
 			},
@@ -348,9 +357,9 @@
 			selectDateText() {
 				return this.i18nT("uni-datetime-picker.selectDate")
 			},
-      selectDateTimeText() {
-        return this.i18nT("uni-datetime-picker.selectDateTime")
-      },
+			selectDateTimeText() {
+				return this.i18nT("uni-datetime-picker.selectDateTime")
+			},
 			selectTimeText() {
 				return this.i18nT("uni-datetime-picker.selectTime")
 			},
@@ -373,18 +382,19 @@
 				return this.i18nT("uni-datetime-picker.clear")
 			},
 			showClearIcon() {
-				return this.clearIcon && !this.disabled && (this.displayValue || (this.displayRangeValue.startDate && this.displayRangeValue.endDate))
+				return this.clearIcon && !this.disabled && (this.displayValue || (this.displayRangeValue.startDate && this
+					.displayRangeValue.endDate))
 			}
 		},
 		created() {
 			this.initI18nT()
-      this.platform()
+			this.platform()
 		},
 		methods: {
-      initI18nT() {
-        const vueI18n = initVueI18n(i18nMessages)
-        this.i18nT = vueI18n.t
-      },
+			initI18nT() {
+				const vueI18n = initVueI18n(i18nMessages)
+				this.i18nT = vueI18n.t
+			},
 			initPicker(newVal) {
 				if ((!newVal && !this.defaultValue) || Array.isArray(newVal) && !newVal.length) {
 					this.$nextTick(() => {
@@ -394,26 +404,26 @@
 				}
 
 				if (!Array.isArray(newVal) && !this.isRange) {
-          if(newVal){
-            this.displayValue = this.inputDate = this.calendarDate = getDate(newVal)
-            if (this.hasTime) {
-              this.pickerTime = getTime(newVal, this.hideSecond)
-              this.displayValue = `${this.displayValue} ${this.pickerTime}`
-            }
-          }else if(this.defaultValue){
-            this.inputDate = this.calendarDate = getDate(this.defaultValue)
-            if(this.hasTime){
-              this.pickerTime = getTime(this.defaultValue, this.hideSecond)
-            }
-          }
+					if (newVal) {
+						this.displayValue = this.inputDate = this.calendarDate = getDate(newVal)
+						if (this.hasTime) {
+							this.pickerTime = getTime(newVal, this.hideSecond)
+							this.displayValue = `${this.displayValue} ${this.pickerTime}`
+						}
+					} else if (this.defaultValue) {
+						this.inputDate = this.calendarDate = getDate(this.defaultValue)
+						if (this.hasTime) {
+							this.pickerTime = getTime(this.defaultValue, this.hideSecond)
+						}
+					}
 				} else {
 					const [before, after] = newVal
 					if (!before && !after) return
-          const beforeDate = getDate(before)
-          const beforeTime = getTime(before, this.hideSecond)
+					const beforeDate = getDate(before)
+					const beforeTime = getTime(before, this.hideSecond)
 
-          const afterDate = getDate(after)
-          const afterTime = getTime(after, this.hideSecond)
+					const afterDate = getDate(after)
+					const afterTime = getTime(after, this.hideSecond)
 					const startDate = beforeDate
 					const endDate = afterDate
 					this.displayRangeValue.startDate = this.tempRange.startDate = startDate
@@ -450,17 +460,33 @@
 				right.setDate(this.$refs.right.nowDate.fullDate)
 			},
 			platform() {
-				const { windowWidth } = uni.getSystemInfoSync()
+				if (typeof navigator !== "undefined") {
+					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
 			},
 			show() {
+				this.$emit("show")
 				if (this.disabled) {
 					return
 				}
 				this.platform()
 				if (this.isPhone) {
-					this.$refs.mobile.open()
+					setTimeout(() => {
+						this.$refs.mobile.open()
+					}, 0);
 					return
 				}
 				this.pickerPositionStyle = {
@@ -485,8 +511,10 @@
 								this.$refs.right.changeMonth('pre')
 							}
 						} else {
-							this.$refs.right.changeMonth('next')
-							this.$refs.right.cale.lastHover = false
+							// this.$refs.right.changeMonth('next')
+							if (this.isPhone) {
+								this.$refs.right.cale.lastHover = false;
+							}
 						}
 					}
 
@@ -538,52 +566,52 @@
 				this.confirmSingleChange()
 			},
 			confirmSingleChange() {
-        if(!checkDate(this.inputDate)){
+				if (!checkDate(this.inputDate)) {
 					const now = new Date()
-          this.calendarDate = this.inputDate = getDate(now)
+					this.calendarDate = this.inputDate = getDate(now)
 					this.pickerTime = getTime(now, this.hideSecond)
-        }
-
-        let startLaterInputDate = false
-        let startDate, startTime
-        if(this.start) {
-          let startString = this.start
-          if(typeof this.start === 'number'){
-            startString = getDateTime(this.start, this.hideSecond)
-          }
-          [startDate, startTime] = startString.split(' ')
-          if(this.start && !dateCompare(startDate, this.inputDate)) {
-            startLaterInputDate = true
-            this.inputDate = startDate
-          }
-        }
-
-        let endEarlierInputDate = false
-        let endDate, endTime
-        if(this.end) {
-          let endString = this.end
-          if(typeof this.end === 'number'){
-            endString = getDateTime(this.end, this.hideSecond)
-          }
-          [endDate, endTime] = endString.split(' ')
-          if(this.end && !dateCompare(this.inputDate, endDate)) {
-            endEarlierInputDate = true
-            this.inputDate = endDate
-          }
-        }
+				}
+
+				let startLaterInputDate = false
+				let startDate, startTime
+				if (this.start) {
+					let startString = this.start
+					if (typeof this.start === 'number') {
+						startString = getDateTime(this.start, this.hideSecond)
+					}
+					[startDate, startTime] = startString.split(' ')
+					if (this.start && !dateCompare(startDate, this.inputDate)) {
+						startLaterInputDate = true
+						this.inputDate = startDate
+					}
+				}
+
+				let endEarlierInputDate = false
+				let endDate, endTime
+				if (this.end) {
+					let endString = this.end
+					if (typeof this.end === 'number') {
+						endString = getDateTime(this.end, this.hideSecond)
+					}
+					[endDate, endTime] = endString.split(' ')
+					if (this.end && !dateCompare(this.inputDate, endDate)) {
+						endEarlierInputDate = true
+						this.inputDate = endDate
+					}
+				}
 				if (this.hasTime) {
-          if(startLaterInputDate){
-            this.pickerTime = startTime || getDefaultSecond(this.hideSecond)
-          }
-          if(endEarlierInputDate){
-            this.pickerTime = endTime || getDefaultSecond(this.hideSecond)
-          }
-          if(!this.pickerTime){
-            this.pickerTime = getTime(Date.now(), this.hideSecond)
-          }
+					if (startLaterInputDate) {
+						this.pickerTime = startTime || getDefaultSecond(this.hideSecond)
+					}
+					if (endEarlierInputDate) {
+						this.pickerTime = endTime || getDefaultSecond(this.hideSecond)
+					}
+					if (!this.pickerTime) {
+						this.pickerTime = getTime(Date.now(), this.hideSecond)
+					}
 					this.displayValue = `${this.inputDate} ${this.pickerTime}`
 				} else {
-          this.displayValue = this.inputDate
+					this.displayValue = this.inputDate
 				}
 				this.setEmit(this.displayValue)
 				this.pickerVisible = false
@@ -601,6 +629,7 @@
 					fulldate: e.fulldate
 				}
 				this.startMultipleStatus = Object.assign({}, this.startMultipleStatus, obj)
+				this.$emit('calendarClick', e)
 			},
 			rightChange(e) {
 				const {
@@ -615,14 +644,17 @@
 					fulldate: e.fulldate
 				}
 				this.endMultipleStatus = Object.assign({}, this.endMultipleStatus, obj)
+				this.$emit('calendarClick', e)
 			},
 			mobileChange(e) {
 				if (this.isRange) {
-					const {before, after} = e.range
-
-          if(!before || !after){
-            return
-          }
+					const {
+						before,
+						after
+					} = e.range
+					if (!before) {
+						return;
+					}
 
 					this.handleStartAndEnd(before, after, true)
 					if (this.hasTime) {
@@ -655,79 +687,79 @@
 					this.pickerVisible = false
 					return
 				}
-        if(!checkDate(this.tempRange.startDate)){
-          this.tempRange.startDate = getDate(Date.now())
-        }
-        if(!checkDate(this.tempRange.endDate)){
-          this.tempRange.endDate = getDate(Date.now())
-        }
+				if (!checkDate(this.tempRange.startDate)) {
+					this.tempRange.startDate = getDate(Date.now())
+				}
+				if (!checkDate(this.tempRange.endDate)) {
+					this.tempRange.endDate = getDate(Date.now())
+				}
 
 				let start, end
 
-        let startDateLaterRangeStartDate = false
-        let startDateLaterRangeEndDate = false
-        let startDate, startTime
-        if(this.start) {
-          let startString = this.start
-          if(typeof this.start === 'number'){
-            startString = getDateTime(this.start, this.hideSecond)
-          }
-          [startDate,startTime] = startString.split(' ')
-          if(this.start && !dateCompare(this.start, this.tempRange.startDate)) {
-            startDateLaterRangeStartDate = true
-            this.tempRange.startDate = startDate
-          }
-          if(this.start && !dateCompare(this.start, this.tempRange.endDate)) {
-            startDateLaterRangeEndDate = true
-            this.tempRange.endDate = startDate
-          }
-        }
-        let endDateEarlierRangeStartDate = false
-        let endDateEarlierRangeEndDate = false
-        let endDate, endTime
-        if(this.end) {
-          let endString = this.end
-          if(typeof this.end === 'number'){
-            endString = getDateTime(this.end, this.hideSecond)
-          }
-          [endDate,endTime] = endString.split(' ')
-
-          if(this.end && !dateCompare(this.tempRange.startDate, this.end)) {
-            endDateEarlierRangeStartDate = true
-            this.tempRange.startDate = endDate
-          }
-          if(this.end && !dateCompare(this.tempRange.endDate, this.end)) {
-            endDateEarlierRangeEndDate = true
-            this.tempRange.endDate = endDate
-          }
-        }
+				let startDateLaterRangeStartDate = false
+				let startDateLaterRangeEndDate = false
+				let startDate, startTime
+				if (this.start) {
+					let startString = this.start
+					if (typeof this.start === 'number') {
+						startString = getDateTime(this.start, this.hideSecond)
+					}
+					[startDate, startTime] = startString.split(' ')
+					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} ${this.tempRange.endTime}`)) {
+						startDateLaterRangeEndDate = true
+						this.tempRange.endDate = startDate
+					}
+				}
+				let endDateEarlierRangeStartDate = false
+				let endDateEarlierRangeEndDate = false
+				let endDate, endTime
+				if (this.end) {
+					let endString = this.end
+					if (typeof this.end === 'number') {
+						endString = getDateTime(this.end, this.hideSecond)
+					}
+					[endDate, endTime] = endString.split(' ')
+
+					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.tempRange.endTime}`, this.end)) {
+						endDateEarlierRangeEndDate = true
+						this.tempRange.endDate = endDate
+					}
+				}
 				if (!this.hasTime) {
-          start = this.displayRangeValue.startDate = this.tempRange.startDate
+					start = this.displayRangeValue.startDate = this.tempRange.startDate
 					end = this.displayRangeValue.endDate = this.tempRange.endDate
 				} else {
-          if(startDateLaterRangeStartDate){
-            this.tempRange.startTime = startTime || getDefaultSecond(this.hideSecond)
-          }else if(endDateEarlierRangeStartDate){
-            this.tempRange.startTime = endTime || getDefaultSecond(this.hideSecond)
-          }
-          if(!this.tempRange.startTime){
-            this.tempRange.startTime = getTime(Date.now(), this.hideSecond)
-          }
-
-          if(startDateLaterRangeEndDate){
-            this.tempRange.endTime = startTime || getDefaultSecond(this.hideSecond)
-          }else if(endDateEarlierRangeEndDate){
-            this.tempRange.endTime = endTime || getDefaultSecond(this.hideSecond)
-          }
-          if(!this.tempRange.endTime){
-            this.tempRange.endTime = getTime(Date.now(), this.hideSecond)
-          }
+					if (startDateLaterRangeStartDate) {
+						this.tempRange.startTime = startTime || getDefaultSecond(this.hideSecond)
+					} else if (endDateEarlierRangeStartDate) {
+						this.tempRange.startTime = endTime || getDefaultSecond(this.hideSecond)
+					}
+					if (!this.tempRange.startTime) {
+						this.tempRange.startTime = getTime(Date.now(), this.hideSecond)
+					}
+
+					if (startDateLaterRangeEndDate) {
+						this.tempRange.endTime = startTime || getDefaultSecond(this.hideSecond)
+					} else if (endDateEarlierRangeEndDate) {
+						this.tempRange.endTime = endTime || getDefaultSecond(this.hideSecond)
+					}
+					if (!this.tempRange.endTime) {
+						this.tempRange.endTime = getTime(Date.now(), this.hideSecond)
+					}
 					start = this.displayRangeValue.startDate = `${this.tempRange.startDate} ${this.tempRange.startTime}`
 					end = this.displayRangeValue.endDate = `${this.tempRange.endDate} ${this.tempRange.endTime}`
 				}
-        if(!dateCompare(start,end)){
-          [start, end] = [end, start]
-        }
+				if (!dateCompare(start, end)) {
+					[start, end] = [end, start]
+				}
 				this.displayRangeValue.startDate = start
 				this.displayRangeValue.endDate = end
 				const displayRange = [start, end]
@@ -735,13 +767,13 @@
 				this.pickerVisible = false
 			},
 			handleStartAndEnd(before, after, temp = false) {
-				if (!(before && after)) return
-
+				if (!before) return
+				if (!after) after = before;
 				const type = temp ? 'tempRange' : 'range'
-        const isStartEarlierEnd = dateCompare(before, after)
-        this[type].startDate = isStartEarlierEnd ? before : after
-        this[type].endDate = isStartEarlierEnd ? after : before
-    },
+				const isStartEarlierEnd = dateCompare(before, after)
+				this[type].startDate = isStartEarlierEnd ? before : after
+				this[type].endDate = isStartEarlierEnd ? after : before
+			},
 			/**
 			 * 比较时间大小
 			 */
@@ -800,6 +832,10 @@
 						this.$emit('update:modelValue', [])
 					}
 				}
+			},
+
+			calendarClick(e) {
+				this.$emit('calendarClick', e)
 			}
 		}
 	}
@@ -812,6 +848,7 @@
 		width: 100%;
 		flex: 1;
 	}
+
 	.uni-date-x {
 		display: flex;
 		flex-direction: row;
@@ -823,16 +860,17 @@
 		font-size: 14px;
 		flex: 1;
 
-    .icon-calendar{
-      padding-left: 3px;
-    }
-    .range-separator{
-      height: 35px;
-      /* #ifndef MP */
-      padding: 0 2px;
-      /* #endif */
+		.icon-calendar {
+			padding-left: 3px;
+		}
+
+		.range-separator {
+			height: 35px;
+			/* #ifndef MP */
+			padding: 0 2px;
+			/* #endif */
 			line-height: 35px;
-    }
+		}
 	}
 
 	.uni-date-x--border {
@@ -859,9 +897,9 @@
 	.uni-date__x-input {
 		width: auto;
 		height: 35px;
-    /* #ifndef MP */
-    padding-left: 5px;
-    /* #endif */
+		/* #ifndef MP */
+		padding-left: 5px;
+		/* #endif */
 		position: relative;
 		flex: 1;
 		line-height: 35px;

+ 103 - 85
uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js

@@ -13,7 +13,7 @@ class Calendar {
 		this.startDate = startDate
 		// 终止时间
 		this.endDate = endDate
-    // 是否范围选择
+		// 是否范围选择
 		this.range = range
 		// 多选状态
 		this.cleanMultipleStatus()
@@ -49,44 +49,44 @@ class Calendar {
 		this.endDate = endDate
 	}
 
-  getPreMonthObj(date){
-    date = fixIosDateFormat(date)
-    date = new Date(date)
-
-    const oldMonth = date.getMonth()
-    date.setMonth(oldMonth - 1)
-    const newMonth = date.getMonth()
-    if(oldMonth !== 0 && newMonth - oldMonth === 0){
-      date.setMonth(newMonth - 1)
-    }
-    return this.getDateObj(date)
-  }
-  getNextMonthObj(date){
-    date = fixIosDateFormat(date)
-    date = new Date(date)
-
-    const oldMonth = date.getMonth()
-    date.setMonth(oldMonth + 1)
-    const newMonth = date.getMonth()
-    if(newMonth - oldMonth > 1){
-      date.setMonth(newMonth - 1)
-    }
-    return this.getDateObj(date)
-  }
+	getPreMonthObj(date) {
+		date = fixIosDateFormat(date)
+		date = new Date(date)
+
+		const oldMonth = date.getMonth()
+		date.setMonth(oldMonth - 1)
+		const newMonth = date.getMonth()
+		if (oldMonth !== 0 && newMonth - oldMonth === 0) {
+			date.setMonth(newMonth - 1)
+		}
+		return this.getDateObj(date)
+	}
+	getNextMonthObj(date) {
+		date = fixIosDateFormat(date)
+		date = new Date(date)
+
+		const oldMonth = date.getMonth()
+		date.setMonth(oldMonth + 1)
+		const newMonth = date.getMonth()
+		if (newMonth - oldMonth > 1) {
+			date.setMonth(newMonth - 1)
+		}
+		return this.getDateObj(date)
+	}
 
 	/**
 	 * 获取指定格式Date对象
 	 */
 	getDateObj(date) {
-    date = fixIosDateFormat(date)
-    date = new Date(date)
+		date = fixIosDateFormat(date)
+		date = new Date(date)
 
 		return {
 			fullDate: getDate(date),
-      year: date.getFullYear(),
-      month: addZero(date.getMonth() + 1),
-      date: addZero(date.getDate()),
-      day: date.getDay()
+			year: date.getFullYear(),
+			month: addZero(date.getMonth() + 1),
+			date: addZero(date.getDate()),
+			day: date.getDay()
 		}
 	}
 
@@ -96,7 +96,7 @@ class Calendar {
 	getPreMonthDays(amount, dateObj) {
 		const result = []
 		for (let i = amount - 1; i >= 0; i--) {
-      const month = dateObj.month - 1
+			const month = dateObj.month - 1
 			result.push({
 				date: new Date(dateObj.year, month, -i).getDate(),
 				month,
@@ -135,11 +135,11 @@ class Calendar {
 			let multiples = this.multipleStatus.data
 			let multiplesStatus = -1
 			if (this.range && multiples) {
-        multiplesStatus = multiples.findIndex((item) => {
-          return this.dateEqual(item, currentDate)
-        })
+				multiplesStatus = multiples.findIndex((item) => {
+					return this.dateEqual(item, currentDate)
+				})
 			}
-      const checked = multiplesStatus !== -1
+			const checked = multiplesStatus !== -1
 
 			result.push({
 				fullDate: currentDate,
@@ -149,10 +149,11 @@ class Calendar {
 				beforeMultiple: this.isLogicBefore(currentDate, this.multipleStatus.before, this.multipleStatus.after),
 				afterMultiple: this.isLogicAfter(currentDate, this.multipleStatus.before, this.multipleStatus.after),
 				month: dateObj.month,
-				disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !dateCompare(currentDate,this.endDate)),
+				disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !dateCompare(
+					currentDate, this.endDate)),
 				isToday,
 				userChecked: false,
-        extraInfo: info
+				extraInfo: info
 			})
 		}
 		return result
@@ -162,7 +163,7 @@ class Calendar {
 	 */
 	_getNextMonthDays(amount, dateObj) {
 		const result = []
-    const month = dateObj.month + 1
+		const month = dateObj.month + 1
 		for (let i = 1; i <= amount; i++) {
 			result.push({
 				date: i,
@@ -181,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)
 	}
 
 	/**
@@ -240,7 +241,7 @@ class Calendar {
 	 *  获取多选状态
 	 */
 	setMultiple(fullDate) {
-    if (!this.range) return
+		if (!this.range) return
 
 		let {
 			before,
@@ -259,6 +260,7 @@ class Calendar {
 		} else {
 			if (!before) {
 				this.multipleStatus.before = fullDate
+				this.multipleStatus.after = undefined;
 				this.lastHover = false
 			} else {
 				this.multipleStatus.after = fullDate
@@ -279,9 +281,12 @@ class Calendar {
 	 *  鼠标 hover 更新多选状态
 	 */
 	setHoverMultiple(fullDate) {
-    if (!this.range || this.lastHover) return
-
-		const { before } = this.multipleStatus
+		//抖音小程序点击会触发hover事件,需要避免一下
+		// #ifndef MP-TOUTIAO
+		if (!this.range || this.lastHover) return
+		const {
+			before
+		} = this.multipleStatus
 
 		if (!before) {
 			this.multipleStatus.before = fullDate
@@ -294,6 +299,8 @@ class Calendar {
 			}
 		}
 		this.getWeeks(fullDate)
+		// #endif
+
 	}
 
 	/**
@@ -324,22 +331,22 @@ class Calendar {
 		} = this.getDateObj(dateData)
 
 		const preMonthDayAmount = new Date(year, month - 1, 1).getDay()
-    const preMonthDays = this.getPreMonthDays(preMonthDayAmount, this.getDateObj(dateData))
+		const preMonthDays = this.getPreMonthDays(preMonthDayAmount, this.getDateObj(dateData))
 
 		const currentMonthDayAmount = new Date(year, month, 0).getDate()
-    const currentMonthDays = this.getCurrentMonthDays(currentMonthDayAmount, this.getDateObj(dateData))
+		const currentMonthDays = this.getCurrentMonthDays(currentMonthDayAmount, this.getDateObj(dateData))
 
-    const nextMonthDayAmount = 42 - preMonthDayAmount - currentMonthDayAmount
-    const nextMonthDays = this._getNextMonthDays(nextMonthDayAmount, this.getDateObj(dateData))
+		const nextMonthDayAmount = 42 - preMonthDayAmount - currentMonthDayAmount
+		const nextMonthDays = this._getNextMonthDays(nextMonthDayAmount, this.getDateObj(dateData))
 
 		const calendarDays = [...preMonthDays, ...currentMonthDays, ...nextMonthDays]
 
 		const weeks = new Array(6)
 		for (let i = 0; i < calendarDays.length; i++) {
-      const index = Math.floor(i / 7)
-      if(!weeks[index]){
-        weeks[index] = new Array(7)
-      }
+			const index = Math.floor(i / 7)
+			if (!weeks[index]) {
+				weeks[index] = new Array(7)
+			}
 			weeks[index][i % 7] = calendarDays[i]
 		}
 
@@ -348,56 +355,67 @@ class Calendar {
 	}
 }
 
-function getDateTime(date, hideSecond){
-  return `${getDate(date)} ${getTime(date, hideSecond)}`
+function getDateTime(date, hideSecond) {
+	return `${getDate(date)} ${getTime(date, hideSecond)}`
 }
 
 function getDate(date) {
-  date = fixIosDateFormat(date)
-  date = new Date(date)
-  const year = date.getFullYear()
-  const month = date.getMonth()+1
-  const day = date.getDate()
-  return `${year}-${addZero(month)}-${addZero(day)}`
+	date = fixIosDateFormat(date)
+	date = new Date(date)
+	const year = date.getFullYear()
+	const month = date.getMonth() + 1
+	const day = date.getDate()
+	return `${year}-${addZero(month)}-${addZero(day)}`
 }
 
-function getTime(date, hideSecond){
-  date = fixIosDateFormat(date)
-  date = new Date(date)
-  const hour = date.getHours()
-  const minute = date.getMinutes()
-  const second = date.getSeconds()
-  return hideSecond ? `${addZero(hour)}:${addZero(minute)}` : `${addZero(hour)}:${addZero(minute)}:${addZero(second)}`
+function getTime(date, hideSecond) {
+	date = fixIosDateFormat(date)
+	date = new Date(date)
+	const hour = date.getHours()
+	const minute = date.getMinutes()
+	const second = date.getSeconds()
+	return hideSecond ? `${addZero(hour)}:${addZero(minute)}` : `${addZero(hour)}:${addZero(minute)}:${addZero(second)}`
 }
 
 function addZero(num) {
-  if(num < 10){
-    num = `0${num}`
-  }
-  return num
+	if (num < 10) {
+		num = `0${num}`
+	}
+	return num
 }
 
 function getDefaultSecond(hideSecond) {
-  return hideSecond ? '00:00' : '00:00:00'
+	return hideSecond ? '00:00' : '00:00:00'
 }
 
 function dateCompare(startDate, endDate) {
-  startDate = new Date(fixIosDateFormat(startDate))
-  endDate = new Date(fixIosDateFormat(endDate))
-  return startDate <= endDate
+	startDate = new Date(fixIosDateFormat(startDate))
+	endDate = new Date(fixIosDateFormat(endDate))
+	return startDate <= endDate
 }
 
-function checkDate(date){
-  const dateReg = /((19|20)\d{2})(-|\/)\d{1,2}(-|\/)\d{1,2}/g
-  return date.match(dateReg)
+function checkDate(date) {
+	const dateReg = /((19|20)\d{2})(-|\/)\d{1,2}(-|\/)\d{1,2}/g
+	return date.match(dateReg)
 }
+//ios低版本15及以下,无法匹配 没有 ’秒‘ 时的情况,所以需要在末尾 秒 加上 问号
+const dateTimeReg = /^\d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])( [0-5]?[0-9]:[0-5]?[0-9](:[0-5]?[0-9])?)?$/;
 
-const dateTimeReg = /^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])( [0-5][0-9]:[0-5][0-9]:[0-5][0-9])?$/
 function fixIosDateFormat(value) {
-  if (typeof value === 'string' && dateTimeReg.test(value)) {
-    value = value.replace(/-/g, '/')
-  }
-  return value
+	if (typeof value === 'string' && dateTimeReg.test(value)) {
+		value = value.replace(/-/g, '/')
+	}
+	return value
 }
 
-export {Calendar, getDateTime, getDate, getTime, addZero, getDefaultSecond, dateCompare, checkDate, fixIosDateFormat}
+export {
+	Calendar,
+	getDateTime,
+	getDate,
+	getTime,
+	addZero,
+	getDefaultSecond,
+	dateCompare,
+	checkDate,
+	fixIosDateFormat
+}

+ 3 - 2
uni_modules/uni-datetime-picker/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-datetime-picker",
   "displayName": "uni-datetime-picker 日期选择器",
-  "version": "2.2.22",
+  "version": "2.2.38",
   "description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择",
   "keywords": [
     "uni-datetime-picker",
@@ -46,7 +46,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {

+ 1 - 1
uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue

@@ -105,7 +105,7 @@
 	}
 </script>
 
-<style lang="scss" >
+<style lang="scss" scoped>
 	$uni-mask: rgba($color: #000000, $alpha: 0.4) ;
 	// 抽屉宽度
 	$drawer-width: 220px;

+ 18 - 0
uni_modules/uni-easyinput/changelog.md

@@ -1,3 +1,21 @@
+## 1.1.19(2024-07-18)
+- 修复 初始值传入 null 导致input报错的bug
+## 1.1.18(2024-04-11)
+- 修复 easyinput组件双向绑定问题
+## 1.1.17(2024-03-28)
+- 修复 在头条小程序下丢失事件绑定的问题
+## 1.1.16(2024-03-20)
+- 修复 在密码输入情况下 清除和小眼睛覆盖bug 在edge浏览器下显示双眼睛bug
+## 1.1.15(2024-02-21)
+- 新增 左侧插槽:left
+## 1.1.14(2024-02-19)
+- 修复 onBlur的emit传值错误
+## 1.1.12(2024-01-29)
+- 补充 adjust-position文档属性补充
+## 1.1.11(2024-01-29)
+- 补充 adjust-position属性传递值:(Boolean)当键盘弹起时,是否自动上推页面
+## 1.1.10(2024-01-22)
+- 去除 移除无用的log输出
 ## 1.1.9(2023-04-11)
 - 修复 vue3 下 keyboardheightchange 事件报错的bug
 ## 1.1.8(2023-03-29)

+ 0 - 2
uni_modules/uni-easyinput/components/uni-easyinput/common.js

@@ -6,9 +6,7 @@
  */
 export const debounce = function(func, wait = 1000, immediate = true) {
 	let timer;
-	console.log(1);
 	return function() {
-		console.log(123);
 		let context = this,
 			args = arguments;
 		if (timer) clearTimeout(timer);

+ 627 - 608
uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue

@@ -2,73 +2,26 @@
 	<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>
-			<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"
-				@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"
-				@focus="_Focus"
-				@blur="_Blur"
-				@input="onInput"
-				@confirm="onConfirm"
-        @keyboardheightchange="onkeyboardheightchange"
-			/>
+			<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>
+				<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-else-if="suffixIcon">
+			<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>
+				<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>
@@ -76,582 +29,648 @@
 </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
- * @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} `;
+	/**
+	 * 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;
 	}
-	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: {
-		virtualHost: true
-	},
-	inject: {
-		form: {
-			from: 'uniForm',
-			default: null
-		},
-		formItem: {
-			from: 'uniFormItem',
-			default: null
+
+	function obj2strStyle(obj) {
+		let style = '';
+		for (let key in obj) {
+			const val = obj[key];
+			style += `${key}:${val};`;
 		}
-	},
-	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
-		},
-		primaryColor: {
-			type: String,
-			default: '#2979ff'
-		},
-		styles: {
-			type: Object,
-			default() {
-				return {
-					color: '#333',
-					backgroundColor: '#fff',
-					disableColor: '#F7F6F6',
-					borderColor: '#e5e5e5'
-				};
+		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
 			}
 		},
-		errorMessage: {
-			type: [String, Boolean],
-			default: ''
-		}
-	},
-	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;
+		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'
+				});
 			}
-			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;
+		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;
+				});
+			}
 		},
-		modelValue(newVal) {
-			this.val = newVal;
+		created() {
+			this.init();
+			// TODO 处理头条vue3 computed 不监听 inject 更改的问题(formItem.errMsg)
+			if (this.form && this.formItem) {
+				this.$watch('formItem.errMsg', newVal => {
+					this.localMsg = newVal;
+				});
+			}
 		},
-		focus(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;
+			}
 		}
-	},
-	created() {
-		this.init();
-		// TODO 处理头条vue3 computed 不监听 inject 更改的问题(formItem.errMsg)
-		if (this.form && this.formItem) {
-			this.$watch('formItem.errMsg', newVal => {
-				this.localMsg = newVal;
-			});
+	};
+</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;
 		}
-	},
-	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);
-		},
+		& ::-ms-clear {
+			display: none;
+		}
 
-		/**
-		 * 显示隐藏内容,密码框时生效
-		 */
-		onEyes() {
-			this.showPassword = !this.showPassword;
-			this.$emit('eyes', this.showPassword);
-		},
+		& ::-o-clear {
+			display: none;
+		}
 
-		/**
-		 * 输入时触发
-		 * @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);
-		},
+		/*endif*/
+	}
 
-		/**
-		 * 外部调用方法
-		 * 获取焦点时触发
-		 * @param {Object} event
-		 */
-		onFocus() {
-			this.$nextTick(() => {
-				this.focused = true;
-			});
-			this.$emit('focus', null);
-		},
+	.uni-easyinput__placeholder-class {
+		color: #999;
+		font-size: 12px;
+		// font-weight: 200;
+	}
 
-		_Focus(event) {
-			this.focusShow = true;
-			this.$emit('focus', event);
-		},
+	.is-textarea {
+		align-items: flex-start;
+	}
 
-		/**
-		 * 外部调用方法
-		 * 失去焦点时触发
-		 * @param {Object} event
-		 */
-		onBlur() {
-			this.focused = false;
-			this.$emit('focus', 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();
-				}
-			}
-		},
+	.is-textarea-icon {
+		margin-top: 5px;
+	}
 
-		/**
-		 * 按下键盘的发送键
-		 * @param {Object} e
-		 */
-		onConfirm(e) {
-			this.$emit('confirm', this.val);
-			this.isEnter = true;
-			this.$emit('change', this.val);
-			this.$nextTick(() => {
-				this.isEnter = false;
-			});
-		},
+	.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 */
+	}
 
-		/**
-		 * 清理内容
-		 * @param {Object} event
-		 */
-		onClear(event) {
-			this.val = '';
-			// TODO 兼容 vue2
-			this.$emit('input', '');
-			// TODO 兼容 vue2
-			// TODO 兼容 vue3
-			this.$emit('update:modelValue', '');
-			// 点击叉号触发
-			this.$emit('clear');
-		},
+	.input-padding {
+		padding-left: 10px;
+	}
 
-    /**
-     * 键盘高度发生变化的时候触发此事件
-     * 兼容性:微信小程序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;
+	.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%);
 		}
 	}
-};
-</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;
-}
-
-.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--border {
+		margin-bottom: 0;
+		padding: 10px 15px;
+		// padding-bottom: 0;
+		border-top: 1px #eee solid;
+	}
 
-	.uni-easyinput__placeholder-class {
-		color: mix(#fff, $uni-error, 50%);
+	.uni-easyinput-error {
+		padding-bottom: 0;
 	}
-}
-
-.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 {
+	.is-first-border {
+		/* #ifndef APP-NVUE */
+		border: none;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		border-width: 0;
+		/* #endif */
+	}
+
+	.is-disabled {
+		background-color: #f7f6f6;
 		color: #d5d5d5;
-		font-size: 12px;
+
+		.uni-easyinput__placeholder-class {
+			color: #d5d5d5;
+			font-size: 12px;
+		}
 	}
-}
-</style>
+</style>

+ 3 - 2
uni_modules/uni-easyinput/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-easyinput",
   "displayName": "uni-easyinput 增强输入框",
-  "version": "1.1.9",
+  "version": "1.1.19",
   "description": "Easyinput 组件是对原生input组件的增强",
   "keywords": [
     "uni-ui",
@@ -46,7 +46,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {

+ 2 - 0
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)

+ 1 - 1
uni_modules/uni-fab/components/uni-fab/uni-fab.vue

@@ -164,8 +164,8 @@
 			},
 			// 计算 nvue bottom
 			nvueBottom() {
-				const safeBottom = uni.getSystemInfoSync().windowBottom;
 				// #ifdef APP-NVUE
+				const safeBottom = uni.getSystemInfoSync().windowBottom;
 				return 30 + safeBottom
 				// #endif
 				// #ifndef APP-NVUE

+ 3 - 2
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": {

+ 14 - 0
uni_modules/uni-file-picker/changelog.md

@@ -1,3 +1,17 @@
+## 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)
+- 新增 微信小程序选择视频时改用chooseMedia,并返回视频缩略图
+## 1.0.6(2024-01-06)
+- 新增 微信小程序不再调用chooseImage,而是调用chooseMedia
+## 1.0.5(2024-01-03)
+- 新增 上传文件至云存储携带本地文件名称
 ## 1.0.4(2023-03-29)
 - 修复 手动上传删除一个文件后不能再上传的bug
 ## 1.0.3(2022-12-19)

+ 67 - 4
uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js

@@ -11,6 +11,28 @@ function chooseImage(opts) {
 		extension
 	} = opts
 	return new Promise((resolve, reject) => {
+		// 微信由于旧接口不再维护,针对微信小程序平台改用chooseMedia接口
+		// #ifdef MP-WEIXIN
+		uni.chooseMedia({
+			count,
+			sizeType,
+			sourceType,
+			mediaType: ['image'],
+			extension,
+			success(res) {
+				res.tempFiles.forEach(item => {
+					item.path = item.tempFilePath;
+				})
+				resolve(normalizeChooseAndUploadFileRes(res, 'image'));
+			},
+			fail(res) {
+				reject({
+					errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL),
+				});
+			},
+		})
+		// #endif
+		// #ifndef MP-WEIXIN
 		uni.chooseImage({
 			count,
 			sizeType,
@@ -25,11 +47,14 @@ function chooseImage(opts) {
 				});
 			},
 		});
+		// #endif
+
 	});
 }
 
 function chooseVideo(opts) {
 	const {
+		count,
 		camera,
 		compressed,
 		maxDuration,
@@ -37,6 +62,45 @@ function chooseVideo(opts) {
 		extension
 	} = opts;
 	return new Promise((resolve, reject) => {
+		// 微信由于旧接口不再维护,针对微信小程序平台改用chooseMedia接口
+		// #ifdef MP-WEIXIN
+		uni.chooseMedia({
+			count,
+			compressed,
+			maxDuration,
+			sourceType,
+			extension,
+			mediaType: ['video'],
+			success(res) {
+				const {
+					tempFiles,
+				} = res;
+				resolve(normalizeChooseAndUploadFileRes({
+					errMsg: 'chooseVideo:ok',
+					tempFiles: tempFiles.map(item => {
+						return {
+							name: item.name || '',
+							path: item.tempFilePath,
+							thumbTempFilePath: item.thumbTempFilePath,
+							size:item.size,
+							type: (res.tempFile && res.tempFile.type) || '',
+							width:item.width,
+							height:item.height,
+							duration:item.duration,
+							fileType: 'video',
+							cloudPath: '',
+						}
+					}),
+				}, 'video'));
+			},
+			fail(res) {
+				reject({
+					errMsg: res.errMsg.replace('chooseVideo:fail', ERR_MSG_FAIL),
+				});
+			},
+		})
+		// #endif
+		// #ifndef MP-WEIXIN
 		uni.chooseVideo({
 			camera,
 			compressed,
@@ -54,8 +118,7 @@ function chooseVideo(opts) {
 				resolve(normalizeChooseAndUploadFileRes({
 					errMsg: 'chooseVideo:ok',
 					tempFilePaths: [tempFilePath],
-					tempFiles: [
-					{
+					tempFiles: [{
 						name: (res.tempFile && res.tempFile.name) || '',
 						path: tempFilePath,
 						size,
@@ -74,6 +137,7 @@ function chooseVideo(opts) {
 				});
 			},
 		});
+		// #endif
 	});
 }
 
@@ -211,8 +275,7 @@ function chooseAndUploadFile(opts = {
 }) {
 	if (opts.type === 'image') {
 		return uploadFiles(chooseImage(opts), opts);
-	}
-	else if (opts.type === 'video') {
+	} else if (opts.type === 'video') {
 		return uploadFiles(chooseVideo(opts), opts);
 	}
 	return uploadFiles(chooseAll(opts), opts);

+ 12 - 11
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
@@ -191,6 +185,10 @@
 				default () {
 					return  ['album', 'camera']
 				}
+			},
+			provider: {
+				type: String,
+				default: '' // 默认上传到 unicloud 内置存储 extStorage 扩展存储
 			}
 		},
 		data() {
@@ -200,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() {
@@ -331,7 +325,6 @@
 			 * 选择文件
 			 */
 			choose() {
-
 				if (this.disabled) return
 				if (this.files.length >= Number(this.limitLength) && this.showType !== 'grid' && this.returnType ===
 					'array') {
@@ -418,6 +411,13 @@
 				if (!this.autoUpload || this.noSpace) {
 					res.tempFiles = []
 				}
+				res.tempFiles.forEach((fileItem, index) => {
+					this.provider && (fileItem.provider = this.provider);
+					const fileNameSplit = fileItem.name.split('.')
+					const ext = fileNameSplit.pop()
+					const fileName = fileNameSplit.join('.').replace(/[\s\/\?<>\\:\*\|":]/g, '_')
+					fileItem.cloudPath = fileName + '_' + Date.now() + '_' + index + '.' + ext
+				})
 			},
 
 			/**
@@ -523,6 +523,7 @@
 			 */
 			delFile(index) {
 				this.$emit('delete', {
+					index,
 					tempFile: this.files[index],
 					tempFilePath: this.files[index].url
 				})

+ 1 - 0
uni_modules/uni-file-picker/components/uni-file-picker/utils.js

@@ -90,6 +90,7 @@ export const get_file_data = async (files, type = 'image') => {
 		extname: extname || '',
 		cloudPath: files.cloudPath,
 		fileType: files.fileType,
+		thumbTempFilePath: files.thumbTempFilePath,
 		url: files.path || files.path,
 		size: files.size, //单位是字节
 		image: {},

+ 3 - 2
uni_modules/uni-file-picker/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-file-picker",
   "displayName": "uni-file-picker 文件选择上传",
-  "version": "1.0.4",
+  "version": "1.0.11",
   "description": "文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间",
   "keywords": [
     "uni-ui",
@@ -42,7 +42,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {

+ 8 - 0
uni_modules/uni-forms/changelog.md

@@ -1,3 +1,11 @@
+## 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)
 - 修复 required 参数无法动态绑定
 ## 1.4.8(2022-08-23)

+ 10 - 5
uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue

@@ -36,7 +36,7 @@
 	 * @tutorial https://ext.dcloud.net.cn/plugin?id=2773
 	 * @property {Boolean} required 是否必填,左边显示红色"*"号
 	 * @property {String } 	label 				输入框左边的文字提示
-	 * @property {Number } 	labelWidth 			label的宽度,单位px(默认65
+	 * @property {Number } 	labelWidth 			label的宽度,单位px(默认70
 	 * @property {String } 	labelAlign = [left|center|right] label的文字对齐方式(默认left)
 	 * 	@value left		label 左侧显示
 	 * 	@value center	label 居中
@@ -57,7 +57,12 @@
 	export default {
 		name: 'uniFormsItem',
 		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
 			virtualHost: true
+			// #endif
 		},
 		provide() {
 			return {
@@ -91,7 +96,7 @@
 				type: String,
 				default: ''
 			},
-			// label的宽度 ,默认 80
+			// label的宽度
 			labelWidth: {
 				type: [String, Number],
 				default: ''
@@ -128,7 +133,7 @@
 				errMsg: '',
 				userRules: null,
 				localLabelAlign: 'left',
-				localLabelWidth: '65px',
+				localLabelWidth: '70px',
 				localLabelPos: 'left',
 				border: false,
 				isFirstBorder: false,
@@ -413,9 +418,9 @@
 				// 	const {
 				// 		labelWidth
 				// 	} = this.form
-				return this.num2px(this.labelWidth ? this.labelWidth : (labelWidth || (this.label ? 65 : 'auto')))
+				return this.num2px(this.labelWidth ? this.labelWidth : (labelWidth || (this.label ? 70 : 'auto')))
 				// }
-				// return '65px'
+				// return '70px'
 			},
 			// 处理 label 位置
 			_labelPosition() {

+ 9 - 2
uni_modules/uni-forms/components/uni-forms/uni-forms.vue

@@ -52,7 +52,7 @@
 	 * @property {String} labelPosition = [top|left]	label 位置 默认 left
 	 * @value top		顶部显示 label
 	 * @value left	左侧显示 label
-	 * @property {String} labelWidth	label 宽度,默认 65px
+	 * @property {String} labelWidth	label 宽度,默认 70px
 	 * @property {String} labelAlign = [left|center|right]	label 居中方式  默认 left
 	 * @value left		label 左侧显示
 	 * @value center	label 居中
@@ -68,7 +68,12 @@
 		name: 'uniForms',
 		emits: ['validate', 'submit'],
 		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
 			virtualHost: true
+			// #endif
 		},
 		props: {
 			// 即将弃用
@@ -180,7 +185,9 @@
 							}
 						}
 						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
 					}
 				}
 			}

+ 3 - 2
uni_modules/uni-forms/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-forms",
   "displayName": "uni-forms 表单",
-  "version": "1.4.9",
+  "version": "1.4.13",
   "description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据",
   "keywords": [
     "uni-ui",
@@ -46,7 +46,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {

+ 1 - 1
uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue

@@ -68,7 +68,7 @@
 	}
 </script>
 
-<style lang="scss" >
+<style lang="scss" scoped>
 	.uni-grid-item {
 		/* #ifndef APP-NVUE */
 		height: 100%;

+ 1 - 1
uni_modules/uni-grid/components/uni-grid/uni-grid.vue

@@ -106,7 +106,7 @@
 	}
 </script>
 
-<style lang="scss" >
+<style lang="scss" scoped>
 	.uni-grid-wrap {
 		/* #ifndef APP-NVUE */
 		display: flex;

+ 20 - 0
uni_modules/uni-icons/changelog.md

@@ -1,3 +1,23 @@
+## 2.0.10(2024-06-07)
+- 优化 uni-app x 中,size 属性的类型
+## 2.0.9(2024-01-12)
+fix: 修复图标大小默认值错误的问题
+## 2.0.8(2023-12-14)
+- 修复 项目未使用 ts 情况下,打包报错的bug
+## 2.0.7(2023-12-14)
+- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
+## 2.0.6(2023-12-11)
+- 优化 兼容老版本icon类型,如 top ,bottom 等
+## 2.0.5(2023-12-11)
+- 优化 兼容老版本icon类型,如 top ,bottom 等
+## 2.0.4(2023-12-06)
+- 优化 uni-app x 下示例项目图标排序
+## 2.0.3(2023-12-06)
+- 修复 nvue下引入组件报错的bug
+## 2.0.2(2023-12-05)
+-优化 size 属性支持单位
+## 2.0.1(2023-12-05)
+- 新增 uni-app x 支持定义图标
 ## 1.3.5(2022-01-24)
 - 优化 size 属性可以传入不带单位的字符串数值
 ## 1.3.4(2022-01-24)

+ 91 - 0
uni_modules/uni-icons/components/uni-icons/uni-icons.uvue

@@ -0,0 +1,91 @@
+<template>
+  <text class="uni-icons" :style="styleObj">
+    <slot>{{unicode}}</slot>
+  </text>
+</template>
+
+<script>
+  import { fontData, IconsDataItem } from './uniicons_file'
+
+  /**
+   * 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');
+  }
+
+  .uni-icons {
+    font-family: UniIconsFontFamily;
+    font-size: 18px;
+    font-style: normal;
+    color: #333;
+  }
+</style>

+ 31 - 17
uni_modules/uni-icons/components/uni-icons/uni-icons.vue

@@ -1,24 +1,28 @@
 <template>
 	<!-- #ifdef APP-NVUE -->
-	<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" @click="_onClick">{{unicode}}</text>
+	<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text>
 	<!-- #endif -->
 	<!-- #ifndef APP-NVUE -->
-	<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
+	<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick">
+		<slot></slot>
+	</text>
 	<!-- #endif -->
 </template>
 
 <script>
-	import icons from './icons.js';
+	import { fontData } from './uniicons_file_vue.js';
+
 	const getVal = (val) => {
 		const reg = /^[0-9]*$/g
-		return (typeof val === 'number' || reg.test(val) )? val + 'px' : val;
-	} 
+		return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;
+	}
+
 	// #ifdef APP-NVUE
 	var domModule = weex.requireModule('dom');
 	import iconUrl from './uniicons.ttf'
 	domModule.addRule('fontFace', {
 		'fontFamily': "uniicons",
-		'src': "url('"+iconUrl+"')"
+		'src': "url('" + iconUrl + "')"
 	});
 	// #endif
 
@@ -34,7 +38,7 @@
 	 */
 	export default {
 		name: 'UniIcons',
-		emits:['click'],
+		emits: ['click'],
 		props: {
 			type: {
 				type: String,
@@ -48,26 +52,36 @@
 				type: [Number, String],
 				default: 16
 			},
-			customPrefix:{
+			customPrefix: {
+				type: String,
+				default: ''
+			},
+			fontFamily: {
 				type: String,
 				default: ''
 			}
 		},
 		data() {
 			return {
-				icons: icons.glyphs
+				icons: fontData
 			}
 		},
-		computed:{
-			unicode(){
-				let code = this.icons.find(v=>v.font_class === this.type)
-				if(code){
-					return unescape(`%u${code.unicode}`)
+		computed: {
+			unicode() {
+				let code = this.icons.find(v => v.font_class === this.type)
+				if (code) {
+					return code.unicode
 				}
 				return ''
 			},
-			iconSize(){
+			iconSize() {
 				return getVal(this.size)
+			},
+			styleObj() {
+				if (this.fontFamily !== '') {
+					return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`
+				}
+				return `color: ${this.color}; font-size: ${this.iconSize};`
 			}
 		},
 		methods: {
@@ -81,9 +95,10 @@
 <style lang="scss">
 	/* #ifndef APP-NVUE */
 	@import './uniicons.css';
+
 	@font-face {
 		font-family: uniicons;
-		src: url('./uniicons.ttf') format('truetype');
+		src: url('./uniicons.ttf');
 	}
 
 	/* #endif */
@@ -92,5 +107,4 @@
 		text-decoration: none;
 		text-align: center;
 	}
-
 </style>

+ 32 - 31
uni_modules/uni-icons/components/uni-icons/uniicons.css

@@ -1,3 +1,12 @@
+
+.uniui-cart-filled:before {
+  content: "\e6d0";
+}
+
+.uniui-gift-filled:before {
+  content: "\e6c4";
+}
+
 .uniui-color:before {
   content: "\e6cf";
 }
@@ -58,10 +67,6 @@
   content: "\e6c3";
 }
 
-.uniui-gift-filled:before {
-  content: "\e6c4";
-}
-
 .uniui-fire-filled:before {
   content: "\e6c5";
 }
@@ -82,6 +87,18 @@
   content: "\e698";
 }
 
+.uniui-arrowthinleft:before {
+  content: "\e6d2";
+}
+
+.uniui-arrowthinup:before {
+  content: "\e6d3";
+}
+
+.uniui-arrowthindown:before {
+  content: "\e6d4";
+}
+
 .uniui-back:before {
   content: "\e6b9";
 }
@@ -94,55 +111,43 @@
   content: "\e6bb";
 }
 
-.uniui-arrowthinright:before {
-  content: "\e6bb";
-}
-
 .uniui-arrow-left:before {
   content: "\e6bc";
 }
 
-.uniui-arrowthinleft:before {
-  content: "\e6bc";
-}
-
 .uniui-arrow-up:before {
   content: "\e6bd";
 }
 
-.uniui-arrowthinup:before {
-  content: "\e6bd";
-}
-
 .uniui-arrow-down:before {
   content: "\e6be";
 }
 
-.uniui-arrowthindown:before {
-  content: "\e6be";
+.uniui-arrowthinright:before {
+  content: "\e6d1";
 }
 
-.uniui-bottom:before {
+.uniui-down:before {
   content: "\e6b8";
 }
 
-.uniui-arrowdown:before {
+.uniui-bottom:before {
   content: "\e6b8";
 }
 
-.uniui-right:before {
-  content: "\e6b5";
+.uniui-arrowright:before {
+  content: "\e6d5";
 }
 
-.uniui-arrowright:before {
+.uniui-right:before {
   content: "\e6b5";
 }
 
-.uniui-top:before {
+.uniui-up:before {
   content: "\e6b6";
 }
 
-.uniui-arrowup:before {
+.uniui-top:before {
   content: "\e6b6";
 }
 
@@ -150,8 +155,8 @@
   content: "\e6b7";
 }
 
-.uniui-arrowleft:before {
-  content: "\e6b7";
+.uniui-arrowup:before {
+  content: "\e6d6";
 }
 
 .uniui-eye:before {
@@ -638,10 +643,6 @@
   content: "\e627";
 }
 
-.uniui-cart-filled:before {
-  content: "\e629";
-}
-
 .uniui-checkbox:before {
   content: "\e62b";
 }

BIN
uni_modules/uni-icons/components/uni-icons/uniicons.ttf


+ 664 - 0
uni_modules/uni-icons/components/uni-icons/uniicons_file.ts

@@ -0,0 +1,664 @@
+
+export type IconsData = {
+	id : string
+	name : string
+	font_family : string
+	css_prefix_text : string
+	description : string
+	glyphs : Array<IconsDataItem>
+}
+
+export type IconsDataItem = {
+	font_class : string
+	unicode : string
+}
+
+
+export const fontData = [
+  {
+    "font_class": "arrow-down",
+    "unicode": "\ue6be"
+  },
+  {
+    "font_class": "arrow-left",
+    "unicode": "\ue6bc"
+  },
+  {
+    "font_class": "arrow-right",
+    "unicode": "\ue6bb"
+  },
+  {
+    "font_class": "arrow-up",
+    "unicode": "\ue6bd"
+  },
+  {
+    "font_class": "auth",
+    "unicode": "\ue6ab"
+  },
+  {
+    "font_class": "auth-filled",
+    "unicode": "\ue6cc"
+  },
+  {
+    "font_class": "back",
+    "unicode": "\ue6b9"
+  },
+  {
+    "font_class": "bars",
+    "unicode": "\ue627"
+  },
+  {
+    "font_class": "calendar",
+    "unicode": "\ue6a0"
+  },
+  {
+    "font_class": "calendar-filled",
+    "unicode": "\ue6c0"
+  },
+  {
+    "font_class": "camera",
+    "unicode": "\ue65a"
+  },
+  {
+    "font_class": "camera-filled",
+    "unicode": "\ue658"
+  },
+  {
+    "font_class": "cart",
+    "unicode": "\ue631"
+  },
+  {
+    "font_class": "cart-filled",
+    "unicode": "\ue6d0"
+  },
+  {
+    "font_class": "chat",
+    "unicode": "\ue65d"
+  },
+  {
+    "font_class": "chat-filled",
+    "unicode": "\ue659"
+  },
+  {
+    "font_class": "chatboxes",
+    "unicode": "\ue696"
+  },
+  {
+    "font_class": "chatboxes-filled",
+    "unicode": "\ue692"
+  },
+  {
+    "font_class": "chatbubble",
+    "unicode": "\ue697"
+  },
+  {
+    "font_class": "chatbubble-filled",
+    "unicode": "\ue694"
+  },
+  {
+    "font_class": "checkbox",
+    "unicode": "\ue62b"
+  },
+  {
+    "font_class": "checkbox-filled",
+    "unicode": "\ue62c"
+  },
+  {
+    "font_class": "checkmarkempty",
+    "unicode": "\ue65c"
+  },
+  {
+    "font_class": "circle",
+    "unicode": "\ue65b"
+  },
+  {
+    "font_class": "circle-filled",
+    "unicode": "\ue65e"
+  },
+  {
+    "font_class": "clear",
+    "unicode": "\ue66d"
+  },
+  {
+    "font_class": "close",
+    "unicode": "\ue673"
+  },
+  {
+    "font_class": "closeempty",
+    "unicode": "\ue66c"
+  },
+  {
+    "font_class": "cloud-download",
+    "unicode": "\ue647"
+  },
+  {
+    "font_class": "cloud-download-filled",
+    "unicode": "\ue646"
+  },
+  {
+    "font_class": "cloud-upload",
+    "unicode": "\ue645"
+  },
+  {
+    "font_class": "cloud-upload-filled",
+    "unicode": "\ue648"
+  },
+  {
+    "font_class": "color",
+    "unicode": "\ue6cf"
+  },
+  {
+    "font_class": "color-filled",
+    "unicode": "\ue6c9"
+  },
+  {
+    "font_class": "compose",
+    "unicode": "\ue67f"
+  },
+  {
+    "font_class": "contact",
+    "unicode": "\ue693"
+  },
+  {
+    "font_class": "contact-filled",
+    "unicode": "\ue695"
+  },
+  {
+    "font_class": "down",
+    "unicode": "\ue6b8"
+  },
+	{
+	  "font_class": "bottom",
+	  "unicode": "\ue6b8"
+	},
+  {
+    "font_class": "download",
+    "unicode": "\ue68d"
+  },
+  {
+    "font_class": "download-filled",
+    "unicode": "\ue681"
+  },
+  {
+    "font_class": "email",
+    "unicode": "\ue69e"
+  },
+  {
+    "font_class": "email-filled",
+    "unicode": "\ue69a"
+  },
+  {
+    "font_class": "eye",
+    "unicode": "\ue651"
+  },
+  {
+    "font_class": "eye-filled",
+    "unicode": "\ue66a"
+  },
+  {
+    "font_class": "eye-slash",
+    "unicode": "\ue6b3"
+  },
+  {
+    "font_class": "eye-slash-filled",
+    "unicode": "\ue6b4"
+  },
+  {
+    "font_class": "fire",
+    "unicode": "\ue6a1"
+  },
+  {
+    "font_class": "fire-filled",
+    "unicode": "\ue6c5"
+  },
+  {
+    "font_class": "flag",
+    "unicode": "\ue65f"
+  },
+  {
+    "font_class": "flag-filled",
+    "unicode": "\ue660"
+  },
+  {
+    "font_class": "folder-add",
+    "unicode": "\ue6a9"
+  },
+  {
+    "font_class": "folder-add-filled",
+    "unicode": "\ue6c8"
+  },
+  {
+    "font_class": "font",
+    "unicode": "\ue6a3"
+  },
+  {
+    "font_class": "forward",
+    "unicode": "\ue6ba"
+  },
+  {
+    "font_class": "gear",
+    "unicode": "\ue664"
+  },
+  {
+    "font_class": "gear-filled",
+    "unicode": "\ue661"
+  },
+  {
+    "font_class": "gift",
+    "unicode": "\ue6a4"
+  },
+  {
+    "font_class": "gift-filled",
+    "unicode": "\ue6c4"
+  },
+  {
+    "font_class": "hand-down",
+    "unicode": "\ue63d"
+  },
+  {
+    "font_class": "hand-down-filled",
+    "unicode": "\ue63c"
+  },
+  {
+    "font_class": "hand-up",
+    "unicode": "\ue63f"
+  },
+  {
+    "font_class": "hand-up-filled",
+    "unicode": "\ue63e"
+  },
+  {
+    "font_class": "headphones",
+    "unicode": "\ue630"
+  },
+  {
+    "font_class": "heart",
+    "unicode": "\ue639"
+  },
+  {
+    "font_class": "heart-filled",
+    "unicode": "\ue641"
+  },
+  {
+    "font_class": "help",
+    "unicode": "\ue679"
+  },
+  {
+    "font_class": "help-filled",
+    "unicode": "\ue674"
+  },
+  {
+    "font_class": "home",
+    "unicode": "\ue662"
+  },
+  {
+    "font_class": "home-filled",
+    "unicode": "\ue663"
+  },
+  {
+    "font_class": "image",
+    "unicode": "\ue670"
+  },
+  {
+    "font_class": "image-filled",
+    "unicode": "\ue678"
+  },
+  {
+    "font_class": "images",
+    "unicode": "\ue650"
+  },
+  {
+    "font_class": "images-filled",
+    "unicode": "\ue64b"
+  },
+  {
+    "font_class": "info",
+    "unicode": "\ue669"
+  },
+  {
+    "font_class": "info-filled",
+    "unicode": "\ue649"
+  },
+  {
+    "font_class": "left",
+    "unicode": "\ue6b7"
+  },
+  {
+    "font_class": "link",
+    "unicode": "\ue6a5"
+  },
+  {
+    "font_class": "list",
+    "unicode": "\ue644"
+  },
+  {
+    "font_class": "location",
+    "unicode": "\ue6ae"
+  },
+  {
+    "font_class": "location-filled",
+    "unicode": "\ue6af"
+  },
+  {
+    "font_class": "locked",
+    "unicode": "\ue66b"
+  },
+  {
+    "font_class": "locked-filled",
+    "unicode": "\ue668"
+  },
+  {
+    "font_class": "loop",
+    "unicode": "\ue633"
+  },
+  {
+    "font_class": "mail-open",
+    "unicode": "\ue643"
+  },
+  {
+    "font_class": "mail-open-filled",
+    "unicode": "\ue63a"
+  },
+  {
+    "font_class": "map",
+    "unicode": "\ue667"
+  },
+  {
+    "font_class": "map-filled",
+    "unicode": "\ue666"
+  },
+  {
+    "font_class": "map-pin",
+    "unicode": "\ue6ad"
+  },
+  {
+    "font_class": "map-pin-ellipse",
+    "unicode": "\ue6ac"
+  },
+  {
+    "font_class": "medal",
+    "unicode": "\ue6a2"
+  },
+  {
+    "font_class": "medal-filled",
+    "unicode": "\ue6c3"
+  },
+  {
+    "font_class": "mic",
+    "unicode": "\ue671"
+  },
+  {
+    "font_class": "mic-filled",
+    "unicode": "\ue677"
+  },
+  {
+    "font_class": "micoff",
+    "unicode": "\ue67e"
+  },
+  {
+    "font_class": "micoff-filled",
+    "unicode": "\ue6b0"
+  },
+  {
+    "font_class": "minus",
+    "unicode": "\ue66f"
+  },
+  {
+    "font_class": "minus-filled",
+    "unicode": "\ue67d"
+  },
+  {
+    "font_class": "more",
+    "unicode": "\ue64d"
+  },
+  {
+    "font_class": "more-filled",
+    "unicode": "\ue64e"
+  },
+  {
+    "font_class": "navigate",
+    "unicode": "\ue66e"
+  },
+  {
+    "font_class": "navigate-filled",
+    "unicode": "\ue67a"
+  },
+  {
+    "font_class": "notification",
+    "unicode": "\ue6a6"
+  },
+  {
+    "font_class": "notification-filled",
+    "unicode": "\ue6c1"
+  },
+  {
+    "font_class": "paperclip",
+    "unicode": "\ue652"
+  },
+  {
+    "font_class": "paperplane",
+    "unicode": "\ue672"
+  },
+  {
+    "font_class": "paperplane-filled",
+    "unicode": "\ue675"
+  },
+  {
+    "font_class": "person",
+    "unicode": "\ue699"
+  },
+  {
+    "font_class": "person-filled",
+    "unicode": "\ue69d"
+  },
+  {
+    "font_class": "personadd",
+    "unicode": "\ue69f"
+  },
+  {
+    "font_class": "personadd-filled",
+    "unicode": "\ue698"
+  },
+  {
+    "font_class": "personadd-filled-copy",
+    "unicode": "\ue6d1"
+  },
+  {
+    "font_class": "phone",
+    "unicode": "\ue69c"
+  },
+  {
+    "font_class": "phone-filled",
+    "unicode": "\ue69b"
+  },
+  {
+    "font_class": "plus",
+    "unicode": "\ue676"
+  },
+  {
+    "font_class": "plus-filled",
+    "unicode": "\ue6c7"
+  },
+  {
+    "font_class": "plusempty",
+    "unicode": "\ue67b"
+  },
+  {
+    "font_class": "pulldown",
+    "unicode": "\ue632"
+  },
+  {
+    "font_class": "pyq",
+    "unicode": "\ue682"
+  },
+  {
+    "font_class": "qq",
+    "unicode": "\ue680"
+  },
+  {
+    "font_class": "redo",
+    "unicode": "\ue64a"
+  },
+  {
+    "font_class": "redo-filled",
+    "unicode": "\ue655"
+  },
+  {
+    "font_class": "refresh",
+    "unicode": "\ue657"
+  },
+  {
+    "font_class": "refresh-filled",
+    "unicode": "\ue656"
+  },
+  {
+    "font_class": "refreshempty",
+    "unicode": "\ue6bf"
+  },
+  {
+    "font_class": "reload",
+    "unicode": "\ue6b2"
+  },
+  {
+    "font_class": "right",
+    "unicode": "\ue6b5"
+  },
+  {
+    "font_class": "scan",
+    "unicode": "\ue62a"
+  },
+  {
+    "font_class": "search",
+    "unicode": "\ue654"
+  },
+  {
+    "font_class": "settings",
+    "unicode": "\ue653"
+  },
+  {
+    "font_class": "settings-filled",
+    "unicode": "\ue6ce"
+  },
+  {
+    "font_class": "shop",
+    "unicode": "\ue62f"
+  },
+  {
+    "font_class": "shop-filled",
+    "unicode": "\ue6cd"
+  },
+  {
+    "font_class": "smallcircle",
+    "unicode": "\ue67c"
+  },
+  {
+    "font_class": "smallcircle-filled",
+    "unicode": "\ue665"
+  },
+  {
+    "font_class": "sound",
+    "unicode": "\ue684"
+  },
+  {
+    "font_class": "sound-filled",
+    "unicode": "\ue686"
+  },
+  {
+    "font_class": "spinner-cycle",
+    "unicode": "\ue68a"
+  },
+  {
+    "font_class": "staff",
+    "unicode": "\ue6a7"
+  },
+  {
+    "font_class": "staff-filled",
+    "unicode": "\ue6cb"
+  },
+  {
+    "font_class": "star",
+    "unicode": "\ue688"
+  },
+  {
+    "font_class": "star-filled",
+    "unicode": "\ue68f"
+  },
+  {
+    "font_class": "starhalf",
+    "unicode": "\ue683"
+  },
+  {
+    "font_class": "trash",
+    "unicode": "\ue687"
+  },
+  {
+    "font_class": "trash-filled",
+    "unicode": "\ue685"
+  },
+  {
+    "font_class": "tune",
+    "unicode": "\ue6aa"
+  },
+  {
+    "font_class": "tune-filled",
+    "unicode": "\ue6ca"
+  },
+  {
+    "font_class": "undo",
+    "unicode": "\ue64f"
+  },
+  {
+    "font_class": "undo-filled",
+    "unicode": "\ue64c"
+  },
+  {
+    "font_class": "up",
+    "unicode": "\ue6b6"
+  },
+	{
+	  "font_class": "top",
+	  "unicode": "\ue6b6"
+	},
+  {
+    "font_class": "upload",
+    "unicode": "\ue690"
+  },
+  {
+    "font_class": "upload-filled",
+    "unicode": "\ue68e"
+  },
+  {
+    "font_class": "videocam",
+    "unicode": "\ue68c"
+  },
+  {
+    "font_class": "videocam-filled",
+    "unicode": "\ue689"
+  },
+  {
+    "font_class": "vip",
+    "unicode": "\ue6a8"
+  },
+  {
+    "font_class": "vip-filled",
+    "unicode": "\ue6c6"
+  },
+  {
+    "font_class": "wallet",
+    "unicode": "\ue6b1"
+  },
+  {
+    "font_class": "wallet-filled",
+    "unicode": "\ue6c2"
+  },
+  {
+    "font_class": "weibo",
+    "unicode": "\ue68b"
+  },
+  {
+    "font_class": "weixin",
+    "unicode": "\ue691"
+  }
+] as IconsDataItem[]
+
+// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

+ 649 - 0
uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js

@@ -0,0 +1,649 @@
+
+export const fontData = [
+  {
+    "font_class": "arrow-down",
+    "unicode": "\ue6be"
+  },
+  {
+    "font_class": "arrow-left",
+    "unicode": "\ue6bc"
+  },
+  {
+    "font_class": "arrow-right",
+    "unicode": "\ue6bb"
+  },
+  {
+    "font_class": "arrow-up",
+    "unicode": "\ue6bd"
+  },
+  {
+    "font_class": "auth",
+    "unicode": "\ue6ab"
+  },
+  {
+    "font_class": "auth-filled",
+    "unicode": "\ue6cc"
+  },
+  {
+    "font_class": "back",
+    "unicode": "\ue6b9"
+  },
+  {
+    "font_class": "bars",
+    "unicode": "\ue627"
+  },
+  {
+    "font_class": "calendar",
+    "unicode": "\ue6a0"
+  },
+  {
+    "font_class": "calendar-filled",
+    "unicode": "\ue6c0"
+  },
+  {
+    "font_class": "camera",
+    "unicode": "\ue65a"
+  },
+  {
+    "font_class": "camera-filled",
+    "unicode": "\ue658"
+  },
+  {
+    "font_class": "cart",
+    "unicode": "\ue631"
+  },
+  {
+    "font_class": "cart-filled",
+    "unicode": "\ue6d0"
+  },
+  {
+    "font_class": "chat",
+    "unicode": "\ue65d"
+  },
+  {
+    "font_class": "chat-filled",
+    "unicode": "\ue659"
+  },
+  {
+    "font_class": "chatboxes",
+    "unicode": "\ue696"
+  },
+  {
+    "font_class": "chatboxes-filled",
+    "unicode": "\ue692"
+  },
+  {
+    "font_class": "chatbubble",
+    "unicode": "\ue697"
+  },
+  {
+    "font_class": "chatbubble-filled",
+    "unicode": "\ue694"
+  },
+  {
+    "font_class": "checkbox",
+    "unicode": "\ue62b"
+  },
+  {
+    "font_class": "checkbox-filled",
+    "unicode": "\ue62c"
+  },
+  {
+    "font_class": "checkmarkempty",
+    "unicode": "\ue65c"
+  },
+  {
+    "font_class": "circle",
+    "unicode": "\ue65b"
+  },
+  {
+    "font_class": "circle-filled",
+    "unicode": "\ue65e"
+  },
+  {
+    "font_class": "clear",
+    "unicode": "\ue66d"
+  },
+  {
+    "font_class": "close",
+    "unicode": "\ue673"
+  },
+  {
+    "font_class": "closeempty",
+    "unicode": "\ue66c"
+  },
+  {
+    "font_class": "cloud-download",
+    "unicode": "\ue647"
+  },
+  {
+    "font_class": "cloud-download-filled",
+    "unicode": "\ue646"
+  },
+  {
+    "font_class": "cloud-upload",
+    "unicode": "\ue645"
+  },
+  {
+    "font_class": "cloud-upload-filled",
+    "unicode": "\ue648"
+  },
+  {
+    "font_class": "color",
+    "unicode": "\ue6cf"
+  },
+  {
+    "font_class": "color-filled",
+    "unicode": "\ue6c9"
+  },
+  {
+    "font_class": "compose",
+    "unicode": "\ue67f"
+  },
+  {
+    "font_class": "contact",
+    "unicode": "\ue693"
+  },
+  {
+    "font_class": "contact-filled",
+    "unicode": "\ue695"
+  },
+  {
+    "font_class": "down",
+    "unicode": "\ue6b8"
+  },
+	{
+	  "font_class": "bottom",
+	  "unicode": "\ue6b8"
+	},
+  {
+    "font_class": "download",
+    "unicode": "\ue68d"
+  },
+  {
+    "font_class": "download-filled",
+    "unicode": "\ue681"
+  },
+  {
+    "font_class": "email",
+    "unicode": "\ue69e"
+  },
+  {
+    "font_class": "email-filled",
+    "unicode": "\ue69a"
+  },
+  {
+    "font_class": "eye",
+    "unicode": "\ue651"
+  },
+  {
+    "font_class": "eye-filled",
+    "unicode": "\ue66a"
+  },
+  {
+    "font_class": "eye-slash",
+    "unicode": "\ue6b3"
+  },
+  {
+    "font_class": "eye-slash-filled",
+    "unicode": "\ue6b4"
+  },
+  {
+    "font_class": "fire",
+    "unicode": "\ue6a1"
+  },
+  {
+    "font_class": "fire-filled",
+    "unicode": "\ue6c5"
+  },
+  {
+    "font_class": "flag",
+    "unicode": "\ue65f"
+  },
+  {
+    "font_class": "flag-filled",
+    "unicode": "\ue660"
+  },
+  {
+    "font_class": "folder-add",
+    "unicode": "\ue6a9"
+  },
+  {
+    "font_class": "folder-add-filled",
+    "unicode": "\ue6c8"
+  },
+  {
+    "font_class": "font",
+    "unicode": "\ue6a3"
+  },
+  {
+    "font_class": "forward",
+    "unicode": "\ue6ba"
+  },
+  {
+    "font_class": "gear",
+    "unicode": "\ue664"
+  },
+  {
+    "font_class": "gear-filled",
+    "unicode": "\ue661"
+  },
+  {
+    "font_class": "gift",
+    "unicode": "\ue6a4"
+  },
+  {
+    "font_class": "gift-filled",
+    "unicode": "\ue6c4"
+  },
+  {
+    "font_class": "hand-down",
+    "unicode": "\ue63d"
+  },
+  {
+    "font_class": "hand-down-filled",
+    "unicode": "\ue63c"
+  },
+  {
+    "font_class": "hand-up",
+    "unicode": "\ue63f"
+  },
+  {
+    "font_class": "hand-up-filled",
+    "unicode": "\ue63e"
+  },
+  {
+    "font_class": "headphones",
+    "unicode": "\ue630"
+  },
+  {
+    "font_class": "heart",
+    "unicode": "\ue639"
+  },
+  {
+    "font_class": "heart-filled",
+    "unicode": "\ue641"
+  },
+  {
+    "font_class": "help",
+    "unicode": "\ue679"
+  },
+  {
+    "font_class": "help-filled",
+    "unicode": "\ue674"
+  },
+  {
+    "font_class": "home",
+    "unicode": "\ue662"
+  },
+  {
+    "font_class": "home-filled",
+    "unicode": "\ue663"
+  },
+  {
+    "font_class": "image",
+    "unicode": "\ue670"
+  },
+  {
+    "font_class": "image-filled",
+    "unicode": "\ue678"
+  },
+  {
+    "font_class": "images",
+    "unicode": "\ue650"
+  },
+  {
+    "font_class": "images-filled",
+    "unicode": "\ue64b"
+  },
+  {
+    "font_class": "info",
+    "unicode": "\ue669"
+  },
+  {
+    "font_class": "info-filled",
+    "unicode": "\ue649"
+  },
+  {
+    "font_class": "left",
+    "unicode": "\ue6b7"
+  },
+  {
+    "font_class": "link",
+    "unicode": "\ue6a5"
+  },
+  {
+    "font_class": "list",
+    "unicode": "\ue644"
+  },
+  {
+    "font_class": "location",
+    "unicode": "\ue6ae"
+  },
+  {
+    "font_class": "location-filled",
+    "unicode": "\ue6af"
+  },
+  {
+    "font_class": "locked",
+    "unicode": "\ue66b"
+  },
+  {
+    "font_class": "locked-filled",
+    "unicode": "\ue668"
+  },
+  {
+    "font_class": "loop",
+    "unicode": "\ue633"
+  },
+  {
+    "font_class": "mail-open",
+    "unicode": "\ue643"
+  },
+  {
+    "font_class": "mail-open-filled",
+    "unicode": "\ue63a"
+  },
+  {
+    "font_class": "map",
+    "unicode": "\ue667"
+  },
+  {
+    "font_class": "map-filled",
+    "unicode": "\ue666"
+  },
+  {
+    "font_class": "map-pin",
+    "unicode": "\ue6ad"
+  },
+  {
+    "font_class": "map-pin-ellipse",
+    "unicode": "\ue6ac"
+  },
+  {
+    "font_class": "medal",
+    "unicode": "\ue6a2"
+  },
+  {
+    "font_class": "medal-filled",
+    "unicode": "\ue6c3"
+  },
+  {
+    "font_class": "mic",
+    "unicode": "\ue671"
+  },
+  {
+    "font_class": "mic-filled",
+    "unicode": "\ue677"
+  },
+  {
+    "font_class": "micoff",
+    "unicode": "\ue67e"
+  },
+  {
+    "font_class": "micoff-filled",
+    "unicode": "\ue6b0"
+  },
+  {
+    "font_class": "minus",
+    "unicode": "\ue66f"
+  },
+  {
+    "font_class": "minus-filled",
+    "unicode": "\ue67d"
+  },
+  {
+    "font_class": "more",
+    "unicode": "\ue64d"
+  },
+  {
+    "font_class": "more-filled",
+    "unicode": "\ue64e"
+  },
+  {
+    "font_class": "navigate",
+    "unicode": "\ue66e"
+  },
+  {
+    "font_class": "navigate-filled",
+    "unicode": "\ue67a"
+  },
+  {
+    "font_class": "notification",
+    "unicode": "\ue6a6"
+  },
+  {
+    "font_class": "notification-filled",
+    "unicode": "\ue6c1"
+  },
+  {
+    "font_class": "paperclip",
+    "unicode": "\ue652"
+  },
+  {
+    "font_class": "paperplane",
+    "unicode": "\ue672"
+  },
+  {
+    "font_class": "paperplane-filled",
+    "unicode": "\ue675"
+  },
+  {
+    "font_class": "person",
+    "unicode": "\ue699"
+  },
+  {
+    "font_class": "person-filled",
+    "unicode": "\ue69d"
+  },
+  {
+    "font_class": "personadd",
+    "unicode": "\ue69f"
+  },
+  {
+    "font_class": "personadd-filled",
+    "unicode": "\ue698"
+  },
+  {
+    "font_class": "personadd-filled-copy",
+    "unicode": "\ue6d1"
+  },
+  {
+    "font_class": "phone",
+    "unicode": "\ue69c"
+  },
+  {
+    "font_class": "phone-filled",
+    "unicode": "\ue69b"
+  },
+  {
+    "font_class": "plus",
+    "unicode": "\ue676"
+  },
+  {
+    "font_class": "plus-filled",
+    "unicode": "\ue6c7"
+  },
+  {
+    "font_class": "plusempty",
+    "unicode": "\ue67b"
+  },
+  {
+    "font_class": "pulldown",
+    "unicode": "\ue632"
+  },
+  {
+    "font_class": "pyq",
+    "unicode": "\ue682"
+  },
+  {
+    "font_class": "qq",
+    "unicode": "\ue680"
+  },
+  {
+    "font_class": "redo",
+    "unicode": "\ue64a"
+  },
+  {
+    "font_class": "redo-filled",
+    "unicode": "\ue655"
+  },
+  {
+    "font_class": "refresh",
+    "unicode": "\ue657"
+  },
+  {
+    "font_class": "refresh-filled",
+    "unicode": "\ue656"
+  },
+  {
+    "font_class": "refreshempty",
+    "unicode": "\ue6bf"
+  },
+  {
+    "font_class": "reload",
+    "unicode": "\ue6b2"
+  },
+  {
+    "font_class": "right",
+    "unicode": "\ue6b5"
+  },
+  {
+    "font_class": "scan",
+    "unicode": "\ue62a"
+  },
+  {
+    "font_class": "search",
+    "unicode": "\ue654"
+  },
+  {
+    "font_class": "settings",
+    "unicode": "\ue653"
+  },
+  {
+    "font_class": "settings-filled",
+    "unicode": "\ue6ce"
+  },
+  {
+    "font_class": "shop",
+    "unicode": "\ue62f"
+  },
+  {
+    "font_class": "shop-filled",
+    "unicode": "\ue6cd"
+  },
+  {
+    "font_class": "smallcircle",
+    "unicode": "\ue67c"
+  },
+  {
+    "font_class": "smallcircle-filled",
+    "unicode": "\ue665"
+  },
+  {
+    "font_class": "sound",
+    "unicode": "\ue684"
+  },
+  {
+    "font_class": "sound-filled",
+    "unicode": "\ue686"
+  },
+  {
+    "font_class": "spinner-cycle",
+    "unicode": "\ue68a"
+  },
+  {
+    "font_class": "staff",
+    "unicode": "\ue6a7"
+  },
+  {
+    "font_class": "staff-filled",
+    "unicode": "\ue6cb"
+  },
+  {
+    "font_class": "star",
+    "unicode": "\ue688"
+  },
+  {
+    "font_class": "star-filled",
+    "unicode": "\ue68f"
+  },
+  {
+    "font_class": "starhalf",
+    "unicode": "\ue683"
+  },
+  {
+    "font_class": "trash",
+    "unicode": "\ue687"
+  },
+  {
+    "font_class": "trash-filled",
+    "unicode": "\ue685"
+  },
+  {
+    "font_class": "tune",
+    "unicode": "\ue6aa"
+  },
+  {
+    "font_class": "tune-filled",
+    "unicode": "\ue6ca"
+  },
+  {
+    "font_class": "undo",
+    "unicode": "\ue64f"
+  },
+  {
+    "font_class": "undo-filled",
+    "unicode": "\ue64c"
+  },
+  {
+    "font_class": "up",
+    "unicode": "\ue6b6"
+  },
+	{
+	  "font_class": "top",
+	  "unicode": "\ue6b6"
+	},
+  {
+    "font_class": "upload",
+    "unicode": "\ue690"
+  },
+  {
+    "font_class": "upload-filled",
+    "unicode": "\ue68e"
+  },
+  {
+    "font_class": "videocam",
+    "unicode": "\ue68c"
+  },
+  {
+    "font_class": "videocam-filled",
+    "unicode": "\ue689"
+  },
+  {
+    "font_class": "vip",
+    "unicode": "\ue6a8"
+  },
+  {
+    "font_class": "vip-filled",
+    "unicode": "\ue6c6"
+  },
+  {
+    "font_class": "wallet",
+    "unicode": "\ue6b1"
+  },
+  {
+    "font_class": "wallet-filled",
+    "unicode": "\ue6c2"
+  },
+  {
+    "font_class": "weibo",
+    "unicode": "\ue68b"
+  },
+  {
+    "font_class": "weixin",
+    "unicode": "\ue691"
+  }
+]
+
+// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

+ 16 - 13
uni_modules/uni-icons/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-icons",
   "displayName": "uni-icons 图标",
-  "version": "1.3.5",
+  "version": "2.0.10",
   "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
   "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,12 +42,14 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {
           "app-vue": "y",
-          "app-nvue": "y"
+          "app-nvue": "y",
+          "app-uvue": "y"
         },
         "H5-mobile": {
           "Safari": "y",
@@ -70,11 +69,15 @@
           "阿里": "y",
           "百度": "y",
           "字节跳动": "y",
-          "QQ": "y"
+          "QQ": "y",
+					"钉钉": "y",
+					"快手": "y",
+					"飞书": "y",
+					"京东": "y"
         },
         "快应用": {
-          "华为": "u",
-          "联盟": "u"
+          "华为": "y",
+          "联盟": "y"
         },
         "Vue": {
             "vue2": "y",
@@ -83,4 +86,4 @@
       }
     }
   }
-}
+}

+ 121 - 0
uni_modules/uni-id/changelog.md

@@ -0,0 +1,121 @@
+## 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)
+- 短信、一键登录相关密钥改为非必填
+## 3.3.29(2022-10-20)
+- 使用[uni-open-bridge-common](https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge.html#common)存储用户三方凭证,以便其他服务使用。
+## 3.3.28(2022-07-27)
+- 修复 app端微信登录返回的accessToken过期时间(expired)不正确的Bug
+## 3.3.27(2022-07-27)
+- 短信发送失败、微信登录失败等场景下输出原始错误方便排查错误
+## 3.3.26(2022-07-08)
+- 兼容配置放在uni-id下的逻辑,但是仍推荐使用uni-config-center
+## 3.3.25(2022-06-30)
+- 修复config文件不合法时未抛出具体错误的Bug
+## 3.3.24(2022-06-28)
+- 修复3.3.12引出的使用多应用配置时报错的Bug
+## 3.3.23(2022-06-13)
+- 修复上版本引出的部分依赖未找到的Bug
+## 3.3.22(2022-06-13)
+- 新增 preferedWebPlatform 配置用于解决HBuilderX 3.4.9版本起web端platform不一致的问题 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=prefered-web-platform)
+## 3.3.21(2022-05-24)
+- 修复createInstance传入clientInfo无效的Bug
+## 3.3.20(2022-05-19)
+- 调整以下错误码(账号已注册[uni-id-account-exists]、账号不存在[uni-id-account-not-exists]、账号已绑定[uni-id-account-bound])
+## 3.3.19(2022-05-19)
+- 修复 addUser 部分情况下会创建出重复账号的Bug
+## 3.3.18(2022-05-12)
+- 调整绑定、解绑邮箱手机号接口,只要传递code参数就进行验证码校验即使传递的值为undefined
+## 3.3.17(2022-05-09)
+- register_env内增加os_name字段用于区分注册时的客户端系统类型
+## 3.3.16(2022-05-09)
+- 修复 addUser接口添加的用户无法使用密码登录的Bug [详情](https://ask.dcloud.net.cn/question/144670)
+## 3.3.15(2022-05-08)
+- 修复config文件语法错误时报`this.t is not a function`的Bug 感谢@寒暄
+## 3.3.14(2022-05-08)
+- 新增 getWeixinUserInfo接口 用于获取app平台微信登录用户的用户信息 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id.html#get-weixin-user-info)
+- 新增 addUser接口 用于手动添加用户 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id.html#add-user)
+- 新增 resetPwdBySms接口 用于使用短信验证码重置密码 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id.html#reset-pwd-by-sms)
+- 新增 refreshToken接口 用于主动刷新用户token [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id.html#refresh-token)
+- 调整 用户注册时记录用户注册环境到 register_env 字段 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id.html#user-table)
+- 调整 用户注册时将注册 ip 移至 register_env 内
+
+## 3.3.13(2022-03-04)
+- createInstance方法支持传递clientInfo [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id.html#create-instance)
+- 修复`this.t is not a function`报错
+## 3.3.12(2022-01-15)
+- 新增 preferedAppPlatform 配置用于解决uni-app vue2版本vue3版本获取platform不一致的问题 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=prefered-app-platform)
+- 修复 checkToken 未返回自定义token内容的Bug
+## 3.3.11(2022-01-11)
+- 修复用户名密码登录时多个应用出现重复用户名登录报错的Bug
+## 3.3.10(2022-01-07)
+- 新增 自定义国际化语言支持 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=custom-i8n)
+- 修复 一键登录时未校验重复手机号是否已验证的Bug
+- 修复 Apple登录时用户邮箱为空时报错的Bug
+- 修复 登录接口未传username时错误提示不正确的Bug
+## 3.3.9(2021-11-09)
+- 去除重复的context.xxx未找到的提示语
+## 3.3.8(2021-10-28)
+- 新增 用户账户封禁接口 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=ban-account)
+- 新增 用户账户注销接口 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=close-account)
+- 修复 未传appid时用户重复注册的Bug
+## 3.3.7(2021-10-08)
+- 移除部分接口的废弃提示
+## 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目录规范

+ 88 - 0
uni_modules/uni-id/package.json

@@ -0,0 +1,88 @@
+{
+  "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"
+        }
+      }
+    }
+  }
+}

+ 33 - 0
uni_modules/uni-id/readme.md

@@ -0,0 +1,33 @@
+**文档已移至[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'对应的权限
+  }
+  ```

+ 201 - 0
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/LICENSE.md

@@ -0,0 +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.

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js


+ 20 - 0
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json

@@ -0,0 +1,20 @@
+{
+    "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"
+}

+ 1 - 1
uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue

@@ -53,7 +53,7 @@
 	}
 </script>
 
-<style lang="scss" >
+<style lang="scss" scoped>
 	.uni-indexed-list__list {
 		background-color: $uni-bg-color;
 		/* #ifndef APP-NVUE */

+ 2 - 2
uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue

@@ -140,7 +140,7 @@
 			setList() {
 				let index = 0;
 				this.lists = []
-				this.options.forEach((value) => {
+				this.options.forEach((value, index) => {
 					if (value.data.length === 0) {
 						return
 					}
@@ -282,7 +282,7 @@
 		}
 	}
 </script>
-<style lang="scss" >
+<style lang="scss" scoped>
 	.uni-indexed-list {
 		position: absolute;
 		left: 0;

+ 2 - 0
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)

+ 1 - 1
uni_modules/uni-list/components/uni-list-item/uni-list-item.vue

@@ -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 {

+ 7 - 4
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",

+ 3 - 303
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)
+3. 云端一体列表(列表模式):[https://ext.dcloud.net.cn/plugin?id=2672](https://ext.dcloud.net.cn/plugin?id=2672)

+ 6 - 0
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)

+ 5 - 0
uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue

@@ -37,7 +37,12 @@
 <script>
 	let platform
 	setTimeout(() => {
+		// #ifdef MP-WEIXIN
+		platform = uni.getDeviceInfo().platform
+		// #endif
+		// #ifndef MP-WEIXIN
 		platform = uni.getSystemInfoSync().platform
+		// #endif
 	}, 16)
 
 	import {

+ 7 - 9
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 @@
       }
     }
   }
-}
+}

+ 6 - 0
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)

+ 1 - 1
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);

+ 7 - 1
uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue

@@ -9,7 +9,13 @@
 		name: 'UniStatusBar',
 		data() {
 			return {
-				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px'
+				// #ifdef MP-WEIXIN
+				statusBarHeight: uni.getWindowInfo().statusBarHeight + 'px',
+				// #endif
+				// #ifndef MP-WEIXIN
+				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+				// #endif
+
 			}
 		}
 	}

+ 4 - 3
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 @@
       }
     }
   }
-}
+}

+ 2 - 0
uni_modules/uni-notice-bar/changelog.md

@@ -1,3 +1,5 @@
+## 1.2.2(2023-12-20)
+- 修复动态绑定title时,滚动速度不一致的问题
 ## 1.2.1(2022-09-05)
 - 新增 属性 fontSize,可修改文字大小。
 ## 1.2.0(2021-11-19)

+ 5 - 0
uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue

@@ -150,6 +150,11 @@
 				animationDelay: '0s'
 			}
 		},
+		watch:{
+			text:function(newValue,oldValue){
+				this.initSize();
+			}
+		},
 		computed: {
 			isShowGetMore() {
 				return this.showGetMore === true || this.showGetMore === 'true'

+ 1 - 1
uni_modules/uni-notice-bar/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-notice-bar",
   "displayName": "uni-notice-bar 通告栏",
-  "version": "1.2.1",
+  "version": "1.2.2",
   "description": "NoticeBar 通告栏组件,常用于展示公告信息,可设为滚动公告",
   "keywords": [
     "uni-ui",

+ 14 - 0
uni_modules/uni-number-box/changelog.md

@@ -1,3 +1,17 @@
+## 1.2.8(2024-04-26)
+- 修复 在vue2下H5黑边的bug
+## 1.2.7(2024-04-26)
+- 修复 在vue2手动输入后失焦导致清空数值的严重bug
+## 1.2.6(2024-02-22)
+- 新增 设置宽度属性width(单位:px)
+## 1.2.5(2024-02-21)
+- 修复 step步长小于1时,键盘类型为number的bug
+## 1.2.4(2024-02-02)
+- 修复 加减号垂直位置偏移样式问题
+## 1.2.3(2023-05-23)
+- 更新示例工程
+## 1.2.2(2023-05-08)
+- 修复 change 事件执行顺序错误的问题
 ## 1.2.1(2021-11-22)
 - 修复 vue3中某些scss变量无法找到的问题
 ## 1.2.0(2021-11-19)

+ 22 - 11
uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue

@@ -1,12 +1,14 @@
 <template>
 	<view class="uni-numbox">
 		<view @click="_calcValue('minus')" class="uni-numbox__minus uni-numbox-btns" :style="{background}">
-			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }" :style="{color}">-</text>
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }"
+				:style="{color}">-</text>
 		</view>
-		<input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value" type="number"
-			v-model="inputValue" :style="{background, color}" />
+		<input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value"
+			:type="step<1?'digit':'number'" v-model="inputValue" :style="{background, color, width:widthWithPx}" />
 		<view @click="_calcValue('plus')" class="uni-numbox__plus uni-numbox-btns" :style="{background}">
-			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }" :style="{color}">+</text>
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }"
+				:style="{color}">+</text>
 		</view>
 	</view>
 </template>
@@ -21,6 +23,7 @@
 	 * @property {Number} step 每次点击改变的间隔大小
 	 * @property {String} background 背景色
 	 * @property {String} color 字体颜色(前景色)
+	 * @property {Number} width 输入框宽度(单位:px)
 	 * @property {Boolean} disabled = [true|false] 是否为禁用状态
 	 * @event {Function} change 输入框值改变时触发的事件,参数为输入框当前的 value
 	 * @event {Function} focus 输入框聚焦时触发的事件,参数为 event 对象
@@ -62,6 +65,10 @@
 			disabled: {
 				type: Boolean,
 				default: false
+			},
+			width: {
+				type: Number,
+				default: 40,
 			}
 		},
 		data() {
@@ -77,6 +84,11 @@
 				this.inputValue = +val;
 			}
 		},
+		computed: {
+			widthWithPx() {
+				return this.width + 'px';
+			}
+		},
 		created() {
 			if (this.value === 1) {
 				this.inputValue = +this.modelValue;
@@ -114,11 +126,11 @@
 				}
 
 				this.inputValue = (value / scale).toFixed(String(scale).length - 1);
-				this.$emit("change", +this.inputValue);
 				// TODO vue2 兼容
 				this.$emit("input", +this.inputValue);
 				// TODO vue3 兼容
 				this.$emit("update:modelValue", +this.inputValue);
+				this.$emit("change", +this.inputValue);
 			},
 			_getDecimalScale() {
 
@@ -133,7 +145,7 @@
 				this.$emit('blur', event)
 				let value = event.detail.value;
 				if (isNaN(value)) {
-					this.inputValue = this.min;
+					this.inputValue = this.value;
 					return;
 				}
 				value = +value;
@@ -144,9 +156,9 @@
 				}
 				const scale = this._getDecimalScale();
 				this.inputValue = value.toFixed(String(scale).length - 1);
-				this.$emit("change", +this.inputValue);
 				this.$emit("input", +this.inputValue);
 				this.$emit("update:modelValue", +this.inputValue);
+				this.$emit("change", +this.inputValue);
 			},
 			_onFocus(event) {
 				this.$emit('focus', event)
@@ -154,7 +166,7 @@
 		}
 	};
 </script>
-<style lang="scss" >
+<style lang="scss">
 	$box-height: 26px;
 	$bg: #f5f5f5;
 	$br: 2px;
@@ -188,8 +200,7 @@
 		height: $box-height;
 		text-align: center;
 		font-size: 14px;
-		border-left-width: 0;
-		border-right-width: 0;
+		border-width: 0;
 		color: $color;
 	}
 
@@ -206,7 +217,7 @@
 	.uni-numbox--text {
 		// fix nvue
 		line-height: 20px;
-
+		margin-bottom: 2px;
 		font-size: 20px;
 		font-weight: 300;
 		color: $color;

+ 6 - 8
uni_modules/uni-number-box/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-number-box",
   "displayName": "uni-number-box 数字输入框",
-  "version": "1.2.1",
+  "version": "1.2.8",
   "description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。",
   "keywords": [
     "uni-ui",
@@ -15,11 +15,7 @@
   "directories": {
     "example": "../../temps/example_temps"
   },
-  "dcloudext": {
-    "category": [
-      "前端组件",
-      "通用组件"
-    ],
+"dcloudext": {
     "sale": {
       "regular": {
         "price": "0.00"
@@ -36,7 +32,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"],
@@ -44,7 +41,8 @@
     "platforms": {
       "cloud": {
         "tcb": "y",
-        "aliyun": "y"
+        "aliyun": "y",
+        "alipay": "n"
       },
       "client": {
         "App": {

+ 27 - 0
uni_modules/uni-open-bridge-common/changelog.md

@@ -0,0 +1,27 @@
+## 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)
+## 1.1.5(2023-03-27)
+- 修复 微信小程序平台 某些情况下 encrypt_key 插入错误的问题
+## 1.1.4(2023-03-13)
+- 修复 平台 weixin-web
+## 1.1.3(2023-03-13)
+- 新增 支持旧版本 uni-id 配置
+- 新增 支持平台 weixin-app|qq-mp|qq-app
+## 1.1.2(2023-02-28)
+- 新增 config 配置错误提示语
+## 1.1.1(2023-02-28)
+- 新增 支持 provider 参数,和 platform 保持一致
+## 1.1.0(2023-02-27)
+- 重要更新 调整数据库key格式,兼容旧版本API,如果开发者通过手动拼接key查询数据库需要修改现有逻辑
+  + 原格式: uni-id:[dcloudAppid]:[platform]:[openid]:[access-token|user-access-token|session-key|encrypt-key-version|ticket]
+  + 新格式: uni-id:[provider]:[appid]:[openid]:[access-token|user-access-token|session-key|encrypt-key-version|ticket]
+## 1.0.4(2022-09-21)
+- 新增 支持使用阿里云固定IP获取微信公众号H5凭据 access_token、ticket,开发者需要在微信公众平台配置阿里云固定IP,[固定IP详情](https://uniapp.dcloud.net.cn/uniCloud/cf-functions.html#aliyun-eip)
+## 1.0.3(2022-09-06)
+- 修复 过期时间问题,容错 AccessToken 默认 fallback 逻辑,当微信服务器没有返回过期时间时设置为2小时后过期
+## 1.0.2(2022-09-02)
+- 新增 依赖数据表schema opendb-open-data
+## 1.0.0(2022-08-22)
+- 首次发布

+ 84 - 0
uni_modules/uni-open-bridge-common/package.json

@@ -0,0 +1,84 @@
+{
+  "id": "uni-open-bridge-common",
+  "displayName": "uni-open-bridge-common",
+  "version": "1.2.1",
+  "description": "统一接管微信等三方平台认证凭据",
+  "keywords": [
+    "access_token",
+    "session_key",
+    "ticket"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.5.2"
+  },
+  "dcloudext": {
+    "type": "unicloud-template-function",
+    "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",
+        "alipay": "n"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "u",
+          "vue3": "u"
+        },
+        "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"
+        }
+      }
+    }
+  }
+}

+ 5 - 0
uni_modules/uni-open-bridge-common/readme.md

@@ -0,0 +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)

+ 26 - 0
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/bridge-error.js

@@ -0,0 +1,26 @@
+'use strict';
+
+class BridgeError extends Error {
+
+  constructor(code, message) {
+    super(message)
+
+    this._code = code
+  }
+
+  get code() {
+    return this._code
+  }
+
+  get errCode() {
+    return this._code
+  }
+
+  get errMsg() {
+    return this.message
+  }
+}
+
+module.exports = {
+  BridgeError
+}

+ 124 - 0
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/config.js

@@ -0,0 +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
+};

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor