From dd67c9edb6148f9cc06e97b88122fe79f4d1558d Mon Sep 17 00:00:00 2001
From: kaeery <3491123437@qq.com>
Date: Tue, 25 Feb 2025 23:25:52 +0800
Subject: [PATCH] =?UTF-8?q?=E3=80=90=E7=94=B5=E9=94=80=E8=80=81=E5=B8=88?=
=?UTF-8?q?=E5=92=8C=E6=8B=9B=E7=94=9F=E8=80=81=E5=B8=88=E3=80=91=20?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E#=20=E6=80=BB=E7=BB=93=E6=A8=A1=E6=9D=BF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/App.vue | 19 +
src/components/date-strip/date-strip-item.vue | 51 +
src/components/date-strip/index.scss | 21 +
src/components/date-strip/index.vue | 146 +
src/components/date-strip/props.ts | 108 +
src/components/date-strip/stripItemProps.ts | 58 +
src/components/date-strip/utils.ts | 74 +
.../widgets/date-strip/date-strip.vue | 26 +
.../widgets/summary-form/summary-form.vue | 70 +
src/pages.json | 12 +
src/pages/recruitsale/summary/index.vue | 41 +
src/pages/telesale/summary/index.vue | 26 +
src/styles/public.scss | 1 +
src/uni_modules/lime-date-strip/changelog.md | 4 +
.../l-date-strip-item/l-date-strip-item.uvue | 90 +
.../l-date-strip-item/l-date-strip-item.vue | 99 +
.../components/l-date-strip-item/props.ts | 54 +
.../components/l-date-strip-item/type.ts | 17 +
.../components/l-date-strip/index.scss | 153 +
.../components/l-date-strip/l-date-strip.uvue | 195 +
.../components/l-date-strip/l-date-strip.vue | 215 +
.../components/l-date-strip/props.ts | 108 +
.../components/l-date-strip/type.ts | 77 +
.../components/l-date-strip/utils.uts | 72 +
.../lime-date-strip/lime-date-strip.uvue | 149 +
.../lime-date-strip/lime-date-strip.vue | 153 +
src/uni_modules/lime-date-strip/index.ts | 2 +
src/uni_modules/lime-date-strip/package.json | 90 +
src/uni_modules/lime-date-strip/readme.md | 176 +
src/uni_modules/lime-shared/addUnit/index.ts | 42 +
.../lime-shared/animation/bezier.ts | 82 +
src/uni_modules/lime-shared/animation/ease.ts | 3 +
.../lime-shared/animation/index.ts | 10 +
.../lime-shared/animation/useTransition.ts | 103 +
.../lime-shared/animation/uvue.uts | 119 +
src/uni_modules/lime-shared/animation/vue.ts | 123 +
.../lime-shared/areaData/city-china.json | 3888 +++++++++++++++++
src/uni_modules/lime-shared/areaData/index.ts | 71 +
.../lime-shared/arrayBufferToFile/index.ts | 8 +
.../lime-shared/arrayBufferToFile/uvue.uts | 10 +
.../lime-shared/arrayBufferToFile/vue.ts | 63 +
.../lime-shared/base64ToArrayBuffer/index.ts | 13 +
.../lime-shared/base64ToPath/index.ts | 9 +
.../lime-shared/base64ToPath/uvue.uts | 22 +
.../lime-shared/base64ToPath/vue.ts | 75 +
.../lime-shared/camelCase/index.ts | 21 +
.../lime-shared/canIUseCanvas2d/index.ts | 67 +
.../lime-shared/capitalizedAmount/index.ts | 111 +
src/uni_modules/lime-shared/changelog.md | 63 +
.../lime-shared/characterLimit/index.ts | 63 +
src/uni_modules/lime-shared/clamp/index.ts | 16 +
.../lime-shared/cloneDeep/index.ts | 10 +
src/uni_modules/lime-shared/cloneDeep/uvue.ts | 17 +
src/uni_modules/lime-shared/cloneDeep/vue.ts | 103 +
src/uni_modules/lime-shared/closest/index.ts | 22 +
.../components/lime-shared/lime-shared.vue | 156 +
.../lime-shared/createAnimation/index.ts | 9 +
.../lime-shared/createAnimation/type.ts | 25 +
.../lime-shared/createAnimation/uvue.ts | 5 +
.../lime-shared/createAnimation/vue.ts | 148 +
.../lime-shared/createCanvas/index.ts | 73 +
.../lime-shared/createImage/index.ts | 71 +
src/uni_modules/lime-shared/debounce/index.ts | 10 +
src/uni_modules/lime-shared/debounce/uvue.ts | 36 +
src/uni_modules/lime-shared/debounce/vue.ts | 40 +
src/uni_modules/lime-shared/exif/index.ts | 9 +
src/uni_modules/lime-shared/exif/uvue.ts | 7 +
src/uni_modules/lime-shared/exif/vue.ts | 1057 +++++
src/uni_modules/lime-shared/fillZero/index.ts | 11 +
src/uni_modules/lime-shared/floatAdd/index.ts | 36 +
src/uni_modules/lime-shared/floatDiv/index.ts | 45 +
src/uni_modules/lime-shared/floatMul/index.ts | 44 +
src/uni_modules/lime-shared/floatSub/index.ts | 32 +
.../lime-shared/getClassStr/index.ts | 53 +
.../lime-shared/getCurrentPage/index.ts | 9 +
.../lime-shared/getCurrentPage/uvue.uts | 5 +
.../lime-shared/getCurrentPage/vue.ts | 6 +
.../lime-shared/getLocalFilePath/index.ts | 62 +
src/uni_modules/lime-shared/getRect/index.ts | 9 +
src/uni_modules/lime-shared/getRect/uvue.uts | 16 +
src/uni_modules/lime-shared/getRect/vue.ts | 117 +
.../lime-shared/getStyleStr/index.ts | 54 +
.../lime-shared/getStyleStr/index_.uts | 39 +
src/uni_modules/lime-shared/hasOwn/index.ts | 9 +
src/uni_modules/lime-shared/hasOwn/uvue.ts | 39 +
src/uni_modules/lime-shared/hasOwn/vue.ts | 30 +
src/uni_modules/lime-shared/index.ts | 43 +
src/uni_modules/lime-shared/isBase64/index.ts | 23 +
.../lime-shared/isBrowser/index.ts | 8 +
src/uni_modules/lime-shared/isDef/index.ts | 23 +
src/uni_modules/lime-shared/isEmpty/index.ts | 83 +
.../lime-shared/isFunction/index.ts | 16 +
src/uni_modules/lime-shared/isNumber/index.ts | 26 +
.../lime-shared/isNumeric/index.ts | 33 +
src/uni_modules/lime-shared/isObject/index.ts | 19 +
.../lime-shared/isPromise/index.ts | 22 +
src/uni_modules/lime-shared/isString/index.ts | 19 +
.../lime-shared/kebabCase/index.ts | 24 +
src/uni_modules/lime-shared/obj2url/index.ts | 11 +
src/uni_modules/lime-shared/package.json | 87 +
.../lime-shared/pathToBase64/index.ts | 9 +
.../lime-shared/pathToBase64/uvue.uts | 17 +
.../lime-shared/pathToBase64/vue.ts | 121 +
src/uni_modules/lime-shared/platform/index.ts | 34 +
src/uni_modules/lime-shared/raf/index.ts | 10 +
src/uni_modules/lime-shared/raf/uvue.ts | 48 +
src/uni_modules/lime-shared/raf/vue.ts | 32 +
src/uni_modules/lime-shared/random/index.ts | 24 +
src/uni_modules/lime-shared/range/index.ts | 36 +
src/uni_modules/lime-shared/readme.md | 464 ++
.../lime-shared/selectAllComponent/index.ts | 8 +
.../lime-shared/selectAllComponent/uvue.uts | 39 +
.../lime-shared/selectAllComponent/vue.ts | 151 +
.../lime-shared/selectComponent/index.ts | 7 +
.../lime-shared/selectComponent/uvue.uts | 75 +
.../lime-shared/selectComponent/vue.ts | 149 +
.../lime-shared/selectElement/index.uts | 275 ++
src/uni_modules/lime-shared/shuffle/index.ts | 16 +
src/uni_modules/lime-shared/sleep/index.ts | 44 +
src/uni_modules/lime-shared/throttle/index.ts | 77 +
src/uni_modules/lime-shared/toArray/index.ts | 21 +
.../lime-shared/toBoolean/index.ts | 40 +
src/uni_modules/lime-shared/toNumber/index.ts | 28 +
.../lime-shared/unitConvert/index.ts | 80 +
src/uni_modules/lime-shared/vue/index.ts | 16 +
125 files changed, 11961 insertions(+)
create mode 100644 src/components/date-strip/date-strip-item.vue
create mode 100644 src/components/date-strip/index.scss
create mode 100644 src/components/date-strip/index.vue
create mode 100644 src/components/date-strip/props.ts
create mode 100644 src/components/date-strip/stripItemProps.ts
create mode 100644 src/components/date-strip/utils.ts
create mode 100644 src/components/widgets/date-strip/date-strip.vue
create mode 100644 src/components/widgets/summary-form/summary-form.vue
create mode 100644 src/pages/recruitsale/summary/index.vue
create mode 100644 src/pages/telesale/summary/index.vue
create mode 100644 src/uni_modules/lime-date-strip/changelog.md
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip-item/l-date-strip-item.uvue
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip-item/l-date-strip-item.vue
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip-item/props.ts
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip-item/type.ts
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip/index.scss
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip/l-date-strip.uvue
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip/l-date-strip.vue
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip/props.ts
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip/type.ts
create mode 100644 src/uni_modules/lime-date-strip/components/l-date-strip/utils.uts
create mode 100644 src/uni_modules/lime-date-strip/components/lime-date-strip/lime-date-strip.uvue
create mode 100644 src/uni_modules/lime-date-strip/components/lime-date-strip/lime-date-strip.vue
create mode 100644 src/uni_modules/lime-date-strip/index.ts
create mode 100644 src/uni_modules/lime-date-strip/package.json
create mode 100644 src/uni_modules/lime-date-strip/readme.md
create mode 100644 src/uni_modules/lime-shared/addUnit/index.ts
create mode 100644 src/uni_modules/lime-shared/animation/bezier.ts
create mode 100644 src/uni_modules/lime-shared/animation/ease.ts
create mode 100644 src/uni_modules/lime-shared/animation/index.ts
create mode 100644 src/uni_modules/lime-shared/animation/useTransition.ts
create mode 100644 src/uni_modules/lime-shared/animation/uvue.uts
create mode 100644 src/uni_modules/lime-shared/animation/vue.ts
create mode 100644 src/uni_modules/lime-shared/areaData/city-china.json
create mode 100644 src/uni_modules/lime-shared/areaData/index.ts
create mode 100644 src/uni_modules/lime-shared/arrayBufferToFile/index.ts
create mode 100644 src/uni_modules/lime-shared/arrayBufferToFile/uvue.uts
create mode 100644 src/uni_modules/lime-shared/arrayBufferToFile/vue.ts
create mode 100644 src/uni_modules/lime-shared/base64ToArrayBuffer/index.ts
create mode 100644 src/uni_modules/lime-shared/base64ToPath/index.ts
create mode 100644 src/uni_modules/lime-shared/base64ToPath/uvue.uts
create mode 100644 src/uni_modules/lime-shared/base64ToPath/vue.ts
create mode 100644 src/uni_modules/lime-shared/camelCase/index.ts
create mode 100644 src/uni_modules/lime-shared/canIUseCanvas2d/index.ts
create mode 100644 src/uni_modules/lime-shared/capitalizedAmount/index.ts
create mode 100644 src/uni_modules/lime-shared/changelog.md
create mode 100644 src/uni_modules/lime-shared/characterLimit/index.ts
create mode 100644 src/uni_modules/lime-shared/clamp/index.ts
create mode 100644 src/uni_modules/lime-shared/cloneDeep/index.ts
create mode 100644 src/uni_modules/lime-shared/cloneDeep/uvue.ts
create mode 100644 src/uni_modules/lime-shared/cloneDeep/vue.ts
create mode 100644 src/uni_modules/lime-shared/closest/index.ts
create mode 100644 src/uni_modules/lime-shared/components/lime-shared/lime-shared.vue
create mode 100644 src/uni_modules/lime-shared/createAnimation/index.ts
create mode 100644 src/uni_modules/lime-shared/createAnimation/type.ts
create mode 100644 src/uni_modules/lime-shared/createAnimation/uvue.ts
create mode 100644 src/uni_modules/lime-shared/createAnimation/vue.ts
create mode 100644 src/uni_modules/lime-shared/createCanvas/index.ts
create mode 100644 src/uni_modules/lime-shared/createImage/index.ts
create mode 100644 src/uni_modules/lime-shared/debounce/index.ts
create mode 100644 src/uni_modules/lime-shared/debounce/uvue.ts
create mode 100644 src/uni_modules/lime-shared/debounce/vue.ts
create mode 100644 src/uni_modules/lime-shared/exif/index.ts
create mode 100644 src/uni_modules/lime-shared/exif/uvue.ts
create mode 100644 src/uni_modules/lime-shared/exif/vue.ts
create mode 100644 src/uni_modules/lime-shared/fillZero/index.ts
create mode 100644 src/uni_modules/lime-shared/floatAdd/index.ts
create mode 100644 src/uni_modules/lime-shared/floatDiv/index.ts
create mode 100644 src/uni_modules/lime-shared/floatMul/index.ts
create mode 100644 src/uni_modules/lime-shared/floatSub/index.ts
create mode 100644 src/uni_modules/lime-shared/getClassStr/index.ts
create mode 100644 src/uni_modules/lime-shared/getCurrentPage/index.ts
create mode 100644 src/uni_modules/lime-shared/getCurrentPage/uvue.uts
create mode 100644 src/uni_modules/lime-shared/getCurrentPage/vue.ts
create mode 100644 src/uni_modules/lime-shared/getLocalFilePath/index.ts
create mode 100644 src/uni_modules/lime-shared/getRect/index.ts
create mode 100644 src/uni_modules/lime-shared/getRect/uvue.uts
create mode 100644 src/uni_modules/lime-shared/getRect/vue.ts
create mode 100644 src/uni_modules/lime-shared/getStyleStr/index.ts
create mode 100644 src/uni_modules/lime-shared/getStyleStr/index_.uts
create mode 100644 src/uni_modules/lime-shared/hasOwn/index.ts
create mode 100644 src/uni_modules/lime-shared/hasOwn/uvue.ts
create mode 100644 src/uni_modules/lime-shared/hasOwn/vue.ts
create mode 100644 src/uni_modules/lime-shared/index.ts
create mode 100644 src/uni_modules/lime-shared/isBase64/index.ts
create mode 100644 src/uni_modules/lime-shared/isBrowser/index.ts
create mode 100644 src/uni_modules/lime-shared/isDef/index.ts
create mode 100644 src/uni_modules/lime-shared/isEmpty/index.ts
create mode 100644 src/uni_modules/lime-shared/isFunction/index.ts
create mode 100644 src/uni_modules/lime-shared/isNumber/index.ts
create mode 100644 src/uni_modules/lime-shared/isNumeric/index.ts
create mode 100644 src/uni_modules/lime-shared/isObject/index.ts
create mode 100644 src/uni_modules/lime-shared/isPromise/index.ts
create mode 100644 src/uni_modules/lime-shared/isString/index.ts
create mode 100644 src/uni_modules/lime-shared/kebabCase/index.ts
create mode 100644 src/uni_modules/lime-shared/obj2url/index.ts
create mode 100644 src/uni_modules/lime-shared/package.json
create mode 100644 src/uni_modules/lime-shared/pathToBase64/index.ts
create mode 100644 src/uni_modules/lime-shared/pathToBase64/uvue.uts
create mode 100644 src/uni_modules/lime-shared/pathToBase64/vue.ts
create mode 100644 src/uni_modules/lime-shared/platform/index.ts
create mode 100644 src/uni_modules/lime-shared/raf/index.ts
create mode 100644 src/uni_modules/lime-shared/raf/uvue.ts
create mode 100644 src/uni_modules/lime-shared/raf/vue.ts
create mode 100644 src/uni_modules/lime-shared/random/index.ts
create mode 100644 src/uni_modules/lime-shared/range/index.ts
create mode 100644 src/uni_modules/lime-shared/readme.md
create mode 100644 src/uni_modules/lime-shared/selectAllComponent/index.ts
create mode 100644 src/uni_modules/lime-shared/selectAllComponent/uvue.uts
create mode 100644 src/uni_modules/lime-shared/selectAllComponent/vue.ts
create mode 100644 src/uni_modules/lime-shared/selectComponent/index.ts
create mode 100644 src/uni_modules/lime-shared/selectComponent/uvue.uts
create mode 100644 src/uni_modules/lime-shared/selectComponent/vue.ts
create mode 100644 src/uni_modules/lime-shared/selectElement/index.uts
create mode 100644 src/uni_modules/lime-shared/shuffle/index.ts
create mode 100644 src/uni_modules/lime-shared/sleep/index.ts
create mode 100644 src/uni_modules/lime-shared/throttle/index.ts
create mode 100644 src/uni_modules/lime-shared/toArray/index.ts
create mode 100644 src/uni_modules/lime-shared/toBoolean/index.ts
create mode 100644 src/uni_modules/lime-shared/toNumber/index.ts
create mode 100644 src/uni_modules/lime-shared/unitConvert/index.ts
create mode 100644 src/uni_modules/lime-shared/vue/index.ts
diff --git a/src/App.vue b/src/App.vue
index e16cffa..2965e0f 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -28,5 +28,24 @@ onShow(async () => {
appStore.updateLocation()
} else appStore.closeTimer()
})
+
+// function genDates() {
+// const weekdays = ['日', '一', '二', '三', '四', '五', '六']
+// const currentDate = new Date()
+// const currentDayOfWeek = currentDate.getDay()
+// let preDateOfWeek = currentDate.getDate() - 1
+// const daysInRange = []
+// for (let i = currentDayOfWeek; i <= weekdays.length - 1; i++) {
+// preDateOfWeek = preDateOfWeek + 1
+// daysInRange.push(preDateOfWeek)
+// }
+// let currentDateOfWeek = currentDate.getDate()
+// for (let i = 0; i <= weekdays.length - daysInRange.length; i++) {
+// currentDateOfWeek = currentDateOfWeek - 1
+// daysInRange.unshift(currentDateOfWeek)
+// }
+// console.log(daysInRange)
+// }
+// genDates()
diff --git a/src/components/date-strip/date-strip-item.vue b/src/components/date-strip/date-strip-item.vue
new file mode 100644
index 0000000..5e78f42
--- /dev/null
+++ b/src/components/date-strip/date-strip-item.vue
@@ -0,0 +1,51 @@
+
+
+
+
+ {{ item.prefix }}
+
+
+
+ {{ item.text }}{{ item.index }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/date-strip/index.scss b/src/components/date-strip/index.scss
new file mode 100644
index 0000000..4e31c3d
--- /dev/null
+++ b/src/components/date-strip/index.scss
@@ -0,0 +1,21 @@
+.date-strip__item {
+ display: flex;
+ .date-strip__grid {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 12rpx;
+ &-info {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 72rpx;
+ height: 72rpx;
+ }
+ &--active-text {
+ color: #fff;
+ }
+ }
+}
diff --git a/src/components/date-strip/index.vue b/src/components/date-strip/index.vue
new file mode 100644
index 0000000..d0184ff
--- /dev/null
+++ b/src/components/date-strip/index.vue
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/date-strip/props.ts b/src/components/date-strip/props.ts
new file mode 100644
index 0000000..a4f8c92
--- /dev/null
+++ b/src/components/date-strip/props.ts
@@ -0,0 +1,108 @@
+export default {
+ // 第一天从星期几开始,默认 1 = 周一
+ firstDayOfWeek: {
+ type: Number,
+ default: 0
+ },
+ // 日期格式,可选
+ format: {
+ type: Function,
+ default: null
+ },
+
+ // 最大可选日期,不传则默认半年后
+ maxDate: {
+ type: Number,
+ default: null
+ },
+
+ // 最小可选日期,不传则默认今天
+ minDate: {
+ type: Number,
+ default: null
+ },
+
+ // 当前选择的日期
+ value: {
+ type: Number,
+ default: null
+ },
+
+ // 默认值(如果使用非 v-model 绑定)
+ defaultValue: {
+ type: Number,
+ default: null
+ },
+
+ // 模型值(如果使用 v-model 绑定)
+ modelValue: {
+ type: Number,
+ default: null
+ },
+
+ // 日期行高
+ height: {
+ type: String,
+ default: null
+ },
+
+ // 网格宽度
+ gridWidth: {
+ type: String,
+ default: null
+ },
+
+ // 主题色,对底部按钮和选中日期生效
+ color: {
+ type: String,
+ default: null
+ },
+
+ // 选中日期的背景色
+ activeBgColor: {
+ type: String,
+ default: null
+ },
+
+ // 选中日期的文字颜色
+ activeColor: {
+ type: String,
+ default: null
+ },
+
+ // 背景色
+ bgColor: {
+ type: String,
+ default: null
+ },
+
+ // 圆角半径
+ radius: {
+ type: String,
+ default: null
+ },
+
+ // 切换模式,'week' 或 'none'
+ switchMode: {
+ type: String,
+ default: 'week'
+ },
+
+ // 形状,'square'、'circle' 或 'none'
+ shape: {
+ type: String,
+ default: 'square'
+ },
+
+ // 控制是否显示切换上一屏和下一屏的按钮,仅在按周切换时有效
+ showNavigation: {
+ type: Boolean,
+ default: false
+ },
+
+ // 星期几的名称数组
+ weekdays: {
+ type: Array,
+ default: () => ['日', '一', '二', '三', '四', '五', '六']
+ }
+}
diff --git a/src/components/date-strip/stripItemProps.ts b/src/components/date-strip/stripItemProps.ts
new file mode 100644
index 0000000..9492595
--- /dev/null
+++ b/src/components/date-strip/stripItemProps.ts
@@ -0,0 +1,58 @@
+// @ts-nocheck
+export default {
+ dates: {
+ type: Array,
+ default: () => []
+ },
+ // 网格宽度
+ gridWidth: {
+ type: String,
+ default: null
+ },
+
+ // 主题色,对底部按钮和选中日期生效
+ color: {
+ type: String,
+ default: null
+ },
+
+ // 选中日期的背景色
+ activeBgColor: {
+ type: String,
+ default: null
+ },
+
+ // 选中日期的文字颜色
+ activeColor: {
+ type: String,
+ default: null
+ },
+
+ // 背景色
+ bgColor: {
+ type: String,
+ default: null
+ },
+
+ // 圆角半径
+ radius: {
+ type: String,
+ default: null
+ },
+
+ // 切换模式,'week' 或 'none'
+ switchMode: {
+ type: String,
+ default: 'week'
+ },
+
+ // 形状,'square'、'circle' 或 'none'
+ shape: {
+ type: String,
+ default: 'square'
+ },
+ selectedDate: {
+ type: [Date, String],
+ default: null
+ }
+}
diff --git a/src/components/date-strip/utils.ts b/src/components/date-strip/utils.ts
new file mode 100644
index 0000000..3d939ed
--- /dev/null
+++ b/src/components/date-strip/utils.ts
@@ -0,0 +1,74 @@
+// @ts-nocheck
+import { WeekRange, DateType } from './type'
+
+/**
+ * 获取指定日期所在周的日期范围。
+ * @param {Date} date - 指定日期。
+ * @param {number} firstDayOfWeek - 一周的第一天,0 表示周日,1 表示周一,以此类推。
+ * @returns {WeekRange} 返回一个包含周起始和结束日期的对象。
+ */
+
+export function getWeekRange(date: Date, firstDayOfWeek: number): WeekRange {
+ const start = new Date(date.getTime())
+ const dayOffset = (date.getDay() - firstDayOfWeek + 7) % 7
+ start.setDate(start.getDate() - dayOffset)
+
+ const end = new Date(start.getTime())
+ end.setDate(end.getDate() + 6)
+ return { start, end } as WeekRange
+}
+
+/**
+ * 向指定日期添加天数。
+ * @param {Date} date - 基础日期。
+ * @param {number} days - 要添加的天数,可以是正数或负数。
+ * @returns {Date} 返回一个新的日期对象,该对象是基础日期加上指定天数后的结果。
+ */
+export function addDays(date: Date, days: number): Date {
+ const result = new Date(date.getTime())
+ result.setDate(result.getDate() + days)
+ return result
+}
+
+export function addWeeks(date: Date, weeks: number): Date {
+ const result = new Date(date.getTime())
+ result.setDate(result.getDate() + weeks * 7)
+ return result
+}
+
+/**
+ * 判断两个日期是否表示同一天(忽略时间部分)。
+ *
+ * @param date1 - 第一个日期。
+ * @param date2 - 第二个日期。
+ * @returns 如果两个日期是同一天,返回 true;否则返回 false。
+ */
+function isSameDate(date1: Date, date2: Date): boolean {
+ return (
+ date1.getFullYear() == date2.getFullYear() &&
+ date1.getMonth() == date2.getMonth() &&
+ date1.getDate() == date2.getDate()
+ )
+}
+export function calcType(
+ date: Date,
+ minDate: Date,
+ maxDate: Date,
+ selectedDate: Date | null
+): DateType {
+ // 检查日期是否早于 minDate 或晚于 maxDate
+ if (date.getTime() < minDate.getTime() || date.getTime() > maxDate.getTime()) {
+ return 'disabled'
+ }
+ // 如果 selectedDate 不为 null,检查日期是否等于 selectedDate
+ if (selectedDate != null && isSameDate(date, selectedDate)) {
+ return 'selected'
+ }
+ return ''
+}
+
+export function daysBetween(date1: Date, date2: Date): number {
+ // 将两个日期转换为毫秒
+ const diffInMilliseconds = Math.abs(date2.getTime() - date1.getTime())
+ return Math.floor(diffInMilliseconds / (1000 * 3600 * 24))
+}
diff --git a/src/components/widgets/date-strip/date-strip.vue b/src/components/widgets/date-strip/date-strip.vue
new file mode 100644
index 0000000..a768232
--- /dev/null
+++ b/src/components/widgets/date-strip/date-strip.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/widgets/summary-form/summary-form.vue b/src/components/widgets/summary-form/summary-form.vue
new file mode 100644
index 0000000..c2c71fe
--- /dev/null
+++ b/src/components/widgets/summary-form/summary-form.vue
@@ -0,0 +1,70 @@
+
+
+
+
+ {{ item.formTitle }}
+
+
+
+
+
+
+
+
+ 确认
+
+
+
+
+
+
+
diff --git a/src/pages.json b/src/pages.json
index 464c4d4..76c036e 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -1,5 +1,17 @@
{
"pages": [
+ {
+ "path": "pages/recruitsale/summary/index",
+ "style": {
+ "navigationBarTitleText": ""
+ }
+ },
+ {
+ "path": "pages/telesale/summary/index",
+ "style": {
+ "navigationBarTitleText": ""
+ }
+ },
{
"path": "pages/recruitsale/home/index",
"style": {
diff --git a/src/pages/recruitsale/summary/index.vue b/src/pages/recruitsale/summary/index.vue
new file mode 100644
index 0000000..96f41cb
--- /dev/null
+++ b/src/pages/recruitsale/summary/index.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/telesale/summary/index.vue b/src/pages/telesale/summary/index.vue
new file mode 100644
index 0000000..bae2787
--- /dev/null
+++ b/src/pages/telesale/summary/index.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/styles/public.scss b/src/styles/public.scss
index 10bc384..62a9adb 100644
--- a/src/styles/public.scss
+++ b/src/styles/public.scss
@@ -126,6 +126,7 @@ page {
padding-right: 0 !important;
// background-color: $gray-1 !important;
}
+
// 显示字段的表单,不需要输入
.c-form-item-wrapper {
@apply px-[32rpx];
diff --git a/src/uni_modules/lime-date-strip/changelog.md b/src/uni_modules/lime-date-strip/changelog.md
new file mode 100644
index 0000000..7247b34
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/changelog.md
@@ -0,0 +1,4 @@
+## 0.0.2(2025-02-10)
+- fix: 修复因导入`unitConvert`为小写名称导致微信小程序无法使用
+## 0.0.1(2025-01-28)
+- init
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip-item/l-date-strip-item.uvue b/src/uni_modules/lime-date-strip/components/l-date-strip-item/l-date-strip-item.uvue
new file mode 100644
index 0000000..6d9e88e
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip-item/l-date-strip-item.uvue
@@ -0,0 +1,90 @@
+
+
+
+ {{item.prefix}}
+
+ {{item.text}}
+ {{item.suffix}}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip-item/l-date-strip-item.vue b/src/uni_modules/lime-date-strip/components/l-date-strip-item/l-date-strip-item.vue
new file mode 100644
index 0000000..6b68d56
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip-item/l-date-strip-item.vue
@@ -0,0 +1,99 @@
+
+
+
+ {{item.prefix}}
+
+ {{item.text}}
+ {{item.suffix}}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip-item/props.ts b/src/uni_modules/lime-date-strip/components/l-date-strip-item/props.ts
new file mode 100644
index 0000000..c182fed
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip-item/props.ts
@@ -0,0 +1,54 @@
+// @ts-nocheck
+export default {
+ dates: {
+ type: Array,
+ default: () => []
+ },
+ // 网格宽度
+ gridWidth: {
+ type: String,
+ default: null
+ },
+
+ // 主题色,对底部按钮和选中日期生效
+ color: {
+ type: String,
+ default: null
+ },
+
+ // 选中日期的背景色
+ activeBgColor: {
+ type: String,
+ default: null
+ },
+
+ // 选中日期的文字颜色
+ activeColor: {
+ type: String,
+ default: null
+ },
+
+ // 背景色
+ bgColor: {
+ type: String,
+ default: null
+ },
+
+ // 圆角半径
+ radius: {
+ type: String,
+ default: null
+ },
+
+ // 切换模式,'week' 或 'none'
+ switchMode: {
+ type: String,
+ default: 'week',
+ },
+
+ // 形状,'square'、'circle' 或 'none'
+ shape: {
+ type: String,
+ default: 'square'
+ },
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip-item/type.ts b/src/uni_modules/lime-date-strip/components/l-date-strip-item/type.ts
new file mode 100644
index 0000000..5d7a943
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip-item/type.ts
@@ -0,0 +1,17 @@
+// @ts-nocheck
+import { Day } from '../l-date-strip/type';
+
+export interface DateStripItemProps {
+ dates: Day[];
+ /**
+ * 主题色,对底部按钮和选中日期生效
+ */
+ color ?: string;
+ activeBgColor ?: string;
+ activeColor ?: string;
+ bgColor ?: string;
+ radius ?: string;
+ gridWidth ?: string;
+ switchMode: 'week' | 'none';
+ shape: 'square' | 'circle' | 'text';
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip/index.scss b/src/uni_modules/lime-date-strip/components/l-date-strip/index.scss
new file mode 100644
index 0000000..49c6aad
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip/index.scss
@@ -0,0 +1,153 @@
+@import '~@/uni_modules/lime-style/index.scss';
+$prefix: l !default;
+$date-strip: #{$prefix}-date-strip;
+
+$date-strip-bg-color: create-var(date-strip-bg-color, $bg-color-container);
+$date-strip-height: create-var(date-strip-height, 86px);
+$date-strip-padding: create-var(date-strip-padding, 8px 0);
+$date-strip-font-size: create-var(date-strip-font-size, 16px);
+$date-strip-color: create-var(date-strip-color, $text-color-1);
+$date-strip-prefix-color: create-var(date-strip-prefix-color, $text-color-3);
+$date-strip-prefix-font-size: create-var(date-strip-prefix-font-size, 14px);
+$date-strip-suffix-color: create-var(date-strip-color, $text-color-2);
+$date-strip-suffix-font-size: create-var(date-strip-font-size, 12px);
+$date-strip-active-color: create-var(date-strip-active-color, $primary-color);
+$date-strip-square-radius: create-var(date-strip-square-radius, 5px);
+
+$date-strip-grid-width: create-var(date-strip-grid-width, 50px);
+// $date-strip-grid-prefix-padding: create-var(date-strip-grid-prefix-padding, 4px);
+$date-strip-grid-square-padding: create-var(date-strip-grid-square-padding, 6px 0);
+$date-strip-grid-circle-radius: create-var(date-strip-grid-circle-radius, 99px);
+// $date-strip-grid-suffix-translate: create-var(date-strip-grid-suffix-translate, 60%);
+
+.#{$date-strip} {
+ height: $date-strip-height;
+ background-color: $date-strip-bg-color;
+ &__scroll {
+ flex-direction: row;
+ }
+ &__item {
+ display: flex;
+ flex-direction: row;
+ padding: $date-strip-padding;
+ box-sizing: border-box;
+ /* #ifndef APP-ANDROID || APP-IOS */
+ height: 100%;
+ /* #endif */
+ &--week {
+ flex: 1;
+ .#{$date-strip}__grid {
+ flex: 1;
+ }
+ }
+ &--none {
+ .#{$date-strip}__grid {
+ width: $date-strip-grid-width;
+ }
+ }
+ }
+
+ &__grid {
+ /* #ifndef APP-ANDROID || APP-IOS */
+ flex-shrink: 0;
+ /* #endif */
+ display: flex;
+ flex-direction: column;
+ margin: 0 4rpx;
+ transition-duration: 300ms;
+ transition-property: background-color, color;
+ transition-timing-function: linear;
+
+ &-prefix,&-day,&-suffix {
+ text-align: center;
+ transition-duration: 200ms;
+ transition-property: color;
+ transition-timing-function: linear;
+ }
+ &-prefix {
+ font-size: $date-strip-prefix-font-size;
+ // font-weight: bold;
+ color: $date-strip-prefix-color;
+ }
+ &--none {
+ .l-date-strip__grid-prefix {
+ padding-bottom: 4px;
+ padding-top: 4px;
+ }
+ }
+ &--circle {
+ .l-date-strip__grid-prefix {
+ padding-bottom: 4px;
+ }
+ .l-date-strip__grid-info {
+ border-radius: $date-strip-grid-circle-radius;
+ }
+ }
+ &--square {
+ border-radius: $date-strip-square-radius;
+ padding: $date-strip-grid-square-padding;
+ }
+ &-suffix {
+ position: absolute;
+ top: 50%;
+ transform: translateY(60%);
+ font-size: $date-strip-suffix-font-size;
+ color: $date-strip-suffix-color;
+ }
+ &-day {
+ font-size: $date-strip-font-size;
+ color: $date-strip-color;
+ font-weight: bold;
+ }
+ &-info {
+ display: flex;
+ flex: 1;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+ }
+ &--active-bg {
+ background-color: $date-strip-active-color;
+ }
+ &--active-text {
+ color: white;
+ &-none {
+ color: $date-strip-active-color;
+ }
+ }
+ // &--selected {
+ // &.l-date-strip__grid--circle {
+ // .l-date-strip__grid {
+ // &-info {
+ // // border-radius: 99px;
+ // background-color: $date-strip-active-color;
+ // }
+ // &-day,&-suffix {
+ // color: white;
+ // }
+ // }
+ // }
+ // &.l-date-strip__grid--square {
+ // background-color: $date-strip-active-color;
+ // border-radius: $date-strip-square-radius;
+
+ // .l-date-strip__grid {
+ // &-prefix,&-day,&-suffix {
+ // color: white;
+ // }
+ // }
+ // }
+ // &.l-date-strip__grid--none {
+ // .l-date-strip__grid {
+ // &-prefix,&-day,&-suffix {
+ // color: $date-strip-active-color;
+ // // font-weight: bold;
+ // }
+ // }
+ // }
+ // }
+ &--disabled {
+ opacity: 0.4;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip/l-date-strip.uvue b/src/uni_modules/lime-date-strip/components/l-date-strip/l-date-strip.uvue
new file mode 100644
index 0000000..b33e28b
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip/l-date-strip.uvue
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip/l-date-strip.vue b/src/uni_modules/lime-date-strip/components/l-date-strip/l-date-strip.vue
new file mode 100644
index 0000000..49fdc10
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip/l-date-strip.vue
@@ -0,0 +1,215 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip/props.ts b/src/uni_modules/lime-date-strip/components/l-date-strip/props.ts
new file mode 100644
index 0000000..2c69dd5
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip/props.ts
@@ -0,0 +1,108 @@
+export default {
+ // 第一天从星期几开始,默认 1 = 周一
+ firstDayOfWeek: {
+ type: Number,
+ default: 0,
+ },
+ // 日期格式,可选
+ format: {
+ type: Function,
+ default: null
+ },
+
+ // 最大可选日期,不传则默认半年后
+ maxDate: {
+ type: Number,
+ default: null
+ },
+
+ // 最小可选日期,不传则默认今天
+ minDate: {
+ type: Number,
+ default: null
+ },
+
+ // 当前选择的日期
+ value: {
+ type: Number,
+ default: null
+ },
+
+ // 默认值(如果使用非 v-model 绑定)
+ defaultValue: {
+ type: Number,
+ default: null
+ },
+
+ // 模型值(如果使用 v-model 绑定)
+ modelValue: {
+ type: Number,
+ default: null
+ },
+
+ // 日期行高
+ height: {
+ type: String,
+ default: null
+ },
+
+ // 网格宽度
+ gridWidth: {
+ type: String,
+ default: null
+ },
+
+ // 主题色,对底部按钮和选中日期生效
+ color: {
+ type: String,
+ default: null
+ },
+
+ // 选中日期的背景色
+ activeBgColor: {
+ type: String,
+ default: null
+ },
+
+ // 选中日期的文字颜色
+ activeColor: {
+ type: String,
+ default: null
+ },
+
+ // 背景色
+ bgColor: {
+ type: String,
+ default: null
+ },
+
+ // 圆角半径
+ radius: {
+ type: String,
+ default: null
+ },
+
+ // 切换模式,'week' 或 'none'
+ switchMode: {
+ type: String,
+ default: 'week',
+ },
+
+ // 形状,'square'、'circle' 或 'none'
+ shape: {
+ type: String,
+ default: 'square'
+ },
+
+ // 控制是否显示切换上一屏和下一屏的按钮,仅在按周切换时有效
+ showNavigation: {
+ type: Boolean,
+ default: false
+ },
+
+ // 星期几的名称数组
+ weekdays: {
+ type: Array,
+ default: () => ['日', '一', '二', '三', '四', '五', '六']
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip/type.ts b/src/uni_modules/lime-date-strip/components/l-date-strip/type.ts
new file mode 100644
index 0000000..555f636
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip/type.ts
@@ -0,0 +1,77 @@
+// @ts-nocheck
+export type DateType = 'selected' | 'disabled' | '';
+
+/**
+ * 定义一个表示周范围的类
+ */
+export type WeekRange = {
+ start: Date
+ end: Date
+}
+
+export type Day = {
+ date : Date;
+ key: string,
+ day : number;
+ year : number;
+ month : number;
+ text: string;
+ type : DateType;
+ prefix : string;
+ prefixStyle ?: UTSJSONObject;
+ textStyle?: UTSJSONObject;
+ suffix ?: string;
+ suffixStyle ?: UTSJSONObject;
+}
+
+
+export type WeekDateCollection = {
+ start: number,
+ end: number,
+ dates : Day[];
+}
+
+export type DateFormatType = (day : Day) => Day;
+export interface DateStripProps {
+ /**
+ * 第一天从星期几开始,默认 0 = 周日
+ * @default 1
+ */
+ firstDayOfWeek : number;
+ format ?: DateFormatType;
+ /**
+ * 最大可选的日期,不传则默认半年后
+ */
+ maxDate ?: number;
+ /**
+ * 最小可选的日期,不传则默认今天
+ */
+ minDate ?: number;
+ /**
+ * 当前选择的日期
+ */
+ value ?: number;
+ defaultValue ?: number;
+ modelValue ?: number;
+ /**
+ * 日期行高
+ */
+ height ?: string;
+ gridWidth ?: string;
+ /**
+ * 主题色,对底部按钮和选中日期生效
+ */
+ color ?: string;
+ activeBgColor ?: string;
+ activeColor ?: string;
+ bgColor ?: string;
+ radius ?: string;
+ switchMode: 'week' | 'none';
+ shape: 'square' | 'circle' | 'none';
+ /**
+ * 控制是否显示切换上一屏和下一屏的按钮。
+ * 该属性仅在按周切换时有效。
+ */
+ showNavigation ?: boolean;
+ weekdays : string[];
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/l-date-strip/utils.uts b/src/uni_modules/lime-date-strip/components/l-date-strip/utils.uts
new file mode 100644
index 0000000..2ac520b
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/l-date-strip/utils.uts
@@ -0,0 +1,72 @@
+// @ts-nocheck
+import { WeekRange, DateType } from './type';
+
+
+/**
+ * 获取指定日期所在周的日期范围。
+ * @param {Date} date - 指定日期。
+ * @param {number} firstDayOfWeek - 一周的第一天,0 表示周日,1 表示周一,以此类推。
+ * @returns {WeekRange} 返回一个包含周起始和结束日期的对象。
+ */
+
+export function getWeekRange(date : Date, firstDayOfWeek : number) : WeekRange {
+ const start = new Date(date.getTime());
+ const dayOffset = (date.getDay() - firstDayOfWeek + 7) % 7;
+ start.setDate(start.getDate() - dayOffset);
+
+ const end = new Date(start.getTime());
+ end.setDate(end.getDate() + 6);
+ return { start, end } as WeekRange
+};
+
+/**
+ * 向指定日期添加天数。
+ * @param {Date} date - 基础日期。
+ * @param {number} days - 要添加的天数,可以是正数或负数。
+ * @returns {Date} 返回一个新的日期对象,该对象是基础日期加上指定天数后的结果。
+ */
+export function addDays(date : Date, days : number) : Date {
+ const result = new Date(date.getTime());
+ result.setDate(result.getDate() + days);
+ return result;
+};
+
+
+export function addWeeks(date : Date, weeks : number) : Date {
+ const result = new Date(date.getTime());
+ result.setDate(result.getDate() + weeks * 7);
+ return result;
+};
+
+/**
+ * 判断两个日期是否表示同一天(忽略时间部分)。
+ *
+ * @param date1 - 第一个日期。
+ * @param date2 - 第二个日期。
+ * @returns 如果两个日期是同一天,返回 true;否则返回 false。
+ */
+function isSameDate(date1 : Date, date2 : Date) : boolean {
+ return (
+ date1.getFullYear() == date2.getFullYear() &&
+ date1.getMonth() == date2.getMonth() &&
+ date1.getDate() == date2.getDate()
+ );
+}
+export function calcType(date : Date, minDate : Date, maxDate : Date, selectedDate : Date | null) : DateType {
+ // 检查日期是否早于 minDate 或晚于 maxDate
+ if (date.getTime() < minDate.getTime() || date.getTime() > maxDate.getTime()) {
+ return 'disabled';
+ }
+ // 如果 selectedDate 不为 null,检查日期是否等于 selectedDate
+ if (selectedDate != null && isSameDate(date, selectedDate)) {
+ return 'selected';
+ }
+ return ''
+}
+
+
+export function daysBetween(date1: Date, date2: Date): number {
+ // 将两个日期转换为毫秒
+ const diffInMilliseconds = Math.abs(date2.getTime() - date1.getTime());
+ return Math.floor(diffInMilliseconds / (1000 * 3600 * 24));
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/lime-date-strip/lime-date-strip.uvue b/src/uni_modules/lime-date-strip/components/lime-date-strip/lime-date-strip.uvue
new file mode 100644
index 0000000..d03cd56
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/lime-date-strip/lime-date-strip.uvue
@@ -0,0 +1,149 @@
+
+
+ DateStrip 日期横条
+ 用于展示周日历或一组日历信息。
+
+
+ 基础用法
+
+
+
+
+
+ 切换方式
+
+
+
+
+
+ 选择样式
+
+
+
+
+
+ shape none
+
+
+
+
+
+ 自定义样式
+
+
+
+
+
+ 自定义日期范围
+
+
+
+
+
+ 自定义日期文案
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/components/lime-date-strip/lime-date-strip.vue b/src/uni_modules/lime-date-strip/components/lime-date-strip/lime-date-strip.vue
new file mode 100644
index 0000000..91f9dd9
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/components/lime-date-strip/lime-date-strip.vue
@@ -0,0 +1,153 @@
+
+
+ DateStrip 日期横条
+ 用于展示周日历或一组日历信息。
+
+
+ 基础用法
+
+
+
+
+
+ 切换方式
+
+
+
+
+
+ 选中样式
+
+
+
+
+
+ shape none
+
+
+
+
+
+ 自定义样式
+
+
+
+
+
+ 自定义日期范围
+
+
+
+
+
+ 自定义日期文案
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/index.ts b/src/uni_modules/lime-date-strip/index.ts
new file mode 100644
index 0000000..b6731f6
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/index.ts
@@ -0,0 +1,2 @@
+// @ts-nocheck
+export * from './components/l-date-strip/type';
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/package.json b/src/uni_modules/lime-date-strip/package.json
new file mode 100644
index 0000000..bb53822
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/package.json
@@ -0,0 +1,90 @@
+{
+ "id": "lime-date-strip",
+ "displayName": "lime-date-strip 日期横条",
+ "version": "0.0.2",
+ "description": "lime-date-strip 日期横条用于展示周日历或一组日历信息,兼容uniapp/uniappx",
+ "keywords": [
+ "lime-date-strip",
+ "周日历",
+ "时间周",
+ "日期横条"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^4.45"
+ },
+ "dcloudext": {
+ "type": "component-vue",
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": ""
+ },
+ "uni_modules": {
+ "dependencies": [
+ "lime-style",
+ "lime-shared"
+ ],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "y"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "u",
+ "vue3": "y"
+ },
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "u",
+ "app-uvue": "y",
+ "app-harmony": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "u",
+ "IE": "u",
+ "Edge": "u",
+ "Firefox": "u",
+ "Safari": "u"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "u",
+ "百度": "u",
+ "字节跳动": "u",
+ "QQ": "u",
+ "钉钉": "u",
+ "快手": "u",
+ "飞书": "u",
+ "京东": "u"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-date-strip/readme.md b/src/uni_modules/lime-date-strip/readme.md
new file mode 100644
index 0000000..d9d4539
--- /dev/null
+++ b/src/uni_modules/lime-date-strip/readme.md
@@ -0,0 +1,176 @@
+# lime-date-strip 日期横条
+- 用于展示周日历或一组日历信息
+- 插件依赖`lime-style`,`lime-shared`不喜勿下
+
+## 安装
+插件市场导入即可,首次可能需要重新编译
+
+## 代码演示
+
+
+### 基础用法
+通过`v-model`可以绑定选择的日历
+```html
+
+```
+```js
+const value = new Date().getTime()
+
+const onChange = (time: number) => {
+
+}
+```
+
+
+### 切换方式
+默认是以周为周期`(swiper)`的切换方式,通过`switchMode`设置为`none`可以换成`scroll-view`,这时是从`minDate`到`maxDate`的所有日期。
+
+```html
+
+```
+```js
+const minDate: new Date(2022, 0, 10).getTime()
+const maxDate: new Date(2027, 10, 27).getTime()
+```
+
+### 选中样式
+
+通过 `shape` 可以设置为选中框的形状,可选值有:`circle`,`square`,`none`。
+
+```html
+
+```
+
+
+### 自定义样式
+
+通过 `bgColor` 可以设置背景色,`activeBgColor`可设置选中的背景色。
+
+```html
+
+```
+
+### 自定义日期文案
+通过传入 `format` 函数来对日历上每一格的内容进行格式化。
+
+```html
+
+```
+```js
+// uniapp 不需要设置类型
+import { Day } from '@/uni_modules/lime-date-strip';
+const customFormat = (day : Day) : Day => {
+ const { date } = day;
+ const year = date.getFullYear();
+ const month = date.getMonth() + 1;
+ const curDate = date.getDate();
+
+ day.suffix = '¥60';
+
+ if (year == 2025) {
+ if (month == 2) {
+ const map = new Map([
+ [1, '初一'],
+ [2, '初二'],
+ [3, '初三'],
+ [14, '情人节'],
+ [15, '元宵节'],
+ ])
+ if (map.has(curDate)) {
+ day.prefix = map.get(curDate)!;
+ day.suffix = '¥100';
+ }
+ }
+ }
+
+ return day;
+};
+```
+
+
+
+### 查看示例
+- 导入后直接使用这个标签查看演示效果
+
+```html
+ // 代码位于 uni_modules/lime-date-strip/compoents/lime-date-strip
+
+```
+
+### 插件标签
+- 默认 l-date-strip 为 component
+- 默认 lime-date-strip 为 demo
+
+### 关于vue2的使用方式
+- 插件使用了`composition-api`, 如果你希望在vue2中使用请按官方的教程[vue-composition-api](https://uniapp.dcloud.net.cn/tutorial/vue-composition-api.html)配置
+- 关键代码是: 在main.js中 在vue2部分加上这一段即可.
+
+```js
+// vue2
+import Vue from 'vue'
+import VueCompositionAPI from '@vue/composition-api'
+Vue.use(VueCompositionAPI)
+```
+
+## API
+
+### Props
+
+| 参数 | 说明 | 类型 | 默认值 |
+| ------ | ---------------------- | --------- | ------- |
+| v-modle | 选中的日期 | _number_ | `` |
+| defaultValue | 选中的日期 | _number_ | `` |
+| value | 选中的日期 | _number_ | `` |
+| switchMode |切换模式:
`none` 平铺展示所有日期,不展示切换按钮,
`week` 按周方式切换 | _string_ | `week` |
+| shape |选中框形状:
`square` 方块,包含星期和日期,
`circle` 圆形,只包含日期,
`none` 文本高亮 | _string_ | `square` |
+| minDate | 可选择的最小日期 | _number_ | |
+| maxDate | 可选择的最大日期 | _number_ | 当前日期的31天 |
+| height | 插件高度 | _string_ | |
+| gridWidth | 每格日期宽度,仅switchMode为`none`生效 | _string_ | |
+| activeBgColor | 选中框背景色 | _string_ | |
+| activeColor | 选中框文本色 | _string_ | |
+| bgColor | 横条背景色 | _string_ | |
+| radius | 选中框圆角 | _string_ | |
+| firstDayOfWeek | 第一天从星期几开始,默认 0 = 周日 | _0-6_ | `0` |
+
+
+
+### Events
+
+| 事件名 | 说明 | 回调参数 |
+| ------ | ---------------- | ------------------- |
+| change | 点击时触发 | _event: number_ |
+| select | 点击时触发 | _event: number_ |
+
+
+
+
+## 主题定制
+
+### 样式变量
+
+组件提供了下列 CSS 变量,可用于自定义样式)。uvue app无效。
+
+| 名称 | 默认值 | 描述 |
+| --- | --- | --- |
+| --l-date-strip-bg-color: | _$bg-color-container_ | - |
+| --l-date-strip-height: | _86px_ | - |
+| --l-date-strip-padding: | _8px 0_ | - |
+| --l-date-strip-font-size: | _16px_ | - |
+| --l-date-strip-color: | _$text-color-1_ | - |
+| --l-date-strip-prefix-color: | _$text-color-3_ | - |
+| --l-date-strip-prefix-font-size: | _14px_ | - |
+| --l-date-strip-suffix-color: | _$text-color-2_ | - |
+| --l-date-strip-suffix-font-size: | _12px_ | - |
+| --l-date-strip-active-color: | _$primary-color_ | - |
+| --l-date-strip-square-radius: | _5px_ | - |
+| --l-date-strip-grid-width: | _50px_ | - |
+| --l-date-strip-grid-square-padding: | _6px 0_ | - |
+| --l-date-strip-grid-circle-radius: | _99px_ | - |
+
+
+## 打赏
+
+如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/addUnit/index.ts b/src/uni_modules/lime-shared/addUnit/index.ts
new file mode 100644
index 0000000..78476c9
--- /dev/null
+++ b/src/uni_modules/lime-shared/addUnit/index.ts
@@ -0,0 +1,42 @@
+// @ts-nocheck
+import {isNumeric} from '../isNumeric'
+import {isDef} from '../isDef'
+/**
+ * 给一个值添加单位(像素 px)
+ * @param value 要添加单位的值,可以是字符串或数字
+ * @returns 添加了单位的值,如果值为 null 则返回 null
+ */
+
+// #ifndef UNI-APP-X && APP
+export function addUnit(value?: string | number): string | null {
+ if (!isDef(value)) {
+ return null;
+ }
+ value = String(value); // 将值转换为字符串
+ // 如果值是数字,则在后面添加单位 "px",否则保持原始值
+ return isNumeric(value) ? `${value}px` : value;
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+function addUnit(value: string): string
+function addUnit(value: number): string
+function addUnit(value: any|null): string|null {
+ if (!isDef(value)) {
+ return null;
+ }
+ value = `${value}` //value.toString(); // 将值转换为字符串
+
+ // 如果值是数字,则在后面添加单位 "px",否则保持原始值
+ return isNumeric(value) ? `${value}px` : value;
+}
+export {addUnit}
+// #endif
+
+
+// console.log(addUnit(100)); // 输出: "100px"
+// console.log(addUnit("200")); // 输出: "200px"
+// console.log(addUnit("300px")); // 输出: "300px"(已经包含单位)
+// console.log(addUnit()); // 输出: undefined(值为 undefined)
+// console.log(addUnit(null)); // 输出: undefined(值为 null)
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/animation/bezier.ts b/src/uni_modules/lime-shared/animation/bezier.ts
new file mode 100644
index 0000000..b4239e1
--- /dev/null
+++ b/src/uni_modules/lime-shared/animation/bezier.ts
@@ -0,0 +1,82 @@
+export function cubicBezier(p1x : number, p1y : number, p2x : number, p2y : number):(x: number)=> number {
+ const ZERO_LIMIT = 1e-6;
+ // Calculate the polynomial coefficients,
+ // implicit first and last control points are (0,0) and (1,1).
+ const ax = 3 * p1x - 3 * p2x + 1;
+ const bx = 3 * p2x - 6 * p1x;
+ const cx = 3 * p1x;
+
+ const ay = 3 * p1y - 3 * p2y + 1;
+ const by = 3 * p2y - 6 * p1y;
+ const cy = 3 * p1y;
+
+ function sampleCurveDerivativeX(t : number) : number {
+ // `ax t^3 + bx t^2 + cx t` expanded using Horner's rule
+ return (3 * ax * t + 2 * bx) * t + cx;
+ }
+
+ function sampleCurveX(t : number) : number {
+ return ((ax * t + bx) * t + cx) * t;
+ }
+
+ function sampleCurveY(t : number) : number {
+ return ((ay * t + by) * t + cy) * t;
+ }
+
+ // Given an x value, find a parametric value it came from.
+ function solveCurveX(x : number) : number {
+ let t2 = x;
+ let derivative : number;
+ let x2 : number;
+
+ // https://trac.webkit.org/browser/trunk/Source/WebCore/platform/animation
+ // first try a few iterations of Newton's method -- normally very fast.
+ // http://en.wikipedia.org/wikiNewton's_method
+ for (let i = 0; i < 8; i++) {
+ // f(t) - x = 0
+ x2 = sampleCurveX(t2) - x;
+ if (Math.abs(x2) < ZERO_LIMIT) {
+ return t2;
+ }
+ derivative = sampleCurveDerivativeX(t2);
+ // == 0, failure
+ /* istanbul ignore if */
+ if (Math.abs(derivative) < ZERO_LIMIT) {
+ break;
+ }
+ t2 -= x2 / derivative;
+ }
+
+ // Fall back to the bisection method for reliability.
+ // bisection
+ // http://en.wikipedia.org/wiki/Bisection_method
+ let t1 = 1;
+ /* istanbul ignore next */
+ let t0 = 0;
+
+ /* istanbul ignore next */
+ t2 = x;
+ /* istanbul ignore next */
+ while (t1 > t0) {
+ x2 = sampleCurveX(t2) - x;
+ if (Math.abs(x2) < ZERO_LIMIT) {
+ return t2;
+ }
+ if (x2 > 0) {
+ t1 = t2;
+ } else {
+ t0 = t2;
+ }
+ t2 = (t1 + t0) / 2;
+ }
+
+ // Failure
+ return t2;
+ }
+
+ return function (x : number) : number {
+ return sampleCurveY(solveCurveX(x));
+ }
+
+ // return solve;
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/animation/ease.ts b/src/uni_modules/lime-shared/animation/ease.ts
new file mode 100644
index 0000000..0af156e
--- /dev/null
+++ b/src/uni_modules/lime-shared/animation/ease.ts
@@ -0,0 +1,3 @@
+import {cubicBezier} from './bezier';
+export let ease = cubicBezier(0.25, 0.1, 0.25, 1);
+export let linear = cubicBezier(0,0,1,1);
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/animation/index.ts b/src/uni_modules/lime-shared/animation/index.ts
new file mode 100644
index 0000000..5979064
--- /dev/null
+++ b/src/uni_modules/lime-shared/animation/index.ts
@@ -0,0 +1,10 @@
+// @ts-nocheck
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
+
+
+
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
diff --git a/src/uni_modules/lime-shared/animation/useTransition.ts b/src/uni_modules/lime-shared/animation/useTransition.ts
new file mode 100644
index 0000000..0939704
--- /dev/null
+++ b/src/uni_modules/lime-shared/animation/useTransition.ts
@@ -0,0 +1,103 @@
+// @ts-nocheck
+import type { ComponentPublicInstance } from 'vue'
+import { ease, linear } from './ease';
+import { Timeline, Animation } from './';
+export type UseTransitionOptions = {
+ duration ?: number
+ immediate ?: boolean
+ context ?: ComponentPublicInstance
+}
+// #ifndef UNI-APP-X && APP
+import { ref, watch, type Ref } from '@/uni_modules/lime-shared/vue'
+
+export function useTransition(percent : Ref|(() => number), options : UseTransitionOptions) : Ref {
+ const current = ref(0)
+ const { immediate, duration = 300 } = options
+ let tl:Timeline|null = null;
+ let timer = -1
+ const isFunction = typeof percent === 'function'
+ watch(isFunction ? percent : () => percent.value, (v) => {
+ if(tl == null){
+ tl = new Timeline()
+ }
+ tl.start();
+ tl.add(
+ new Animation(
+ current.value,
+ v,
+ duration,
+ 0,
+ ease,
+ nowValue => {
+ current.value = nowValue
+ clearTimeout(timer)
+ if(current.value == v){
+ timer = setTimeout(()=>{
+ tl?.pause();
+ tl = null
+ }, duration)
+ }
+ }
+ )
+ );
+ }, { immediate })
+
+ return current
+}
+
+// #endif
+
+// #ifdef UNI-APP-X && APP
+type UseTransitionReturnType = Ref
+export function useTransition(source : any, options : UseTransitionOptions) : UseTransitionReturnType {
+ const outputRef : Ref = ref(0)
+ const immediate = options.immediate ?? false
+ const duration = options.duration ?? 300
+ const context = options.context //as ComponentPublicInstance | null
+ let tl:Timeline|null = null;
+ let timer = -1
+ const watchFunc = (v : number) => {
+ if(tl == null){
+ tl = new Timeline()
+ }
+ tl!.start();
+ tl!.add(
+ new Animation(
+ outputRef.value,
+ v,
+ duration,
+ 0,
+ ease,
+ nowValue => {
+ outputRef.value = nowValue
+ clearTimeout(timer)
+ if(outputRef.value == v){
+ timer = setTimeout(()=>{
+ tl?.pause();
+ tl = null
+ }, duration)
+ }
+ }
+ ),
+ null
+ );
+ }
+
+ if (context != null && typeof source == 'string') {
+ context.$watch(source, watchFunc, { immediate } as WatchOptions)
+ } else if(typeof source == 'function'){
+ watch(source, watchFunc, { immediate })
+ } else if(isRef(source) && typeof source.value == 'number') {
+ watch(source as Ref, watchFunc, { immediate })
+ }
+ // else if(source instanceof Ref){
+ // watch(source as Ref, watchFunc, { immediate })
+ // }
+
+ const stop = ()=>{
+
+ }
+ return outputRef //as UseTransitionReturnType
+}
+
+// #endif
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/animation/uvue.uts b/src/uni_modules/lime-shared/animation/uvue.uts
new file mode 100644
index 0000000..37e2bc9
--- /dev/null
+++ b/src/uni_modules/lime-shared/animation/uvue.uts
@@ -0,0 +1,119 @@
+import { raf, cancelRaf} from '../raf'
+// @ts-nocheck
+export class Timeline {
+ state : string
+ animations : Set = new Set()
+ delAnimations : Animation[] = []
+ startTimes : Map = new Map()
+ pauseTime : number = 0
+ pauseStart : number = Date.now()
+ tickHandler : number = 0
+ tickHandlers : number[] = []
+ tick : (() => void) | null = null
+ constructor() {
+ this.state = 'Initiated';
+ }
+ start() {
+ if (!(this.state == 'Initiated')) return;
+ this.state = 'Started';
+
+ let startTime = Date.now();
+ this.pauseTime = 0;
+ this.tick = () => {
+ let now = Date.now();
+ this.animations.forEach((animation : Animation) => {
+ let t:number;
+ const ani = this.startTimes.get(animation)
+ if (ani == null) return
+ if (ani < startTime) {
+ t = now - startTime - animation.delay - this.pauseTime;
+ } else {
+ t = now - ani - animation.delay - this.pauseTime;
+ }
+ if (t > animation.duration) {
+ this.delAnimations.push(animation)
+ // 不能在 foreach 里面 对 集合进行删除操作
+ // this.animations.delete(animation);
+ t = animation.duration;
+ }
+ if (t > 0) animation.run(t);
+ })
+ // 不能在 foreach 里面 对 集合进行删除操作
+ while (this.delAnimations.length > 0) {
+ const animation = this.delAnimations.pop();
+ if (animation == null) return
+ this.animations.delete(animation);
+ }
+ // cancelAnimationFrame(this.tickHandler);
+ if (this.state != 'Started') return
+
+ this.tickHandler = raf(()=>{
+ this.tick!()
+ })
+
+ this.tickHandlers.push(this.tickHandler)
+ }
+ if(this.tick != null) {
+ this.tick!()
+ }
+
+ }
+ pause() {
+ if (!(this.state === 'Started')) return;
+ this.state = 'Paused';
+ this.pauseStart = Date.now();
+ cancelRaf(this.tickHandler);
+ // cancelRaf(this.tickHandler);
+ }
+ resume() {
+ if (!(this.state === 'Paused')) return;
+ this.state = 'Started';
+ this.pauseTime += Date.now() - this.pauseStart;
+ this.tick!();
+ }
+ reset() {
+ this.pause();
+ this.state = 'Initiated';
+ this.pauseTime = 0;
+ this.pauseStart = 0;
+ this.animations.clear()
+ this.delAnimations.clear()
+ this.startTimes.clear()
+ this.tickHandler = 0;
+ }
+ add(animation : Animation, startTime ?: number | null) {
+ if (startTime == null) startTime = Date.now();
+ this.animations.add(animation);
+ this.startTimes.set(animation, startTime);
+ }
+}
+
+export class Animation {
+ startValue : number
+ endValue : number
+ duration : number
+ timingFunction : (t : number) => number
+ delay : number
+ template : (t : number) => void
+ constructor(
+ startValue : number,
+ endValue : number,
+ duration : number,
+ delay : number,
+ timingFunction : (t : number) => number,
+ template : (v : number) => void) {
+ this.startValue = startValue;
+ this.endValue = endValue;
+ this.duration = duration;
+ this.timingFunction = timingFunction;
+ this.delay = delay;
+ this.template = template;
+ }
+
+ run(time : number) {
+ let range = this.endValue - this.startValue;
+ let progress = time / this.duration
+ if(progress != 1) progress = this.timingFunction(progress)
+ this.template(this.startValue + range * progress)
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/animation/vue.ts b/src/uni_modules/lime-shared/animation/vue.ts
new file mode 100644
index 0000000..30f89e5
--- /dev/null
+++ b/src/uni_modules/lime-shared/animation/vue.ts
@@ -0,0 +1,123 @@
+// @ts-nocheck
+const TICK = Symbol('tick');
+const TICK_HANDLER = Symbol('tick-handler');
+const ANIMATIONS = Symbol('animations');
+const START_TIMES = Symbol('start-times');
+const PAUSE_START = Symbol('pause-start');
+const PAUSE_TIME = Symbol('pause-time');
+const _raf = typeof requestAnimationFrame !== 'undefined' ? requestAnimationFrame : function(cb: Function) {return setTimeout(cb, 1000/60)}
+const _caf = typeof cancelAnimationFrame !== 'undefined' ? cancelAnimationFrame: function(id: any) {clearTimeout(id)}
+
+// const TICK = 'tick';
+// const TICK_HANDLER = 'tick-handler';
+// const ANIMATIONS = 'animations';
+// const START_TIMES = 'start-times';
+// const PAUSE_START = 'pause-start';
+// const PAUSE_TIME = 'pause-time';
+// const _raf = function(callback):number|null {return setTimeout(callback, 1000/60)}
+// const _caf = function(id: number):void {clearTimeout(id)}
+
+export class Timeline {
+ state: string
+ constructor() {
+ this.state = 'Initiated';
+ this[ANIMATIONS] = new Set();
+ this[START_TIMES] = new Map();
+ }
+ start() {
+ if (!(this.state === 'Initiated')) return;
+ this.state = 'Started';
+
+ let startTime = Date.now();
+ this[PAUSE_TIME] = 0;
+ this[TICK] = () => {
+ let now = Date.now();
+ this[ANIMATIONS].forEach((animation) => {
+ let t: number;
+ if (this[START_TIMES].get(animation) < startTime) {
+ t = now - startTime - animation.delay - this[PAUSE_TIME];
+ } else {
+ t = now - this[START_TIMES].get(animation) - animation.delay - this[PAUSE_TIME];
+ }
+
+ if (t > animation.duration) {
+ this[ANIMATIONS].delete(animation);
+ t = animation.duration;
+ }
+ if (t > 0) animation.run(t);
+ })
+ // for (let animation of this[ANIMATIONS]) {
+ // let t: number;
+ // console.log('animation', animation)
+ // if (this[START_TIMES].get(animation) < startTime) {
+ // t = now - startTime - animation.delay - this[PAUSE_TIME];
+ // } else {
+ // t = now - this[START_TIMES].get(animation) - animation.delay - this[PAUSE_TIME];
+ // }
+
+ // if (t > animation.duration) {
+ // this[ANIMATIONS].delete(animation);
+ // t = animation.duration;
+ // }
+ // if (t > 0) animation.run(t);
+ // }
+ this[TICK_HANDLER] = _raf(this[TICK]);
+ };
+ this[TICK]();
+ }
+ pause() {
+ if (!(this.state === 'Started')) return;
+ this.state = 'Paused';
+
+ this[PAUSE_START] = Date.now();
+ _caf(this[TICK_HANDLER]);
+ }
+ resume() {
+ if (!(this.state === 'Paused')) return;
+ this.state = 'Started';
+
+ this[PAUSE_TIME] += Date.now() - this[PAUSE_START];
+ this[TICK]();
+ }
+ reset() {
+ this.pause();
+ this.state = 'Initiated';
+ this[PAUSE_TIME] = 0;
+ this[PAUSE_START] = 0;
+ this[ANIMATIONS] = new Set();
+ this[START_TIMES] = new Map();
+ this[TICK_HANDLER] = null;
+ }
+ add(animation: any, startTime?: number) {
+ if (arguments.length < 2) startTime = Date.now();
+ this[ANIMATIONS].add(animation);
+ this[START_TIMES].set(animation, startTime);
+ }
+}
+
+export class Animation {
+ startValue: number
+ endValue: number
+ duration: number
+ timingFunction: (t: number) => number
+ delay: number
+ template: (t: number) => void
+ constructor(startValue: number, endValue: number, duration: number, delay: number, timingFunction: (t: number) => number, template: (v: number) => void) {
+ timingFunction = timingFunction || (v => v);
+ template = template || (v => v);
+
+ this.startValue = startValue;
+ this.endValue = endValue;
+ this.duration = duration;
+ this.timingFunction = timingFunction;
+ this.delay = delay;
+ this.template = template;
+ }
+
+ run(time: number) {
+ let range = this.endValue - this.startValue;
+ let progress = time / this.duration
+ if(progress != 1) progress = this.timingFunction(progress)
+ this.template(this.startValue + range * progress)
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/areaData/city-china.json b/src/uni_modules/lime-shared/areaData/city-china.json
new file mode 100644
index 0000000..d9872a0
--- /dev/null
+++ b/src/uni_modules/lime-shared/areaData/city-china.json
@@ -0,0 +1,3888 @@
+{
+ "province_list": {
+ "110000": "北京市",
+ "120000": "天津市",
+ "130000": "河北省",
+ "140000": "山西省",
+ "150000": "内蒙古自治区",
+ "210000": "辽宁省",
+ "220000": "吉林省",
+ "230000": "黑龙江省",
+ "310000": "上海市",
+ "320000": "江苏省",
+ "330000": "浙江省",
+ "340000": "安徽省",
+ "350000": "福建省",
+ "360000": "江西省",
+ "370000": "山东省",
+ "410000": "河南省",
+ "420000": "湖北省",
+ "430000": "湖南省",
+ "440000": "广东省",
+ "450000": "广西壮族自治区",
+ "460000": "海南省",
+ "500000": "重庆市",
+ "510000": "四川省",
+ "520000": "贵州省",
+ "530000": "云南省",
+ "540000": "西藏自治区",
+ "610000": "陕西省",
+ "620000": "甘肃省",
+ "630000": "青海省",
+ "640000": "宁夏回族自治区",
+ "650000": "新疆维吾尔自治区",
+ "710000": "台湾省",
+ "810000": "香港特别行政区",
+ "820000": "澳门特别行政区"
+ },
+ "city_list": {
+ "110100": "北京市",
+ "120100": "天津市",
+ "130100": "石家庄市",
+ "130200": "唐山市",
+ "130300": "秦皇岛市",
+ "130400": "邯郸市",
+ "130500": "邢台市",
+ "130600": "保定市",
+ "130700": "张家口市",
+ "130800": "承德市",
+ "130900": "沧州市",
+ "131000": "廊坊市",
+ "131100": "衡水市",
+ "140100": "太原市",
+ "140200": "大同市",
+ "140300": "阳泉市",
+ "140400": "长治市",
+ "140500": "晋城市",
+ "140600": "朔州市",
+ "140700": "晋中市",
+ "140800": "运城市",
+ "140900": "忻州市",
+ "141000": "临汾市",
+ "141100": "吕梁市",
+ "150100": "呼和浩特市",
+ "150200": "包头市",
+ "150300": "乌海市",
+ "150400": "赤峰市",
+ "150500": "通辽市",
+ "150600": "鄂尔多斯市",
+ "150700": "呼伦贝尔市",
+ "150800": "巴彦淖尔市",
+ "150900": "乌兰察布市",
+ "152200": "兴安盟",
+ "152500": "锡林郭勒盟",
+ "152900": "阿拉善盟",
+ "210100": "沈阳市",
+ "210200": "大连市",
+ "210300": "鞍山市",
+ "210400": "抚顺市",
+ "210500": "本溪市",
+ "210600": "丹东市",
+ "210700": "锦州市",
+ "210800": "营口市",
+ "210900": "阜新市",
+ "211000": "辽阳市",
+ "211100": "盘锦市",
+ "211200": "铁岭市",
+ "211300": "朝阳市",
+ "211400": "葫芦岛市",
+ "220100": "长春市",
+ "220200": "吉林市",
+ "220300": "四平市",
+ "220400": "辽源市",
+ "220500": "通化市",
+ "220600": "白山市",
+ "220700": "松原市",
+ "220800": "白城市",
+ "222400": "延边朝鲜族自治州",
+ "230100": "哈尔滨市",
+ "230200": "齐齐哈尔市",
+ "230300": "鸡西市",
+ "230400": "鹤岗市",
+ "230500": "双鸭山市",
+ "230600": "大庆市",
+ "230700": "伊春市",
+ "230800": "佳木斯市",
+ "230900": "七台河市",
+ "231000": "牡丹江市",
+ "231100": "黑河市",
+ "231200": "绥化市",
+ "232700": "大兴安岭地区",
+ "310100": "上海市",
+ "320100": "南京市",
+ "320200": "无锡市",
+ "320300": "徐州市",
+ "320400": "常州市",
+ "320500": "苏州市",
+ "320600": "南通市",
+ "320700": "连云港市",
+ "320800": "淮安市",
+ "320900": "盐城市",
+ "321000": "扬州市",
+ "321100": "镇江市",
+ "321200": "泰州市",
+ "321300": "宿迁市",
+ "330100": "杭州市",
+ "330200": "宁波市",
+ "330300": "温州市",
+ "330400": "嘉兴市",
+ "330500": "湖州市",
+ "330600": "绍兴市",
+ "330700": "金华市",
+ "330800": "衢州市",
+ "330900": "舟山市",
+ "331000": "台州市",
+ "331100": "丽水市",
+ "340100": "合肥市",
+ "340200": "芜湖市",
+ "340300": "蚌埠市",
+ "340400": "淮南市",
+ "340500": "马鞍山市",
+ "340600": "淮北市",
+ "340700": "铜陵市",
+ "340800": "安庆市",
+ "341000": "黄山市",
+ "341100": "滁州市",
+ "341200": "阜阳市",
+ "341300": "宿州市",
+ "341500": "六安市",
+ "341600": "亳州市",
+ "341700": "池州市",
+ "341800": "宣城市",
+ "350100": "福州市",
+ "350200": "厦门市",
+ "350300": "莆田市",
+ "350400": "三明市",
+ "350500": "泉州市",
+ "350600": "漳州市",
+ "350700": "南平市",
+ "350800": "龙岩市",
+ "350900": "宁德市",
+ "360100": "南昌市",
+ "360200": "景德镇市",
+ "360300": "萍乡市",
+ "360400": "九江市",
+ "360500": "新余市",
+ "360600": "鹰潭市",
+ "360700": "赣州市",
+ "360800": "吉安市",
+ "360900": "宜春市",
+ "361000": "抚州市",
+ "361100": "上饶市",
+ "370100": "济南市",
+ "370200": "青岛市",
+ "370300": "淄博市",
+ "370400": "枣庄市",
+ "370500": "东营市",
+ "370600": "烟台市",
+ "370700": "潍坊市",
+ "370800": "济宁市",
+ "370900": "泰安市",
+ "371000": "威海市",
+ "371100": "日照市",
+ "371300": "临沂市",
+ "371400": "德州市",
+ "371500": "聊城市",
+ "371600": "滨州市",
+ "371700": "菏泽市",
+ "410100": "郑州市",
+ "410200": "开封市",
+ "410300": "洛阳市",
+ "410400": "平顶山市",
+ "410500": "安阳市",
+ "410600": "鹤壁市",
+ "410700": "新乡市",
+ "410800": "焦作市",
+ "410900": "濮阳市",
+ "411000": "许昌市",
+ "411100": "漯河市",
+ "411200": "三门峡市",
+ "411300": "南阳市",
+ "411400": "商丘市",
+ "411500": "信阳市",
+ "411600": "周口市",
+ "411700": "驻马店市",
+ "419000": "省直辖县",
+ "420100": "武汉市",
+ "420200": "黄石市",
+ "420300": "十堰市",
+ "420500": "宜昌市",
+ "420600": "襄阳市",
+ "420700": "鄂州市",
+ "420800": "荆门市",
+ "420900": "孝感市",
+ "421000": "荆州市",
+ "421100": "黄冈市",
+ "421200": "咸宁市",
+ "421300": "随州市",
+ "422800": "恩施土家族苗族自治州",
+ "429000": "省直辖县",
+ "430100": "长沙市",
+ "430200": "株洲市",
+ "430300": "湘潭市",
+ "430400": "衡阳市",
+ "430500": "邵阳市",
+ "430600": "岳阳市",
+ "430700": "常德市",
+ "430800": "张家界市",
+ "430900": "益阳市",
+ "431000": "郴州市",
+ "431100": "永州市",
+ "431200": "怀化市",
+ "431300": "娄底市",
+ "433100": "湘西土家族苗族自治州",
+ "440100": "广州市",
+ "440200": "韶关市",
+ "440300": "深圳市",
+ "440400": "珠海市",
+ "440500": "汕头市",
+ "440600": "佛山市",
+ "440700": "江门市",
+ "440800": "湛江市",
+ "440900": "茂名市",
+ "441200": "肇庆市",
+ "441300": "惠州市",
+ "441400": "梅州市",
+ "441500": "汕尾市",
+ "441600": "河源市",
+ "441700": "阳江市",
+ "441800": "清远市",
+ "441900": "东莞市",
+ "442000": "中山市",
+ "445100": "潮州市",
+ "445200": "揭阳市",
+ "445300": "云浮市",
+ "450100": "南宁市",
+ "450200": "柳州市",
+ "450300": "桂林市",
+ "450400": "梧州市",
+ "450500": "北海市",
+ "450600": "防城港市",
+ "450700": "钦州市",
+ "450800": "贵港市",
+ "450900": "玉林市",
+ "451000": "百色市",
+ "451100": "贺州市",
+ "451200": "河池市",
+ "451300": "来宾市",
+ "451400": "崇左市",
+ "460100": "海口市",
+ "460200": "三亚市",
+ "460300": "三沙市",
+ "460400": "儋州市",
+ "469000": "省直辖县",
+ "500100": "重庆市",
+ "500200": "县",
+ "510100": "成都市",
+ "510300": "自贡市",
+ "510400": "攀枝花市",
+ "510500": "泸州市",
+ "510600": "德阳市",
+ "510700": "绵阳市",
+ "510800": "广元市",
+ "510900": "遂宁市",
+ "511000": "内江市",
+ "511100": "乐山市",
+ "511300": "南充市",
+ "511400": "眉山市",
+ "511500": "宜宾市",
+ "511600": "广安市",
+ "511700": "达州市",
+ "511800": "雅安市",
+ "511900": "巴中市",
+ "512000": "资阳市",
+ "513200": "阿坝藏族羌族自治州",
+ "513300": "甘孜藏族自治州",
+ "513400": "凉山彝族自治州",
+ "520100": "贵阳市",
+ "520200": "六盘水市",
+ "520300": "遵义市",
+ "520400": "安顺市",
+ "520500": "毕节市",
+ "520600": "铜仁市",
+ "522300": "黔西南布依族苗族自治州",
+ "522600": "黔东南苗族侗族自治州",
+ "522700": "黔南布依族苗族自治州",
+ "530100": "昆明市",
+ "530300": "曲靖市",
+ "530400": "玉溪市",
+ "530500": "保山市",
+ "530600": "昭通市",
+ "530700": "丽江市",
+ "530800": "普洱市",
+ "530900": "临沧市",
+ "532300": "楚雄彝族自治州",
+ "532500": "红河哈尼族彝族自治州",
+ "532600": "文山壮族苗族自治州",
+ "532800": "西双版纳傣族自治州",
+ "532900": "大理白族自治州",
+ "533100": "德宏傣族景颇族自治州",
+ "533300": "怒江傈僳族自治州",
+ "533400": "迪庆藏族自治州",
+ "540100": "拉萨市",
+ "540200": "日喀则市",
+ "540300": "昌都市",
+ "540400": "林芝市",
+ "540500": "山南市",
+ "540600": "那曲市",
+ "542500": "阿里地区",
+ "610100": "西安市",
+ "610200": "铜川市",
+ "610300": "宝鸡市",
+ "610400": "咸阳市",
+ "610500": "渭南市",
+ "610600": "延安市",
+ "610700": "汉中市",
+ "610800": "榆林市",
+ "610900": "安康市",
+ "611000": "商洛市",
+ "620100": "兰州市",
+ "620200": "嘉峪关市",
+ "620300": "金昌市",
+ "620400": "白银市",
+ "620500": "天水市",
+ "620600": "武威市",
+ "620700": "张掖市",
+ "620800": "平凉市",
+ "620900": "酒泉市",
+ "621000": "庆阳市",
+ "621100": "定西市",
+ "621200": "陇南市",
+ "622900": "临夏回族自治州",
+ "623000": "甘南藏族自治州",
+ "630100": "西宁市",
+ "630200": "海东市",
+ "632200": "海北藏族自治州",
+ "632300": "黄南藏族自治州",
+ "632500": "海南藏族自治州",
+ "632600": "果洛藏族自治州",
+ "632700": "玉树藏族自治州",
+ "632800": "海西蒙古族藏族自治州",
+ "640100": "银川市",
+ "640200": "石嘴山市",
+ "640300": "吴忠市",
+ "640400": "固原市",
+ "640500": "中卫市",
+ "650100": "乌鲁木齐市",
+ "650200": "克拉玛依市",
+ "650400": "吐鲁番市",
+ "650500": "哈密市",
+ "652300": "昌吉回族自治州",
+ "652700": "博尔塔拉蒙古自治州",
+ "652800": "巴音郭楞蒙古自治州",
+ "652900": "阿克苏地区",
+ "653000": "克孜勒苏柯尔克孜自治州",
+ "653100": "喀什地区",
+ "653200": "和田地区",
+ "654000": "伊犁哈萨克自治州",
+ "654200": "塔城地区",
+ "654300": "阿勒泰地区",
+ "659000": "自治区直辖县级行政区划",
+ "710100": "台北市",
+ "710200": "高雄市",
+ "710300": "台南市",
+ "710400": "台中市",
+ "710500": "金门县",
+ "710600": "南投县",
+ "710700": "基隆市",
+ "710800": "新竹市",
+ "710900": "嘉义市",
+ "711100": "新北市",
+ "711200": "宜兰县",
+ "711300": "新竹县",
+ "711400": "桃园市",
+ "711500": "苗栗县",
+ "711700": "彰化县",
+ "711900": "嘉义县",
+ "712100": "云林县",
+ "712400": "屏东县",
+ "712500": "台东县",
+ "712600": "花莲县",
+ "712700": "澎湖县",
+ "712800": "连江县",
+ "810100": "香港岛",
+ "810200": "九龙",
+ "810300": "新界",
+ "820100": "澳门半岛",
+ "820200": "离岛"
+ },
+ "county_list": {
+ "110101": "东城区",
+ "110102": "西城区",
+ "110105": "朝阳区",
+ "110106": "丰台区",
+ "110107": "石景山区",
+ "110108": "海淀区",
+ "110109": "门头沟区",
+ "110111": "房山区",
+ "110112": "通州区",
+ "110113": "顺义区",
+ "110114": "昌平区",
+ "110115": "大兴区",
+ "110116": "怀柔区",
+ "110117": "平谷区",
+ "110118": "密云区",
+ "110119": "延庆区",
+ "120101": "和平区",
+ "120102": "河东区",
+ "120103": "河西区",
+ "120104": "南开区",
+ "120105": "河北区",
+ "120106": "红桥区",
+ "120110": "东丽区",
+ "120111": "西青区",
+ "120112": "津南区",
+ "120113": "北辰区",
+ "120114": "武清区",
+ "120115": "宝坻区",
+ "120116": "滨海新区",
+ "120117": "宁河区",
+ "120118": "静海区",
+ "120119": "蓟州区",
+ "130102": "长安区",
+ "130104": "桥西区",
+ "130105": "新华区",
+ "130107": "井陉矿区",
+ "130108": "裕华区",
+ "130109": "藁城区",
+ "130110": "鹿泉区",
+ "130111": "栾城区",
+ "130121": "井陉县",
+ "130123": "正定县",
+ "130125": "行唐县",
+ "130126": "灵寿县",
+ "130127": "高邑县",
+ "130128": "深泽县",
+ "130129": "赞皇县",
+ "130130": "无极县",
+ "130131": "平山县",
+ "130132": "元氏县",
+ "130133": "赵县",
+ "130171": "石家庄高新技术产业开发区",
+ "130172": "石家庄循环化工园区",
+ "130181": "辛集市",
+ "130183": "晋州市",
+ "130184": "新乐市",
+ "130202": "路南区",
+ "130203": "路北区",
+ "130204": "古冶区",
+ "130205": "开平区",
+ "130207": "丰南区",
+ "130208": "丰润区",
+ "130209": "曹妃甸区",
+ "130224": "滦南县",
+ "130225": "乐亭县",
+ "130227": "迁西县",
+ "130229": "玉田县",
+ "130273": "唐山高新技术产业开发区",
+ "130274": "河北唐山海港经济开发区",
+ "130281": "遵化市",
+ "130283": "迁安市",
+ "130284": "滦州市",
+ "130302": "海港区",
+ "130303": "山海关区",
+ "130304": "北戴河区",
+ "130306": "抚宁区",
+ "130321": "青龙满族自治县",
+ "130322": "昌黎县",
+ "130324": "卢龙县",
+ "130371": "秦皇岛市经济技术开发区",
+ "130372": "北戴河新区",
+ "130390": "经济技术开发区",
+ "130402": "邯山区",
+ "130403": "丛台区",
+ "130404": "复兴区",
+ "130406": "峰峰矿区",
+ "130407": "肥乡区",
+ "130408": "永年区",
+ "130423": "临漳县",
+ "130424": "成安县",
+ "130425": "大名县",
+ "130426": "涉县",
+ "130427": "磁县",
+ "130430": "邱县",
+ "130431": "鸡泽县",
+ "130432": "广平县",
+ "130433": "馆陶县",
+ "130434": "魏县",
+ "130435": "曲周县",
+ "130471": "邯郸经济技术开发区",
+ "130473": "邯郸冀南新区",
+ "130481": "武安市",
+ "130502": "襄都区",
+ "130503": "信都区",
+ "130505": "任泽区",
+ "130506": "南和区",
+ "130522": "临城县",
+ "130523": "内丘县",
+ "130524": "柏乡县",
+ "130525": "隆尧县",
+ "130528": "宁晋县",
+ "130529": "巨鹿县",
+ "130530": "新河县",
+ "130531": "广宗县",
+ "130532": "平乡县",
+ "130533": "威县",
+ "130534": "清河县",
+ "130535": "临西县",
+ "130571": "河北邢台经济开发区",
+ "130581": "南宫市",
+ "130582": "沙河市",
+ "130602": "竞秀区",
+ "130606": "莲池区",
+ "130607": "满城区",
+ "130608": "清苑区",
+ "130609": "徐水区",
+ "130623": "涞水县",
+ "130624": "阜平县",
+ "130626": "定兴县",
+ "130627": "唐县",
+ "130628": "高阳县",
+ "130629": "容城县",
+ "130630": "涞源县",
+ "130631": "望都县",
+ "130632": "安新县",
+ "130633": "易县",
+ "130634": "曲阳县",
+ "130635": "蠡县",
+ "130636": "顺平县",
+ "130637": "博野县",
+ "130638": "雄县",
+ "130671": "保定高新技术产业开发区",
+ "130672": "保定白沟新城",
+ "130681": "涿州市",
+ "130682": "定州市",
+ "130683": "安国市",
+ "130684": "高碑店市",
+ "130702": "桥东区",
+ "130703": "桥西区",
+ "130705": "宣化区",
+ "130706": "下花园区",
+ "130708": "万全区",
+ "130709": "崇礼区",
+ "130722": "张北县",
+ "130723": "康保县",
+ "130724": "沽源县",
+ "130725": "尚义县",
+ "130726": "蔚县",
+ "130727": "阳原县",
+ "130728": "怀安县",
+ "130730": "怀来县",
+ "130731": "涿鹿县",
+ "130732": "赤城县",
+ "130772": "张家口市察北管理区",
+ "130802": "双桥区",
+ "130803": "双滦区",
+ "130804": "鹰手营子矿区",
+ "130821": "承德县",
+ "130822": "兴隆县",
+ "130824": "滦平县",
+ "130825": "隆化县",
+ "130826": "丰宁满族自治县",
+ "130827": "宽城满族自治县",
+ "130828": "围场满族蒙古族自治县",
+ "130871": "承德高新技术产业开发区",
+ "130881": "平泉市",
+ "130902": "新华区",
+ "130903": "运河区",
+ "130921": "沧县",
+ "130922": "青县",
+ "130923": "东光县",
+ "130924": "海兴县",
+ "130925": "盐山县",
+ "130926": "肃宁县",
+ "130927": "南皮县",
+ "130928": "吴桥县",
+ "130929": "献县",
+ "130930": "孟村回族自治县",
+ "130971": "河北沧州经济开发区",
+ "130972": "沧州高新技术产业开发区",
+ "130973": "沧州渤海新区",
+ "130981": "泊头市",
+ "130982": "任丘市",
+ "130983": "黄骅市",
+ "130984": "河间市",
+ "131002": "安次区",
+ "131003": "广阳区",
+ "131022": "固安县",
+ "131023": "永清县",
+ "131024": "香河县",
+ "131025": "大城县",
+ "131026": "文安县",
+ "131028": "大厂回族自治县",
+ "131071": "廊坊经济技术开发区",
+ "131081": "霸州市",
+ "131082": "三河市",
+ "131090": "开发区",
+ "131102": "桃城区",
+ "131103": "冀州区",
+ "131121": "枣强县",
+ "131122": "武邑县",
+ "131123": "武强县",
+ "131124": "饶阳县",
+ "131125": "安平县",
+ "131126": "故城县",
+ "131127": "景县",
+ "131128": "阜城县",
+ "131171": "河北衡水经济开发区",
+ "131172": "衡水滨湖新区",
+ "131182": "深州市",
+ "140105": "小店区",
+ "140106": "迎泽区",
+ "140107": "杏花岭区",
+ "140108": "尖草坪区",
+ "140109": "万柏林区",
+ "140110": "晋源区",
+ "140121": "清徐县",
+ "140122": "阳曲县",
+ "140123": "娄烦县",
+ "140181": "古交市",
+ "140212": "新荣区",
+ "140213": "平城区",
+ "140214": "云冈区",
+ "140215": "云州区",
+ "140221": "阳高县",
+ "140222": "天镇县",
+ "140223": "广灵县",
+ "140224": "灵丘县",
+ "140225": "浑源县",
+ "140226": "左云县",
+ "140271": "山西大同经济开发区",
+ "140302": "城区",
+ "140303": "矿区",
+ "140311": "郊区",
+ "140321": "平定县",
+ "140322": "盂县",
+ "140403": "潞州区",
+ "140404": "上党区",
+ "140405": "屯留区",
+ "140406": "潞城区",
+ "140423": "襄垣县",
+ "140425": "平顺县",
+ "140426": "黎城县",
+ "140427": "壶关县",
+ "140428": "长子县",
+ "140429": "武乡县",
+ "140430": "沁县",
+ "140431": "沁源县",
+ "140471": "山西长治高新技术产业园区",
+ "140502": "城区",
+ "140521": "沁水县",
+ "140522": "阳城县",
+ "140524": "陵川县",
+ "140525": "泽州县",
+ "140581": "高平市",
+ "140602": "朔城区",
+ "140603": "平鲁区",
+ "140621": "山阴县",
+ "140622": "应县",
+ "140623": "右玉县",
+ "140671": "山西朔州经济开发区",
+ "140681": "怀仁市",
+ "140702": "榆次区",
+ "140703": "太谷区",
+ "140721": "榆社县",
+ "140722": "左权县",
+ "140723": "和顺县",
+ "140724": "昔阳县",
+ "140725": "寿阳县",
+ "140727": "祁县",
+ "140728": "平遥县",
+ "140729": "灵石县",
+ "140781": "介休市",
+ "140802": "盐湖区",
+ "140821": "临猗县",
+ "140822": "万荣县",
+ "140823": "闻喜县",
+ "140824": "稷山县",
+ "140825": "新绛县",
+ "140826": "绛县",
+ "140827": "垣曲县",
+ "140828": "夏县",
+ "140829": "平陆县",
+ "140830": "芮城县",
+ "140881": "永济市",
+ "140882": "河津市",
+ "140902": "忻府区",
+ "140921": "定襄县",
+ "140922": "五台县",
+ "140923": "代县",
+ "140924": "繁峙县",
+ "140925": "宁武县",
+ "140926": "静乐县",
+ "140927": "神池县",
+ "140928": "五寨县",
+ "140929": "岢岚县",
+ "140930": "河曲县",
+ "140931": "保德县",
+ "140932": "偏关县",
+ "140971": "五台山风景名胜区",
+ "140981": "原平市",
+ "141002": "尧都区",
+ "141021": "曲沃县",
+ "141022": "翼城县",
+ "141023": "襄汾县",
+ "141024": "洪洞县",
+ "141025": "古县",
+ "141026": "安泽县",
+ "141027": "浮山县",
+ "141028": "吉县",
+ "141029": "乡宁县",
+ "141030": "大宁县",
+ "141031": "隰县",
+ "141032": "永和县",
+ "141033": "蒲县",
+ "141034": "汾西县",
+ "141081": "侯马市",
+ "141082": "霍州市",
+ "141102": "离石区",
+ "141121": "文水县",
+ "141122": "交城县",
+ "141123": "兴县",
+ "141124": "临县",
+ "141125": "柳林县",
+ "141126": "石楼县",
+ "141127": "岚县",
+ "141128": "方山县",
+ "141129": "中阳县",
+ "141130": "交口县",
+ "141181": "孝义市",
+ "141182": "汾阳市",
+ "150102": "新城区",
+ "150103": "回民区",
+ "150104": "玉泉区",
+ "150105": "赛罕区",
+ "150121": "土默特左旗",
+ "150122": "托克托县",
+ "150123": "和林格尔县",
+ "150124": "清水河县",
+ "150125": "武川县",
+ "150172": "呼和浩特经济技术开发区",
+ "150202": "东河区",
+ "150203": "昆都仑区",
+ "150204": "青山区",
+ "150205": "石拐区",
+ "150206": "白云鄂博矿区",
+ "150207": "九原区",
+ "150221": "土默特右旗",
+ "150222": "固阳县",
+ "150223": "达尔罕茂明安联合旗",
+ "150271": "包头稀土高新技术产业开发区",
+ "150302": "海勃湾区",
+ "150303": "海南区",
+ "150304": "乌达区",
+ "150402": "红山区",
+ "150403": "元宝山区",
+ "150404": "松山区",
+ "150421": "阿鲁科尔沁旗",
+ "150422": "巴林左旗",
+ "150423": "巴林右旗",
+ "150424": "林西县",
+ "150425": "克什克腾旗",
+ "150426": "翁牛特旗",
+ "150428": "喀喇沁旗",
+ "150429": "宁城县",
+ "150430": "敖汉旗",
+ "150502": "科尔沁区",
+ "150521": "科尔沁左翼中旗",
+ "150522": "科尔沁左翼后旗",
+ "150523": "开鲁县",
+ "150524": "库伦旗",
+ "150525": "奈曼旗",
+ "150526": "扎鲁特旗",
+ "150571": "通辽经济技术开发区",
+ "150581": "霍林郭勒市",
+ "150602": "东胜区",
+ "150603": "康巴什区",
+ "150621": "达拉特旗",
+ "150622": "准格尔旗",
+ "150623": "鄂托克前旗",
+ "150624": "鄂托克旗",
+ "150625": "杭锦旗",
+ "150626": "乌审旗",
+ "150627": "伊金霍洛旗",
+ "150702": "海拉尔区",
+ "150703": "扎赉诺尔区",
+ "150721": "阿荣旗",
+ "150722": "莫力达瓦达斡尔族自治旗",
+ "150723": "鄂伦春自治旗",
+ "150724": "鄂温克族自治旗",
+ "150725": "陈巴尔虎旗",
+ "150726": "新巴尔虎左旗",
+ "150727": "新巴尔虎右旗",
+ "150781": "满洲里市",
+ "150782": "牙克石市",
+ "150783": "扎兰屯市",
+ "150784": "额尔古纳市",
+ "150785": "根河市",
+ "150802": "临河区",
+ "150821": "五原县",
+ "150822": "磴口县",
+ "150823": "乌拉特前旗",
+ "150824": "乌拉特中旗",
+ "150825": "乌拉特后旗",
+ "150826": "杭锦后旗",
+ "150902": "集宁区",
+ "150921": "卓资县",
+ "150922": "化德县",
+ "150923": "商都县",
+ "150924": "兴和县",
+ "150925": "凉城县",
+ "150926": "察哈尔右翼前旗",
+ "150927": "察哈尔右翼中旗",
+ "150928": "察哈尔右翼后旗",
+ "150929": "四子王旗",
+ "150981": "丰镇市",
+ "152201": "乌兰浩特市",
+ "152202": "阿尔山市",
+ "152221": "科尔沁右翼前旗",
+ "152222": "科尔沁右翼中旗",
+ "152223": "扎赉特旗",
+ "152224": "突泉县",
+ "152501": "二连浩特市",
+ "152502": "锡林浩特市",
+ "152522": "阿巴嘎旗",
+ "152523": "苏尼特左旗",
+ "152524": "苏尼特右旗",
+ "152525": "东乌珠穆沁旗",
+ "152526": "西乌珠穆沁旗",
+ "152527": "太仆寺旗",
+ "152528": "镶黄旗",
+ "152529": "正镶白旗",
+ "152530": "正蓝旗",
+ "152531": "多伦县",
+ "152571": "乌拉盖管委会",
+ "152921": "阿拉善左旗",
+ "152922": "阿拉善右旗",
+ "152923": "额济纳旗",
+ "152971": "内蒙古阿拉善经济开发区",
+ "210102": "和平区",
+ "210103": "沈河区",
+ "210104": "大东区",
+ "210105": "皇姑区",
+ "210106": "铁西区",
+ "210111": "苏家屯区",
+ "210112": "浑南区",
+ "210113": "沈北新区",
+ "210114": "于洪区",
+ "210115": "辽中区",
+ "210123": "康平县",
+ "210124": "法库县",
+ "210181": "新民市",
+ "210190": "经济技术开发区",
+ "210202": "中山区",
+ "210203": "西岗区",
+ "210204": "沙河口区",
+ "210211": "甘井子区",
+ "210212": "旅顺口区",
+ "210213": "金州区",
+ "210214": "普兰店区",
+ "210224": "长海县",
+ "210281": "瓦房店市",
+ "210283": "庄河市",
+ "210302": "铁东区",
+ "210303": "铁西区",
+ "210304": "立山区",
+ "210311": "千山区",
+ "210321": "台安县",
+ "210323": "岫岩满族自治县",
+ "210381": "海城市",
+ "210390": "高新区",
+ "210402": "新抚区",
+ "210403": "东洲区",
+ "210404": "望花区",
+ "210411": "顺城区",
+ "210421": "抚顺县",
+ "210422": "新宾满族自治县",
+ "210423": "清原满族自治县",
+ "210502": "平山区",
+ "210503": "溪湖区",
+ "210504": "明山区",
+ "210505": "南芬区",
+ "210521": "本溪满族自治县",
+ "210522": "桓仁满族自治县",
+ "210602": "元宝区",
+ "210603": "振兴区",
+ "210604": "振安区",
+ "210624": "宽甸满族自治县",
+ "210681": "东港市",
+ "210682": "凤城市",
+ "210702": "古塔区",
+ "210703": "凌河区",
+ "210711": "太和区",
+ "210726": "黑山县",
+ "210727": "义县",
+ "210781": "凌海市",
+ "210782": "北镇市",
+ "210793": "经济技术开发区",
+ "210802": "站前区",
+ "210803": "西市区",
+ "210804": "鲅鱼圈区",
+ "210811": "老边区",
+ "210881": "盖州市",
+ "210882": "大石桥市",
+ "210902": "海州区",
+ "210903": "新邱区",
+ "210904": "太平区",
+ "210905": "清河门区",
+ "210911": "细河区",
+ "210921": "阜新蒙古族自治县",
+ "210922": "彰武县",
+ "211002": "白塔区",
+ "211003": "文圣区",
+ "211004": "宏伟区",
+ "211005": "弓长岭区",
+ "211011": "太子河区",
+ "211021": "辽阳县",
+ "211081": "灯塔市",
+ "211102": "双台子区",
+ "211103": "兴隆台区",
+ "211104": "大洼区",
+ "211122": "盘山县",
+ "211202": "银州区",
+ "211204": "清河区",
+ "211221": "铁岭县",
+ "211223": "西丰县",
+ "211224": "昌图县",
+ "211281": "调兵山市",
+ "211282": "开原市",
+ "211302": "双塔区",
+ "211303": "龙城区",
+ "211321": "朝阳县",
+ "211322": "建平县",
+ "211324": "喀喇沁左翼蒙古族自治县",
+ "211381": "北票市",
+ "211382": "凌源市",
+ "211402": "连山区",
+ "211403": "龙港区",
+ "211404": "南票区",
+ "211421": "绥中县",
+ "211422": "建昌县",
+ "211481": "兴城市",
+ "220102": "南关区",
+ "220103": "宽城区",
+ "220104": "朝阳区",
+ "220105": "二道区",
+ "220106": "绿园区",
+ "220112": "双阳区",
+ "220113": "九台区",
+ "220122": "农安县",
+ "220171": "长春经济技术开发区",
+ "220172": "长春净月高新技术产业开发区",
+ "220173": "长春高新技术产业开发区",
+ "220174": "长春汽车经济技术开发区",
+ "220182": "榆树市",
+ "220183": "德惠市",
+ "220184": "公主岭市",
+ "220192": "经济技术开发区",
+ "220202": "昌邑区",
+ "220203": "龙潭区",
+ "220204": "船营区",
+ "220211": "丰满区",
+ "220221": "永吉县",
+ "220271": "吉林经济开发区",
+ "220272": "吉林高新技术产业开发区",
+ "220281": "蛟河市",
+ "220282": "桦甸市",
+ "220283": "舒兰市",
+ "220284": "磐石市",
+ "220302": "铁西区",
+ "220303": "铁东区",
+ "220322": "梨树县",
+ "220323": "伊通满族自治县",
+ "220382": "双辽市",
+ "220402": "龙山区",
+ "220403": "西安区",
+ "220421": "东丰县",
+ "220422": "东辽县",
+ "220502": "东昌区",
+ "220503": "二道江区",
+ "220521": "通化县",
+ "220523": "辉南县",
+ "220524": "柳河县",
+ "220581": "梅河口市",
+ "220582": "集安市",
+ "220602": "浑江区",
+ "220605": "江源区",
+ "220621": "抚松县",
+ "220622": "靖宇县",
+ "220623": "长白朝鲜族自治县",
+ "220681": "临江市",
+ "220702": "宁江区",
+ "220721": "前郭尔罗斯蒙古族自治县",
+ "220722": "长岭县",
+ "220723": "乾安县",
+ "220771": "吉林松原经济开发区",
+ "220781": "扶余市",
+ "220802": "洮北区",
+ "220821": "镇赉县",
+ "220822": "通榆县",
+ "220871": "吉林白城经济开发区",
+ "220881": "洮南市",
+ "220882": "大安市",
+ "222401": "延吉市",
+ "222402": "图们市",
+ "222403": "敦化市",
+ "222404": "珲春市",
+ "222405": "龙井市",
+ "222406": "和龙市",
+ "222424": "汪清县",
+ "222426": "安图县",
+ "230102": "道里区",
+ "230103": "南岗区",
+ "230104": "道外区",
+ "230108": "平房区",
+ "230109": "松北区",
+ "230110": "香坊区",
+ "230111": "呼兰区",
+ "230112": "阿城区",
+ "230113": "双城区",
+ "230123": "依兰县",
+ "230124": "方正县",
+ "230125": "宾县",
+ "230126": "巴彦县",
+ "230127": "木兰县",
+ "230128": "通河县",
+ "230129": "延寿县",
+ "230183": "尚志市",
+ "230184": "五常市",
+ "230202": "龙沙区",
+ "230203": "建华区",
+ "230204": "铁锋区",
+ "230205": "昂昂溪区",
+ "230206": "富拉尔基区",
+ "230207": "碾子山区",
+ "230208": "梅里斯达斡尔族区",
+ "230221": "龙江县",
+ "230223": "依安县",
+ "230224": "泰来县",
+ "230225": "甘南县",
+ "230227": "富裕县",
+ "230229": "克山县",
+ "230230": "克东县",
+ "230231": "拜泉县",
+ "230281": "讷河市",
+ "230302": "鸡冠区",
+ "230303": "恒山区",
+ "230304": "滴道区",
+ "230305": "梨树区",
+ "230306": "城子河区",
+ "230307": "麻山区",
+ "230321": "鸡东县",
+ "230381": "虎林市",
+ "230382": "密山市",
+ "230402": "向阳区",
+ "230403": "工农区",
+ "230404": "南山区",
+ "230405": "兴安区",
+ "230406": "东山区",
+ "230407": "兴山区",
+ "230421": "萝北县",
+ "230422": "绥滨县",
+ "230502": "尖山区",
+ "230503": "岭东区",
+ "230505": "四方台区",
+ "230506": "宝山区",
+ "230521": "集贤县",
+ "230522": "友谊县",
+ "230523": "宝清县",
+ "230524": "饶河县",
+ "230602": "萨尔图区",
+ "230603": "龙凤区",
+ "230604": "让胡路区",
+ "230605": "红岗区",
+ "230606": "大同区",
+ "230621": "肇州县",
+ "230622": "肇源县",
+ "230623": "林甸县",
+ "230624": "杜尔伯特蒙古族自治县",
+ "230671": "大庆高新技术产业开发区",
+ "230717": "伊美区",
+ "230718": "乌翠区",
+ "230719": "友好区",
+ "230722": "嘉荫县",
+ "230723": "汤旺县",
+ "230724": "丰林县",
+ "230725": "大箐山县",
+ "230726": "南岔县",
+ "230751": "金林区",
+ "230781": "铁力市",
+ "230803": "向阳区",
+ "230804": "前进区",
+ "230805": "东风区",
+ "230811": "郊区",
+ "230822": "桦南县",
+ "230826": "桦川县",
+ "230828": "汤原县",
+ "230881": "同江市",
+ "230882": "富锦市",
+ "230883": "抚远市",
+ "230902": "新兴区",
+ "230903": "桃山区",
+ "230904": "茄子河区",
+ "230921": "勃利县",
+ "231002": "东安区",
+ "231003": "阳明区",
+ "231004": "爱民区",
+ "231005": "西安区",
+ "231025": "林口县",
+ "231081": "绥芬河市",
+ "231083": "海林市",
+ "231084": "宁安市",
+ "231085": "穆棱市",
+ "231086": "东宁市",
+ "231102": "爱辉区",
+ "231123": "逊克县",
+ "231124": "孙吴县",
+ "231181": "北安市",
+ "231182": "五大连池市",
+ "231183": "嫩江市",
+ "231202": "北林区",
+ "231221": "望奎县",
+ "231222": "兰西县",
+ "231223": "青冈县",
+ "231224": "庆安县",
+ "231225": "明水县",
+ "231226": "绥棱县",
+ "231281": "安达市",
+ "231282": "肇东市",
+ "231283": "海伦市",
+ "232701": "漠河市",
+ "232721": "呼玛县",
+ "232722": "塔河县",
+ "232761": "加格达奇区",
+ "232762": "松岭区",
+ "232763": "新林区",
+ "232764": "呼中区",
+ "310101": "黄浦区",
+ "310104": "徐汇区",
+ "310105": "长宁区",
+ "310106": "静安区",
+ "310107": "普陀区",
+ "310109": "虹口区",
+ "310110": "杨浦区",
+ "310112": "闵行区",
+ "310113": "宝山区",
+ "310114": "嘉定区",
+ "310115": "浦东新区",
+ "310116": "金山区",
+ "310117": "松江区",
+ "310118": "青浦区",
+ "310120": "奉贤区",
+ "310151": "崇明区",
+ "320102": "玄武区",
+ "320104": "秦淮区",
+ "320105": "建邺区",
+ "320106": "鼓楼区",
+ "320111": "浦口区",
+ "320112": "江北新区",
+ "320113": "栖霞区",
+ "320114": "雨花台区",
+ "320115": "江宁区",
+ "320116": "六合区",
+ "320117": "溧水区",
+ "320118": "高淳区",
+ "320205": "锡山区",
+ "320206": "惠山区",
+ "320211": "滨湖区",
+ "320213": "梁溪区",
+ "320214": "新吴区",
+ "320281": "江阴市",
+ "320282": "宜兴市",
+ "320302": "鼓楼区",
+ "320303": "云龙区",
+ "320305": "贾汪区",
+ "320311": "泉山区",
+ "320312": "铜山区",
+ "320321": "丰县",
+ "320322": "沛县",
+ "320324": "睢宁县",
+ "320371": "徐州经济技术开发区",
+ "320381": "新沂市",
+ "320382": "邳州市",
+ "320391": "工业园区",
+ "320402": "天宁区",
+ "320404": "钟楼区",
+ "320411": "新北区",
+ "320412": "武进区",
+ "320413": "金坛区",
+ "320481": "溧阳市",
+ "320505": "虎丘区",
+ "320506": "吴中区",
+ "320507": "相城区",
+ "320508": "姑苏区",
+ "320509": "吴江区",
+ "320571": "苏州工业园区",
+ "320581": "常熟市",
+ "320582": "张家港市",
+ "320583": "昆山市",
+ "320585": "太仓市",
+ "320590": "工业园区",
+ "320591": "高新区",
+ "320611": "港闸区",
+ "320612": "通州区",
+ "320613": "崇川区",
+ "320614": "海门区",
+ "320623": "如东县",
+ "320681": "启东市",
+ "320682": "如皋市",
+ "320685": "海安市",
+ "320691": "高新区",
+ "320703": "连云区",
+ "320706": "海州区",
+ "320707": "赣榆区",
+ "320722": "东海县",
+ "320723": "灌云县",
+ "320724": "灌南县",
+ "320771": "连云港经济技术开发区",
+ "320803": "淮安区",
+ "320804": "淮阴区",
+ "320812": "清江浦区",
+ "320813": "洪泽区",
+ "320826": "涟水县",
+ "320830": "盱眙县",
+ "320831": "金湖县",
+ "320871": "淮安经济技术开发区",
+ "320890": "经济开发区",
+ "320902": "亭湖区",
+ "320903": "盐都区",
+ "320904": "大丰区",
+ "320921": "响水县",
+ "320922": "滨海县",
+ "320923": "阜宁县",
+ "320924": "射阳县",
+ "320925": "建湖县",
+ "320971": "盐城经济技术开发区",
+ "320981": "东台市",
+ "321002": "广陵区",
+ "321003": "邗江区",
+ "321012": "江都区",
+ "321023": "宝应县",
+ "321071": "扬州经济技术开发区",
+ "321081": "仪征市",
+ "321084": "高邮市",
+ "321090": "经济开发区",
+ "321102": "京口区",
+ "321111": "润州区",
+ "321112": "丹徒区",
+ "321150": "镇江新区",
+ "321181": "丹阳市",
+ "321182": "扬中市",
+ "321183": "句容市",
+ "321202": "海陵区",
+ "321203": "高港区",
+ "321204": "姜堰区",
+ "321271": "泰州医药高新技术产业开发区",
+ "321281": "兴化市",
+ "321282": "靖江市",
+ "321283": "泰兴市",
+ "321302": "宿城区",
+ "321311": "宿豫区",
+ "321322": "沭阳县",
+ "321323": "泗阳县",
+ "321324": "泗洪县",
+ "321371": "宿迁经济技术开发区",
+ "330102": "上城区",
+ "330105": "拱墅区",
+ "330106": "西湖区",
+ "330108": "滨江区",
+ "330109": "萧山区",
+ "330110": "余杭区",
+ "330111": "富阳区",
+ "330112": "临安区",
+ "330113": "临平区",
+ "330114": "钱塘区",
+ "330122": "桐庐县",
+ "330127": "淳安县",
+ "330182": "建德市",
+ "330203": "海曙区",
+ "330205": "江北区",
+ "330206": "北仑区",
+ "330211": "镇海区",
+ "330212": "鄞州区",
+ "330213": "奉化区",
+ "330225": "象山县",
+ "330226": "宁海县",
+ "330281": "余姚市",
+ "330282": "慈溪市",
+ "330302": "鹿城区",
+ "330303": "龙湾区",
+ "330304": "瓯海区",
+ "330305": "洞头区",
+ "330324": "永嘉县",
+ "330326": "平阳县",
+ "330327": "苍南县",
+ "330328": "文成县",
+ "330329": "泰顺县",
+ "330381": "瑞安市",
+ "330382": "乐清市",
+ "330383": "龙港市",
+ "330402": "南湖区",
+ "330411": "秀洲区",
+ "330421": "嘉善县",
+ "330424": "海盐县",
+ "330481": "海宁市",
+ "330482": "平湖市",
+ "330483": "桐乡市",
+ "330502": "吴兴区",
+ "330503": "南浔区",
+ "330521": "德清县",
+ "330522": "长兴县",
+ "330523": "安吉县",
+ "330602": "越城区",
+ "330603": "柯桥区",
+ "330604": "上虞区",
+ "330624": "新昌县",
+ "330681": "诸暨市",
+ "330683": "嵊州市",
+ "330702": "婺城区",
+ "330703": "金东区",
+ "330723": "武义县",
+ "330726": "浦江县",
+ "330727": "磐安县",
+ "330781": "兰溪市",
+ "330782": "义乌市",
+ "330783": "东阳市",
+ "330784": "永康市",
+ "330802": "柯城区",
+ "330803": "衢江区",
+ "330822": "常山县",
+ "330824": "开化县",
+ "330825": "龙游县",
+ "330881": "江山市",
+ "330902": "定海区",
+ "330903": "普陀区",
+ "330921": "岱山县",
+ "330922": "嵊泗县",
+ "331002": "椒江区",
+ "331003": "黄岩区",
+ "331004": "路桥区",
+ "331022": "三门县",
+ "331023": "天台县",
+ "331024": "仙居县",
+ "331081": "温岭市",
+ "331082": "临海市",
+ "331083": "玉环市",
+ "331102": "莲都区",
+ "331121": "青田县",
+ "331122": "缙云县",
+ "331123": "遂昌县",
+ "331124": "松阳县",
+ "331125": "云和县",
+ "331126": "庆元县",
+ "331127": "景宁畲族自治县",
+ "331181": "龙泉市",
+ "340102": "瑶海区",
+ "340103": "庐阳区",
+ "340104": "蜀山区",
+ "340111": "包河区",
+ "340121": "长丰县",
+ "340122": "肥东县",
+ "340123": "肥西县",
+ "340124": "庐江县",
+ "340171": "合肥高新技术产业开发区",
+ "340172": "合肥经济技术开发区",
+ "340173": "合肥新站高新技术产业开发区",
+ "340181": "巢湖市",
+ "340190": "高新技术开发区",
+ "340191": "经济技术开发区",
+ "340202": "镜湖区",
+ "340207": "鸠江区",
+ "340209": "弋江区",
+ "340210": "湾沚区",
+ "340212": "繁昌区",
+ "340223": "南陵县",
+ "340281": "无为市",
+ "340302": "龙子湖区",
+ "340303": "蚌山区",
+ "340304": "禹会区",
+ "340311": "淮上区",
+ "340321": "怀远县",
+ "340322": "五河县",
+ "340323": "固镇县",
+ "340371": "蚌埠市高新技术开发区",
+ "340372": "蚌埠市经济开发区",
+ "340402": "大通区",
+ "340403": "田家庵区",
+ "340404": "谢家集区",
+ "340405": "八公山区",
+ "340406": "潘集区",
+ "340421": "凤台县",
+ "340422": "寿县",
+ "340503": "花山区",
+ "340504": "雨山区",
+ "340506": "博望区",
+ "340521": "当涂县",
+ "340522": "含山县",
+ "340523": "和县",
+ "340602": "杜集区",
+ "340603": "相山区",
+ "340604": "烈山区",
+ "340621": "濉溪县",
+ "340705": "铜官区",
+ "340706": "义安区",
+ "340711": "郊区",
+ "340722": "枞阳县",
+ "340802": "迎江区",
+ "340803": "大观区",
+ "340811": "宜秀区",
+ "340822": "怀宁县",
+ "340825": "太湖县",
+ "340826": "宿松县",
+ "340827": "望江县",
+ "340828": "岳西县",
+ "340881": "桐城市",
+ "340882": "潜山市",
+ "341002": "屯溪区",
+ "341003": "黄山区",
+ "341004": "徽州区",
+ "341021": "歙县",
+ "341022": "休宁县",
+ "341023": "黟县",
+ "341024": "祁门县",
+ "341102": "琅琊区",
+ "341103": "南谯区",
+ "341122": "来安县",
+ "341124": "全椒县",
+ "341125": "定远县",
+ "341126": "凤阳县",
+ "341181": "天长市",
+ "341182": "明光市",
+ "341202": "颍州区",
+ "341203": "颍东区",
+ "341204": "颍泉区",
+ "341221": "临泉县",
+ "341222": "太和县",
+ "341225": "阜南县",
+ "341226": "颍上县",
+ "341271": "阜阳合肥现代产业园区",
+ "341282": "界首市",
+ "341302": "埇桥区",
+ "341321": "砀山县",
+ "341322": "萧县",
+ "341323": "灵璧县",
+ "341324": "泗县",
+ "341371": "宿州马鞍山现代产业园区",
+ "341372": "宿州经济技术开发区",
+ "341390": "经济开发区",
+ "341502": "金安区",
+ "341503": "裕安区",
+ "341504": "叶集区",
+ "341522": "霍邱县",
+ "341523": "舒城县",
+ "341524": "金寨县",
+ "341525": "霍山县",
+ "341602": "谯城区",
+ "341621": "涡阳县",
+ "341622": "蒙城县",
+ "341623": "利辛县",
+ "341702": "贵池区",
+ "341721": "东至县",
+ "341722": "石台县",
+ "341723": "青阳县",
+ "341802": "宣州区",
+ "341821": "郎溪县",
+ "341823": "泾县",
+ "341824": "绩溪县",
+ "341825": "旌德县",
+ "341871": "宣城市经济开发区",
+ "341881": "宁国市",
+ "341882": "广德市",
+ "350102": "鼓楼区",
+ "350103": "台江区",
+ "350104": "仓山区",
+ "350105": "马尾区",
+ "350111": "晋安区",
+ "350112": "长乐区",
+ "350121": "闽侯县",
+ "350122": "连江县",
+ "350123": "罗源县",
+ "350124": "闽清县",
+ "350125": "永泰县",
+ "350128": "平潭县",
+ "350181": "福清市",
+ "350203": "思明区",
+ "350205": "海沧区",
+ "350206": "湖里区",
+ "350211": "集美区",
+ "350212": "同安区",
+ "350213": "翔安区",
+ "350302": "城厢区",
+ "350303": "涵江区",
+ "350304": "荔城区",
+ "350305": "秀屿区",
+ "350322": "仙游县",
+ "350402": "梅列区",
+ "350404": "三元区",
+ "350405": "沙县区",
+ "350421": "明溪县",
+ "350423": "清流县",
+ "350424": "宁化县",
+ "350425": "大田县",
+ "350426": "尤溪县",
+ "350428": "将乐县",
+ "350429": "泰宁县",
+ "350430": "建宁县",
+ "350481": "永安市",
+ "350502": "鲤城区",
+ "350503": "丰泽区",
+ "350504": "洛江区",
+ "350505": "泉港区",
+ "350521": "惠安县",
+ "350524": "安溪县",
+ "350525": "永春县",
+ "350526": "德化县",
+ "350527": "金门县",
+ "350581": "石狮市",
+ "350582": "晋江市",
+ "350583": "南安市",
+ "350602": "芗城区",
+ "350603": "龙文区",
+ "350604": "龙海区",
+ "350605": "长泰区",
+ "350622": "云霄县",
+ "350623": "漳浦县",
+ "350624": "诏安县",
+ "350626": "东山县",
+ "350627": "南靖县",
+ "350628": "平和县",
+ "350629": "华安县",
+ "350702": "延平区",
+ "350703": "建阳区",
+ "350721": "顺昌县",
+ "350722": "浦城县",
+ "350723": "光泽县",
+ "350724": "松溪县",
+ "350725": "政和县",
+ "350781": "邵武市",
+ "350782": "武夷山市",
+ "350783": "建瓯市",
+ "350802": "新罗区",
+ "350803": "永定区",
+ "350821": "长汀县",
+ "350823": "上杭县",
+ "350824": "武平县",
+ "350825": "连城县",
+ "350881": "漳平市",
+ "350902": "蕉城区",
+ "350921": "霞浦县",
+ "350922": "古田县",
+ "350923": "屏南县",
+ "350924": "寿宁县",
+ "350925": "周宁县",
+ "350926": "柘荣县",
+ "350981": "福安市",
+ "350982": "福鼎市",
+ "360102": "东湖区",
+ "360103": "西湖区",
+ "360104": "青云谱区",
+ "360111": "青山湖区",
+ "360112": "新建区",
+ "360113": "红谷滩区",
+ "360121": "南昌县",
+ "360123": "安义县",
+ "360124": "进贤县",
+ "360190": "经济技术开发区",
+ "360192": "高新区",
+ "360202": "昌江区",
+ "360203": "珠山区",
+ "360222": "浮梁县",
+ "360281": "乐平市",
+ "360302": "安源区",
+ "360313": "湘东区",
+ "360321": "莲花县",
+ "360322": "上栗县",
+ "360323": "芦溪县",
+ "360402": "濂溪区",
+ "360403": "浔阳区",
+ "360404": "柴桑区",
+ "360423": "武宁县",
+ "360424": "修水县",
+ "360425": "永修县",
+ "360426": "德安县",
+ "360428": "都昌县",
+ "360429": "湖口县",
+ "360430": "彭泽县",
+ "360481": "瑞昌市",
+ "360482": "共青城市",
+ "360483": "庐山市",
+ "360490": "经济技术开发区",
+ "360502": "渝水区",
+ "360521": "分宜县",
+ "360602": "月湖区",
+ "360603": "余江区",
+ "360681": "贵溪市",
+ "360702": "章贡区",
+ "360703": "南康区",
+ "360704": "赣县区",
+ "360722": "信丰县",
+ "360723": "大余县",
+ "360724": "上犹县",
+ "360725": "崇义县",
+ "360726": "安远县",
+ "360728": "定南县",
+ "360729": "全南县",
+ "360730": "宁都县",
+ "360731": "于都县",
+ "360732": "兴国县",
+ "360733": "会昌县",
+ "360734": "寻乌县",
+ "360735": "石城县",
+ "360781": "瑞金市",
+ "360783": "龙南市",
+ "360802": "吉州区",
+ "360803": "青原区",
+ "360821": "吉安县",
+ "360822": "吉水县",
+ "360823": "峡江县",
+ "360824": "新干县",
+ "360825": "永丰县",
+ "360826": "泰和县",
+ "360827": "遂川县",
+ "360828": "万安县",
+ "360829": "安福县",
+ "360830": "永新县",
+ "360881": "井冈山市",
+ "360902": "袁州区",
+ "360921": "奉新县",
+ "360922": "万载县",
+ "360923": "上高县",
+ "360924": "宜丰县",
+ "360925": "靖安县",
+ "360926": "铜鼓县",
+ "360981": "丰城市",
+ "360982": "樟树市",
+ "360983": "高安市",
+ "361002": "临川区",
+ "361003": "东乡区",
+ "361021": "南城县",
+ "361022": "黎川县",
+ "361023": "南丰县",
+ "361024": "崇仁县",
+ "361025": "乐安县",
+ "361026": "宜黄县",
+ "361027": "金溪县",
+ "361028": "资溪县",
+ "361030": "广昌县",
+ "361102": "信州区",
+ "361103": "广丰区",
+ "361104": "广信区",
+ "361123": "玉山县",
+ "361124": "铅山县",
+ "361125": "横峰县",
+ "361126": "弋阳县",
+ "361127": "余干县",
+ "361128": "鄱阳县",
+ "361129": "万年县",
+ "361130": "婺源县",
+ "361181": "德兴市",
+ "370102": "历下区",
+ "370103": "市中区",
+ "370104": "槐荫区",
+ "370105": "天桥区",
+ "370112": "历城区",
+ "370113": "长清区",
+ "370114": "章丘区",
+ "370115": "济阳区",
+ "370116": "莱芜区",
+ "370117": "钢城区",
+ "370124": "平阴县",
+ "370126": "商河县",
+ "370171": "济南高新技术产业开发区",
+ "370190": "高新区",
+ "370202": "市南区",
+ "370203": "市北区",
+ "370211": "黄岛区",
+ "370212": "崂山区",
+ "370213": "李沧区",
+ "370214": "城阳区",
+ "370215": "即墨区",
+ "370271": "青岛高新技术产业开发区",
+ "370281": "胶州市",
+ "370283": "平度市",
+ "370285": "莱西市",
+ "370290": "开发区",
+ "370302": "淄川区",
+ "370303": "张店区",
+ "370304": "博山区",
+ "370305": "临淄区",
+ "370306": "周村区",
+ "370321": "桓台县",
+ "370322": "高青县",
+ "370323": "沂源县",
+ "370402": "市中区",
+ "370403": "薛城区",
+ "370404": "峄城区",
+ "370405": "台儿庄区",
+ "370406": "山亭区",
+ "370481": "滕州市",
+ "370502": "东营区",
+ "370503": "河口区",
+ "370505": "垦利区",
+ "370522": "利津县",
+ "370523": "广饶县",
+ "370571": "东营经济技术开发区",
+ "370572": "东营港经济开发区",
+ "370602": "芝罘区",
+ "370611": "福山区",
+ "370612": "牟平区",
+ "370613": "莱山区",
+ "370614": "蓬莱区",
+ "370634": "长岛县",
+ "370671": "烟台高新技术产业开发区",
+ "370672": "烟台经济技术开发区",
+ "370681": "龙口市",
+ "370682": "莱阳市",
+ "370683": "莱州市",
+ "370685": "招远市",
+ "370686": "栖霞市",
+ "370687": "海阳市",
+ "370690": "开发区",
+ "370702": "潍城区",
+ "370703": "寒亭区",
+ "370704": "坊子区",
+ "370705": "奎文区",
+ "370724": "临朐县",
+ "370725": "昌乐县",
+ "370772": "潍坊滨海经济技术开发区",
+ "370781": "青州市",
+ "370782": "诸城市",
+ "370783": "寿光市",
+ "370784": "安丘市",
+ "370785": "高密市",
+ "370786": "昌邑市",
+ "370790": "开发区",
+ "370791": "高新区",
+ "370811": "任城区",
+ "370812": "兖州区",
+ "370826": "微山县",
+ "370827": "鱼台县",
+ "370828": "金乡县",
+ "370829": "嘉祥县",
+ "370830": "汶上县",
+ "370831": "泗水县",
+ "370832": "梁山县",
+ "370871": "济宁高新技术产业开发区",
+ "370881": "曲阜市",
+ "370883": "邹城市",
+ "370890": "高新区",
+ "370902": "泰山区",
+ "370911": "岱岳区",
+ "370921": "宁阳县",
+ "370923": "东平县",
+ "370982": "新泰市",
+ "370983": "肥城市",
+ "371002": "环翠区",
+ "371003": "文登区",
+ "371071": "威海火炬高技术产业开发区",
+ "371072": "威海经济技术开发区",
+ "371082": "荣成市",
+ "371083": "乳山市",
+ "371091": "经济技术开发区",
+ "371102": "东港区",
+ "371103": "岚山区",
+ "371121": "五莲县",
+ "371122": "莒县",
+ "371171": "日照经济技术开发区",
+ "371302": "兰山区",
+ "371311": "罗庄区",
+ "371312": "河东区",
+ "371321": "沂南县",
+ "371322": "郯城县",
+ "371323": "沂水县",
+ "371324": "兰陵县",
+ "371325": "费县",
+ "371326": "平邑县",
+ "371327": "莒南县",
+ "371328": "蒙阴县",
+ "371329": "临沭县",
+ "371371": "临沂高新技术产业开发区",
+ "371402": "德城区",
+ "371403": "陵城区",
+ "371422": "宁津县",
+ "371423": "庆云县",
+ "371424": "临邑县",
+ "371425": "齐河县",
+ "371426": "平原县",
+ "371427": "夏津县",
+ "371428": "武城县",
+ "371472": "德州运河经济开发区",
+ "371481": "乐陵市",
+ "371482": "禹城市",
+ "371502": "东昌府区",
+ "371503": "茌平区",
+ "371521": "阳谷县",
+ "371522": "莘县",
+ "371524": "东阿县",
+ "371525": "冠县",
+ "371526": "高唐县",
+ "371581": "临清市",
+ "371602": "滨城区",
+ "371603": "沾化区",
+ "371621": "惠民县",
+ "371622": "阳信县",
+ "371623": "无棣县",
+ "371625": "博兴县",
+ "371681": "邹平市",
+ "371702": "牡丹区",
+ "371703": "定陶区",
+ "371721": "曹县",
+ "371722": "单县",
+ "371723": "成武县",
+ "371724": "巨野县",
+ "371725": "郓城县",
+ "371726": "鄄城县",
+ "371728": "东明县",
+ "371771": "菏泽经济技术开发区",
+ "371772": "菏泽高新技术开发区",
+ "410102": "中原区",
+ "410103": "二七区",
+ "410104": "管城回族区",
+ "410105": "金水区",
+ "410106": "上街区",
+ "410108": "惠济区",
+ "410122": "中牟县",
+ "410171": "郑州经济技术开发区",
+ "410172": "郑州高新技术产业开发区",
+ "410173": "郑州航空港经济综合实验区",
+ "410181": "巩义市",
+ "410182": "荥阳市",
+ "410183": "新密市",
+ "410184": "新郑市",
+ "410185": "登封市",
+ "410190": "高新技术开发区",
+ "410191": "经济技术开发区",
+ "410202": "龙亭区",
+ "410203": "顺河回族区",
+ "410204": "鼓楼区",
+ "410205": "禹王台区",
+ "410212": "祥符区",
+ "410221": "杞县",
+ "410222": "通许县",
+ "410223": "尉氏县",
+ "410225": "兰考县",
+ "410302": "老城区",
+ "410303": "西工区",
+ "410304": "瀍河回族区",
+ "410305": "涧西区",
+ "410307": "偃师区",
+ "410308": "孟津区",
+ "410311": "洛龙区",
+ "410323": "新安县",
+ "410324": "栾川县",
+ "410325": "嵩县",
+ "410326": "汝阳县",
+ "410327": "宜阳县",
+ "410328": "洛宁县",
+ "410329": "伊川县",
+ "410402": "新华区",
+ "410403": "卫东区",
+ "410404": "石龙区",
+ "410411": "湛河区",
+ "410421": "宝丰县",
+ "410422": "叶县",
+ "410423": "鲁山县",
+ "410425": "郏县",
+ "410471": "平顶山高新技术产业开发区",
+ "410481": "舞钢市",
+ "410482": "汝州市",
+ "410502": "文峰区",
+ "410503": "北关区",
+ "410505": "殷都区",
+ "410506": "龙安区",
+ "410522": "安阳县",
+ "410523": "汤阴县",
+ "410526": "滑县",
+ "410527": "内黄县",
+ "410581": "林州市",
+ "410590": "开发区",
+ "410602": "鹤山区",
+ "410603": "山城区",
+ "410611": "淇滨区",
+ "410621": "浚县",
+ "410622": "淇县",
+ "410702": "红旗区",
+ "410703": "卫滨区",
+ "410704": "凤泉区",
+ "410711": "牧野区",
+ "410721": "新乡县",
+ "410724": "获嘉县",
+ "410725": "原阳县",
+ "410726": "延津县",
+ "410727": "封丘县",
+ "410771": "新乡高新技术产业开发区",
+ "410772": "新乡经济技术开发区",
+ "410781": "卫辉市",
+ "410782": "辉县市",
+ "410783": "长垣市",
+ "410802": "解放区",
+ "410803": "中站区",
+ "410804": "马村区",
+ "410811": "山阳区",
+ "410821": "修武县",
+ "410822": "博爱县",
+ "410823": "武陟县",
+ "410825": "温县",
+ "410871": "焦作城乡一体化示范区",
+ "410882": "沁阳市",
+ "410883": "孟州市",
+ "410902": "华龙区",
+ "410922": "清丰县",
+ "410923": "南乐县",
+ "410926": "范县",
+ "410927": "台前县",
+ "410928": "濮阳县",
+ "410971": "河南濮阳工业园区",
+ "411002": "魏都区",
+ "411003": "建安区",
+ "411024": "鄢陵县",
+ "411025": "襄城县",
+ "411071": "许昌经济技术开发区",
+ "411081": "禹州市",
+ "411082": "长葛市",
+ "411102": "源汇区",
+ "411103": "郾城区",
+ "411104": "召陵区",
+ "411121": "舞阳县",
+ "411122": "临颍县",
+ "411171": "漯河经济技术开发区",
+ "411202": "湖滨区",
+ "411203": "陕州区",
+ "411221": "渑池县",
+ "411224": "卢氏县",
+ "411271": "河南三门峡经济开发区",
+ "411281": "义马市",
+ "411282": "灵宝市",
+ "411302": "宛城区",
+ "411303": "卧龙区",
+ "411321": "南召县",
+ "411322": "方城县",
+ "411323": "西峡县",
+ "411324": "镇平县",
+ "411325": "内乡县",
+ "411326": "淅川县",
+ "411327": "社旗县",
+ "411328": "唐河县",
+ "411329": "新野县",
+ "411330": "桐柏县",
+ "411372": "南阳市城乡一体化示范区",
+ "411381": "邓州市",
+ "411402": "梁园区",
+ "411403": "睢阳区",
+ "411421": "民权县",
+ "411422": "睢县",
+ "411423": "宁陵县",
+ "411424": "柘城县",
+ "411425": "虞城县",
+ "411426": "夏邑县",
+ "411481": "永城市",
+ "411502": "浉河区",
+ "411503": "平桥区",
+ "411521": "罗山县",
+ "411522": "光山县",
+ "411523": "新县",
+ "411524": "商城县",
+ "411525": "固始县",
+ "411526": "潢川县",
+ "411527": "淮滨县",
+ "411528": "息县",
+ "411602": "川汇区",
+ "411603": "淮阳区",
+ "411621": "扶沟县",
+ "411622": "西华县",
+ "411623": "商水县",
+ "411624": "沈丘县",
+ "411625": "郸城县",
+ "411627": "太康县",
+ "411628": "鹿邑县",
+ "411671": "河南周口经济开发区",
+ "411681": "项城市",
+ "411690": "经济开发区",
+ "411702": "驿城区",
+ "411721": "西平县",
+ "411722": "上蔡县",
+ "411723": "平舆县",
+ "411724": "正阳县",
+ "411725": "确山县",
+ "411726": "泌阳县",
+ "411727": "汝南县",
+ "411728": "遂平县",
+ "411729": "新蔡县",
+ "419001": "济源市",
+ "420102": "江岸区",
+ "420103": "江汉区",
+ "420104": "硚口区",
+ "420105": "汉阳区",
+ "420106": "武昌区",
+ "420107": "青山区",
+ "420111": "洪山区",
+ "420112": "东西湖区",
+ "420113": "汉南区",
+ "420114": "蔡甸区",
+ "420115": "江夏区",
+ "420116": "黄陂区",
+ "420117": "新洲区",
+ "420202": "黄石港区",
+ "420203": "西塞山区",
+ "420204": "下陆区",
+ "420205": "铁山区",
+ "420222": "阳新县",
+ "420281": "大冶市",
+ "420302": "茅箭区",
+ "420303": "张湾区",
+ "420304": "郧阳区",
+ "420322": "郧西县",
+ "420323": "竹山县",
+ "420324": "竹溪县",
+ "420325": "房县",
+ "420381": "丹江口市",
+ "420502": "西陵区",
+ "420503": "伍家岗区",
+ "420504": "点军区",
+ "420505": "猇亭区",
+ "420506": "夷陵区",
+ "420525": "远安县",
+ "420526": "兴山县",
+ "420527": "秭归县",
+ "420528": "长阳土家族自治县",
+ "420529": "五峰土家族自治县",
+ "420581": "宜都市",
+ "420582": "当阳市",
+ "420583": "枝江市",
+ "420590": "经济开发区",
+ "420602": "襄城区",
+ "420606": "樊城区",
+ "420607": "襄州区",
+ "420624": "南漳县",
+ "420625": "谷城县",
+ "420626": "保康县",
+ "420682": "老河口市",
+ "420683": "枣阳市",
+ "420684": "宜城市",
+ "420702": "梁子湖区",
+ "420703": "华容区",
+ "420704": "鄂城区",
+ "420802": "东宝区",
+ "420804": "掇刀区",
+ "420822": "沙洋县",
+ "420881": "钟祥市",
+ "420882": "京山市",
+ "420902": "孝南区",
+ "420921": "孝昌县",
+ "420922": "大悟县",
+ "420923": "云梦县",
+ "420981": "应城市",
+ "420982": "安陆市",
+ "420984": "汉川市",
+ "421002": "沙市区",
+ "421003": "荆州区",
+ "421022": "公安县",
+ "421024": "江陵县",
+ "421081": "石首市",
+ "421083": "洪湖市",
+ "421087": "松滋市",
+ "421088": "监利市",
+ "421102": "黄州区",
+ "421121": "团风县",
+ "421122": "红安县",
+ "421123": "罗田县",
+ "421124": "英山县",
+ "421125": "浠水县",
+ "421126": "蕲春县",
+ "421127": "黄梅县",
+ "421171": "龙感湖管理区",
+ "421181": "麻城市",
+ "421182": "武穴市",
+ "421202": "咸安区",
+ "421221": "嘉鱼县",
+ "421222": "通城县",
+ "421223": "崇阳县",
+ "421224": "通山县",
+ "421281": "赤壁市",
+ "421303": "曾都区",
+ "421321": "随县",
+ "421381": "广水市",
+ "422801": "恩施市",
+ "422802": "利川市",
+ "422822": "建始县",
+ "422823": "巴东县",
+ "422825": "宣恩县",
+ "422826": "咸丰县",
+ "422827": "来凤县",
+ "422828": "鹤峰县",
+ "429004": "仙桃市",
+ "429005": "潜江市",
+ "429006": "天门市",
+ "429021": "神农架林区",
+ "430102": "芙蓉区",
+ "430103": "天心区",
+ "430104": "岳麓区",
+ "430105": "开福区",
+ "430111": "雨花区",
+ "430112": "望城区",
+ "430121": "长沙县",
+ "430181": "浏阳市",
+ "430182": "宁乡市",
+ "430202": "荷塘区",
+ "430203": "芦淞区",
+ "430204": "石峰区",
+ "430211": "天元区",
+ "430212": "渌口区",
+ "430223": "攸县",
+ "430224": "茶陵县",
+ "430225": "炎陵县",
+ "430271": "云龙示范区",
+ "430281": "醴陵市",
+ "430302": "雨湖区",
+ "430304": "岳塘区",
+ "430321": "湘潭县",
+ "430373": "湘潭九华示范区",
+ "430381": "湘乡市",
+ "430382": "韶山市",
+ "430405": "珠晖区",
+ "430406": "雁峰区",
+ "430407": "石鼓区",
+ "430408": "蒸湘区",
+ "430412": "南岳区",
+ "430421": "衡阳县",
+ "430422": "衡南县",
+ "430423": "衡山县",
+ "430424": "衡东县",
+ "430426": "祁东县",
+ "430481": "耒阳市",
+ "430482": "常宁市",
+ "430502": "双清区",
+ "430503": "大祥区",
+ "430511": "北塔区",
+ "430522": "新邵县",
+ "430523": "邵阳县",
+ "430524": "隆回县",
+ "430525": "洞口县",
+ "430527": "绥宁县",
+ "430528": "新宁县",
+ "430529": "城步苗族自治县",
+ "430581": "武冈市",
+ "430582": "邵东市",
+ "430602": "岳阳楼区",
+ "430603": "云溪区",
+ "430611": "君山区",
+ "430621": "岳阳县",
+ "430623": "华容县",
+ "430624": "湘阴县",
+ "430626": "平江县",
+ "430681": "汨罗市",
+ "430682": "临湘市",
+ "430702": "武陵区",
+ "430703": "鼎城区",
+ "430721": "安乡县",
+ "430722": "汉寿县",
+ "430723": "澧县",
+ "430724": "临澧县",
+ "430725": "桃源县",
+ "430726": "石门县",
+ "430781": "津市市",
+ "430802": "永定区",
+ "430811": "武陵源区",
+ "430821": "慈利县",
+ "430822": "桑植县",
+ "430902": "资阳区",
+ "430903": "赫山区",
+ "430921": "南县",
+ "430922": "桃江县",
+ "430923": "安化县",
+ "430971": "益阳市大通湖管理区",
+ "430981": "沅江市",
+ "431002": "北湖区",
+ "431003": "苏仙区",
+ "431021": "桂阳县",
+ "431022": "宜章县",
+ "431023": "永兴县",
+ "431024": "嘉禾县",
+ "431025": "临武县",
+ "431026": "汝城县",
+ "431027": "桂东县",
+ "431028": "安仁县",
+ "431081": "资兴市",
+ "431102": "零陵区",
+ "431103": "冷水滩区",
+ "431122": "东安县",
+ "431123": "双牌县",
+ "431124": "道县",
+ "431125": "江永县",
+ "431126": "宁远县",
+ "431127": "蓝山县",
+ "431128": "新田县",
+ "431129": "江华瑶族自治县",
+ "431181": "祁阳市",
+ "431202": "鹤城区",
+ "431221": "中方县",
+ "431222": "沅陵县",
+ "431223": "辰溪县",
+ "431224": "溆浦县",
+ "431225": "会同县",
+ "431226": "麻阳苗族自治县",
+ "431227": "新晃侗族自治县",
+ "431228": "芷江侗族自治县",
+ "431229": "靖州苗族侗族自治县",
+ "431230": "通道侗族自治县",
+ "431271": "怀化市洪江管理区",
+ "431281": "洪江市",
+ "431302": "娄星区",
+ "431321": "双峰县",
+ "431322": "新化县",
+ "431381": "冷水江市",
+ "431382": "涟源市",
+ "433101": "吉首市",
+ "433122": "泸溪县",
+ "433123": "凤凰县",
+ "433124": "花垣县",
+ "433125": "保靖县",
+ "433126": "古丈县",
+ "433127": "永顺县",
+ "433130": "龙山县",
+ "440103": "荔湾区",
+ "440104": "越秀区",
+ "440105": "海珠区",
+ "440106": "天河区",
+ "440111": "白云区",
+ "440112": "黄埔区",
+ "440113": "番禺区",
+ "440114": "花都区",
+ "440115": "南沙区",
+ "440117": "从化区",
+ "440118": "增城区",
+ "440203": "武江区",
+ "440204": "浈江区",
+ "440205": "曲江区",
+ "440222": "始兴县",
+ "440224": "仁化县",
+ "440229": "翁源县",
+ "440232": "乳源瑶族自治县",
+ "440233": "新丰县",
+ "440281": "乐昌市",
+ "440282": "南雄市",
+ "440303": "罗湖区",
+ "440304": "福田区",
+ "440305": "南山区",
+ "440306": "宝安区",
+ "440307": "龙岗区",
+ "440308": "盐田区",
+ "440309": "龙华区",
+ "440310": "坪山区",
+ "440311": "光明区",
+ "440402": "香洲区",
+ "440403": "斗门区",
+ "440404": "金湾区",
+ "440507": "龙湖区",
+ "440511": "金平区",
+ "440512": "濠江区",
+ "440513": "潮阳区",
+ "440514": "潮南区",
+ "440515": "澄海区",
+ "440523": "南澳县",
+ "440604": "禅城区",
+ "440605": "南海区",
+ "440606": "顺德区",
+ "440607": "三水区",
+ "440608": "高明区",
+ "440703": "蓬江区",
+ "440704": "江海区",
+ "440705": "新会区",
+ "440781": "台山市",
+ "440783": "开平市",
+ "440784": "鹤山市",
+ "440785": "恩平市",
+ "440802": "赤坎区",
+ "440803": "霞山区",
+ "440804": "坡头区",
+ "440811": "麻章区",
+ "440823": "遂溪县",
+ "440825": "徐闻县",
+ "440881": "廉江市",
+ "440882": "雷州市",
+ "440883": "吴川市",
+ "440890": "经济技术开发区",
+ "440902": "茂南区",
+ "440904": "电白区",
+ "440981": "高州市",
+ "440982": "化州市",
+ "440983": "信宜市",
+ "441202": "端州区",
+ "441203": "鼎湖区",
+ "441204": "高要区",
+ "441223": "广宁县",
+ "441224": "怀集县",
+ "441225": "封开县",
+ "441226": "德庆县",
+ "441284": "四会市",
+ "441302": "惠城区",
+ "441303": "惠阳区",
+ "441322": "博罗县",
+ "441323": "惠东县",
+ "441324": "龙门县",
+ "441402": "梅江区",
+ "441403": "梅县区",
+ "441422": "大埔县",
+ "441423": "丰顺县",
+ "441424": "五华县",
+ "441426": "平远县",
+ "441427": "蕉岭县",
+ "441481": "兴宁市",
+ "441502": "城区",
+ "441521": "海丰县",
+ "441523": "陆河县",
+ "441581": "陆丰市",
+ "441602": "源城区",
+ "441621": "紫金县",
+ "441622": "龙川县",
+ "441623": "连平县",
+ "441624": "和平县",
+ "441625": "东源县",
+ "441702": "江城区",
+ "441704": "阳东区",
+ "441721": "阳西县",
+ "441781": "阳春市",
+ "441802": "清城区",
+ "441803": "清新区",
+ "441821": "佛冈县",
+ "441823": "阳山县",
+ "441825": "连山壮族瑶族自治县",
+ "441826": "连南瑶族自治县",
+ "441881": "英德市",
+ "441882": "连州市",
+ "441901": "中堂镇",
+ "441903": "南城街道",
+ "441904": "长安镇",
+ "441905": "东坑镇",
+ "441906": "樟木头镇",
+ "441907": "莞城街道",
+ "441908": "石龙镇",
+ "441909": "桥头镇",
+ "441910": "万江街道",
+ "441911": "麻涌镇",
+ "441912": "虎门镇",
+ "441913": "谢岗镇",
+ "441914": "石碣镇",
+ "441915": "茶山镇",
+ "441916": "东城街道",
+ "441917": "洪梅镇",
+ "441918": "道滘镇",
+ "441919": "高埗镇",
+ "441920": "企石镇",
+ "441921": "凤岗镇",
+ "441922": "大岭山镇",
+ "441923": "松山湖",
+ "441924": "清溪镇",
+ "441925": "望牛墩镇",
+ "441926": "厚街镇",
+ "441927": "常平镇",
+ "441928": "寮步镇",
+ "441929": "石排镇",
+ "441930": "横沥镇",
+ "441931": "塘厦镇",
+ "441932": "黄江镇",
+ "441933": "大朗镇",
+ "441934": "东莞港",
+ "441935": "东莞生态园",
+ "441990": "沙田镇",
+ "442001": "南头镇",
+ "442002": "神湾镇",
+ "442003": "东凤镇",
+ "442004": "五桂山街道",
+ "442005": "黄圃镇",
+ "442006": "小榄镇",
+ "442007": "石岐街道",
+ "442008": "横栏镇",
+ "442009": "三角镇",
+ "442010": "三乡镇",
+ "442011": "港口镇",
+ "442012": "沙溪镇",
+ "442013": "板芙镇",
+ "442015": "东升镇",
+ "442016": "阜沙镇",
+ "442017": "民众镇",
+ "442018": "东区街道",
+ "442019": "火炬开发区街道办事处",
+ "442020": "西区街道",
+ "442021": "南区街道",
+ "442022": "古镇镇",
+ "442023": "坦洲镇",
+ "442024": "大涌镇",
+ "442025": "南朗镇",
+ "445102": "湘桥区",
+ "445103": "潮安区",
+ "445122": "饶平县",
+ "445202": "榕城区",
+ "445203": "揭东区",
+ "445222": "揭西县",
+ "445224": "惠来县",
+ "445281": "普宁市",
+ "445302": "云城区",
+ "445303": "云安区",
+ "445321": "新兴县",
+ "445322": "郁南县",
+ "445381": "罗定市",
+ "450102": "兴宁区",
+ "450103": "青秀区",
+ "450105": "江南区",
+ "450107": "西乡塘区",
+ "450108": "良庆区",
+ "450109": "邕宁区",
+ "450110": "武鸣区",
+ "450123": "隆安县",
+ "450124": "马山县",
+ "450125": "上林县",
+ "450126": "宾阳县",
+ "450181": "横州市",
+ "450202": "城中区",
+ "450203": "鱼峰区",
+ "450204": "柳南区",
+ "450205": "柳北区",
+ "450206": "柳江区",
+ "450222": "柳城县",
+ "450223": "鹿寨县",
+ "450224": "融安县",
+ "450225": "融水苗族自治县",
+ "450226": "三江侗族自治县",
+ "450302": "秀峰区",
+ "450303": "叠彩区",
+ "450304": "象山区",
+ "450305": "七星区",
+ "450311": "雁山区",
+ "450312": "临桂区",
+ "450321": "阳朔县",
+ "450323": "灵川县",
+ "450324": "全州县",
+ "450325": "兴安县",
+ "450326": "永福县",
+ "450327": "灌阳县",
+ "450328": "龙胜各族自治县",
+ "450329": "资源县",
+ "450330": "平乐县",
+ "450332": "恭城瑶族自治县",
+ "450381": "荔浦市",
+ "450403": "万秀区",
+ "450405": "长洲区",
+ "450406": "龙圩区",
+ "450421": "苍梧县",
+ "450422": "藤县",
+ "450423": "蒙山县",
+ "450481": "岑溪市",
+ "450502": "海城区",
+ "450503": "银海区",
+ "450512": "铁山港区",
+ "450521": "合浦县",
+ "450602": "港口区",
+ "450603": "防城区",
+ "450621": "上思县",
+ "450681": "东兴市",
+ "450702": "钦南区",
+ "450703": "钦北区",
+ "450721": "灵山县",
+ "450722": "浦北县",
+ "450802": "港北区",
+ "450803": "港南区",
+ "450804": "覃塘区",
+ "450821": "平南县",
+ "450881": "桂平市",
+ "450902": "玉州区",
+ "450903": "福绵区",
+ "450921": "容县",
+ "450922": "陆川县",
+ "450923": "博白县",
+ "450924": "兴业县",
+ "450981": "北流市",
+ "451002": "右江区",
+ "451003": "田阳区",
+ "451022": "田东县",
+ "451024": "德保县",
+ "451026": "那坡县",
+ "451027": "凌云县",
+ "451028": "乐业县",
+ "451029": "田林县",
+ "451030": "西林县",
+ "451031": "隆林各族自治县",
+ "451081": "靖西市",
+ "451082": "平果市",
+ "451102": "八步区",
+ "451103": "平桂区",
+ "451121": "昭平县",
+ "451122": "钟山县",
+ "451123": "富川瑶族自治县",
+ "451202": "金城江区",
+ "451203": "宜州区",
+ "451221": "南丹县",
+ "451222": "天峨县",
+ "451223": "凤山县",
+ "451224": "东兰县",
+ "451225": "罗城仫佬族自治县",
+ "451226": "环江毛南族自治县",
+ "451227": "巴马瑶族自治县",
+ "451228": "都安瑶族自治县",
+ "451229": "大化瑶族自治县",
+ "451302": "兴宾区",
+ "451321": "忻城县",
+ "451322": "象州县",
+ "451323": "武宣县",
+ "451324": "金秀瑶族自治县",
+ "451381": "合山市",
+ "451402": "江州区",
+ "451421": "扶绥县",
+ "451422": "宁明县",
+ "451423": "龙州县",
+ "451424": "大新县",
+ "451425": "天等县",
+ "451481": "凭祥市",
+ "460105": "秀英区",
+ "460106": "龙华区",
+ "460107": "琼山区",
+ "460108": "美兰区",
+ "460202": "海棠区",
+ "460203": "吉阳区",
+ "460204": "天涯区",
+ "460205": "崖州区",
+ "460321": "西沙区",
+ "460322": "南沙区",
+ "460401": "那大镇",
+ "460402": "和庆镇",
+ "460403": "南丰镇",
+ "460404": "大成镇",
+ "460405": "雅星镇",
+ "460406": "兰洋镇",
+ "460407": "光村镇",
+ "460408": "木棠镇",
+ "460409": "海头镇",
+ "460410": "峨蔓镇",
+ "460411": "王五镇",
+ "460412": "白马井镇",
+ "460413": "中和镇",
+ "460414": "排浦镇",
+ "460415": "东成镇",
+ "460416": "新州镇",
+ "460417": "洋浦经济开发区",
+ "460418": "华南热作学院",
+ "469001": "五指山市",
+ "469002": "琼海市",
+ "469005": "文昌市",
+ "469006": "万宁市",
+ "469007": "东方市",
+ "469021": "定安县",
+ "469022": "屯昌县",
+ "469023": "澄迈县",
+ "469024": "临高县",
+ "469025": "白沙黎族自治县",
+ "469026": "昌江黎族自治县",
+ "469027": "乐东黎族自治县",
+ "469028": "陵水黎族自治县",
+ "469029": "保亭黎族苗族自治县",
+ "469030": "琼中黎族苗族自治县",
+ "500101": "万州区",
+ "500102": "涪陵区",
+ "500103": "渝中区",
+ "500104": "大渡口区",
+ "500105": "江北区",
+ "500106": "沙坪坝区",
+ "500107": "九龙坡区",
+ "500108": "南岸区",
+ "500109": "北碚区",
+ "500110": "綦江区",
+ "500111": "大足区",
+ "500112": "渝北区",
+ "500113": "巴南区",
+ "500114": "黔江区",
+ "500115": "长寿区",
+ "500116": "江津区",
+ "500117": "合川区",
+ "500118": "永川区",
+ "500119": "南川区",
+ "500120": "璧山区",
+ "500151": "铜梁区",
+ "500152": "潼南区",
+ "500153": "荣昌区",
+ "500154": "开州区",
+ "500155": "梁平区",
+ "500156": "武隆区",
+ "500229": "城口县",
+ "500230": "丰都县",
+ "500231": "垫江县",
+ "500233": "忠县",
+ "500235": "云阳县",
+ "500236": "奉节县",
+ "500237": "巫山县",
+ "500238": "巫溪县",
+ "500240": "石柱土家族自治县",
+ "500241": "秀山土家族苗族自治县",
+ "500242": "酉阳土家族苗族自治县",
+ "500243": "彭水苗族土家族自治县",
+ "510104": "锦江区",
+ "510105": "青羊区",
+ "510106": "金牛区",
+ "510107": "武侯区",
+ "510108": "成华区",
+ "510112": "龙泉驿区",
+ "510113": "青白江区",
+ "510114": "新都区",
+ "510115": "温江区",
+ "510116": "双流区",
+ "510117": "郫都区",
+ "510118": "新津区",
+ "510121": "金堂县",
+ "510129": "大邑县",
+ "510131": "蒲江县",
+ "510181": "都江堰市",
+ "510182": "彭州市",
+ "510183": "邛崃市",
+ "510184": "崇州市",
+ "510185": "简阳市",
+ "510191": "高新区",
+ "510302": "自流井区",
+ "510303": "贡井区",
+ "510304": "大安区",
+ "510311": "沿滩区",
+ "510321": "荣县",
+ "510322": "富顺县",
+ "510402": "东区",
+ "510403": "西区",
+ "510411": "仁和区",
+ "510421": "米易县",
+ "510422": "盐边县",
+ "510502": "江阳区",
+ "510503": "纳溪区",
+ "510504": "龙马潭区",
+ "510521": "泸县",
+ "510522": "合江县",
+ "510524": "叙永县",
+ "510525": "古蔺县",
+ "510603": "旌阳区",
+ "510604": "罗江区",
+ "510623": "中江县",
+ "510681": "广汉市",
+ "510682": "什邡市",
+ "510683": "绵竹市",
+ "510703": "涪城区",
+ "510704": "游仙区",
+ "510705": "安州区",
+ "510722": "三台县",
+ "510723": "盐亭县",
+ "510725": "梓潼县",
+ "510726": "北川羌族自治县",
+ "510727": "平武县",
+ "510781": "江油市",
+ "510791": "高新区",
+ "510802": "利州区",
+ "510811": "昭化区",
+ "510812": "朝天区",
+ "510821": "旺苍县",
+ "510822": "青川县",
+ "510823": "剑阁县",
+ "510824": "苍溪县",
+ "510903": "船山区",
+ "510904": "安居区",
+ "510921": "蓬溪县",
+ "510923": "大英县",
+ "510981": "射洪市",
+ "511002": "市中区",
+ "511011": "东兴区",
+ "511024": "威远县",
+ "511025": "资中县",
+ "511083": "隆昌市",
+ "511102": "市中区",
+ "511111": "沙湾区",
+ "511112": "五通桥区",
+ "511113": "金口河区",
+ "511123": "犍为县",
+ "511124": "井研县",
+ "511126": "夹江县",
+ "511129": "沐川县",
+ "511132": "峨边彝族自治县",
+ "511133": "马边彝族自治县",
+ "511181": "峨眉山市",
+ "511302": "顺庆区",
+ "511303": "高坪区",
+ "511304": "嘉陵区",
+ "511321": "南部县",
+ "511322": "营山县",
+ "511323": "蓬安县",
+ "511324": "仪陇县",
+ "511325": "西充县",
+ "511381": "阆中市",
+ "511402": "东坡区",
+ "511403": "彭山区",
+ "511421": "仁寿县",
+ "511423": "洪雅县",
+ "511424": "丹棱县",
+ "511425": "青神县",
+ "511502": "翠屏区",
+ "511503": "南溪区",
+ "511504": "叙州区",
+ "511523": "江安县",
+ "511524": "长宁县",
+ "511525": "高县",
+ "511526": "珙县",
+ "511527": "筠连县",
+ "511528": "兴文县",
+ "511529": "屏山县",
+ "511602": "广安区",
+ "511603": "前锋区",
+ "511621": "岳池县",
+ "511622": "武胜县",
+ "511623": "邻水县",
+ "511681": "华蓥市",
+ "511702": "通川区",
+ "511703": "达川区",
+ "511722": "宣汉县",
+ "511723": "开江县",
+ "511724": "大竹县",
+ "511725": "渠县",
+ "511781": "万源市",
+ "511802": "雨城区",
+ "511803": "名山区",
+ "511822": "荥经县",
+ "511823": "汉源县",
+ "511824": "石棉县",
+ "511825": "天全县",
+ "511826": "芦山县",
+ "511827": "宝兴县",
+ "511902": "巴州区",
+ "511903": "恩阳区",
+ "511921": "通江县",
+ "511922": "南江县",
+ "511923": "平昌县",
+ "511971": "巴中经济开发区",
+ "512002": "雁江区",
+ "512021": "安岳县",
+ "512022": "乐至县",
+ "513201": "马尔康市",
+ "513221": "汶川县",
+ "513222": "理县",
+ "513223": "茂县",
+ "513224": "松潘县",
+ "513225": "九寨沟县",
+ "513226": "金川县",
+ "513227": "小金县",
+ "513228": "黑水县",
+ "513230": "壤塘县",
+ "513231": "阿坝县",
+ "513232": "若尔盖县",
+ "513233": "红原县",
+ "513301": "康定市",
+ "513322": "泸定县",
+ "513323": "丹巴县",
+ "513324": "九龙县",
+ "513325": "雅江县",
+ "513326": "道孚县",
+ "513327": "炉霍县",
+ "513328": "甘孜县",
+ "513329": "新龙县",
+ "513330": "德格县",
+ "513331": "白玉县",
+ "513332": "石渠县",
+ "513333": "色达县",
+ "513334": "理塘县",
+ "513335": "巴塘县",
+ "513336": "乡城县",
+ "513337": "稻城县",
+ "513338": "得荣县",
+ "513401": "西昌市",
+ "513402": "会理市",
+ "513422": "木里藏族自治县",
+ "513423": "盐源县",
+ "513424": "德昌县",
+ "513426": "会东县",
+ "513427": "宁南县",
+ "513428": "普格县",
+ "513429": "布拖县",
+ "513430": "金阳县",
+ "513431": "昭觉县",
+ "513432": "喜德县",
+ "513433": "冕宁县",
+ "513434": "越西县",
+ "513435": "甘洛县",
+ "513436": "美姑县",
+ "513437": "雷波县",
+ "520102": "南明区",
+ "520103": "云岩区",
+ "520111": "花溪区",
+ "520112": "乌当区",
+ "520113": "白云区",
+ "520115": "观山湖区",
+ "520121": "开阳县",
+ "520122": "息烽县",
+ "520123": "修文县",
+ "520181": "清镇市",
+ "520201": "钟山区",
+ "520203": "六枝特区",
+ "520204": "水城区",
+ "520281": "盘州市",
+ "520302": "红花岗区",
+ "520303": "汇川区",
+ "520304": "播州区",
+ "520322": "桐梓县",
+ "520323": "绥阳县",
+ "520324": "正安县",
+ "520325": "道真仡佬族苗族自治县",
+ "520326": "务川仡佬族苗族自治县",
+ "520327": "凤冈县",
+ "520328": "湄潭县",
+ "520329": "余庆县",
+ "520330": "习水县",
+ "520381": "赤水市",
+ "520382": "仁怀市",
+ "520402": "西秀区",
+ "520403": "平坝区",
+ "520422": "普定县",
+ "520423": "镇宁布依族苗族自治县",
+ "520424": "关岭布依族苗族自治县",
+ "520425": "紫云苗族布依族自治县",
+ "520502": "七星关区",
+ "520521": "大方县",
+ "520523": "金沙县",
+ "520524": "织金县",
+ "520525": "纳雍县",
+ "520526": "威宁彝族回族苗族自治县",
+ "520527": "赫章县",
+ "520581": "黔西市",
+ "520602": "碧江区",
+ "520603": "万山区",
+ "520621": "江口县",
+ "520622": "玉屏侗族自治县",
+ "520623": "石阡县",
+ "520624": "思南县",
+ "520625": "印江土家族苗族自治县",
+ "520626": "德江县",
+ "520627": "沿河土家族自治县",
+ "520628": "松桃苗族自治县",
+ "522301": "兴义市",
+ "522302": "兴仁市",
+ "522323": "普安县",
+ "522324": "晴隆县",
+ "522325": "贞丰县",
+ "522326": "望谟县",
+ "522327": "册亨县",
+ "522328": "安龙县",
+ "522601": "凯里市",
+ "522622": "黄平县",
+ "522623": "施秉县",
+ "522624": "三穗县",
+ "522625": "镇远县",
+ "522626": "岑巩县",
+ "522627": "天柱县",
+ "522628": "锦屏县",
+ "522629": "剑河县",
+ "522630": "台江县",
+ "522631": "黎平县",
+ "522632": "榕江县",
+ "522633": "从江县",
+ "522634": "雷山县",
+ "522635": "麻江县",
+ "522636": "丹寨县",
+ "522701": "都匀市",
+ "522702": "福泉市",
+ "522722": "荔波县",
+ "522723": "贵定县",
+ "522725": "瓮安县",
+ "522726": "独山县",
+ "522727": "平塘县",
+ "522728": "罗甸县",
+ "522729": "长顺县",
+ "522730": "龙里县",
+ "522731": "惠水县",
+ "522732": "三都水族自治县",
+ "530102": "五华区",
+ "530103": "盘龙区",
+ "530111": "官渡区",
+ "530112": "西山区",
+ "530113": "东川区",
+ "530114": "呈贡区",
+ "530115": "晋宁区",
+ "530124": "富民县",
+ "530125": "宜良县",
+ "530126": "石林彝族自治县",
+ "530127": "嵩明县",
+ "530128": "禄劝彝族苗族自治县",
+ "530129": "寻甸回族彝族自治县",
+ "530181": "安宁市",
+ "530302": "麒麟区",
+ "530303": "沾益区",
+ "530304": "马龙区",
+ "530322": "陆良县",
+ "530323": "师宗县",
+ "530324": "罗平县",
+ "530325": "富源县",
+ "530326": "会泽县",
+ "530381": "宣威市",
+ "530402": "红塔区",
+ "530403": "江川区",
+ "530423": "通海县",
+ "530424": "华宁县",
+ "530425": "易门县",
+ "530426": "峨山彝族自治县",
+ "530427": "新平彝族傣族自治县",
+ "530428": "元江哈尼族彝族傣族自治县",
+ "530481": "澄江市",
+ "530502": "隆阳区",
+ "530521": "施甸县",
+ "530523": "龙陵县",
+ "530524": "昌宁县",
+ "530581": "腾冲市",
+ "530602": "昭阳区",
+ "530621": "鲁甸县",
+ "530622": "巧家县",
+ "530623": "盐津县",
+ "530624": "大关县",
+ "530625": "永善县",
+ "530626": "绥江县",
+ "530627": "镇雄县",
+ "530628": "彝良县",
+ "530629": "威信县",
+ "530681": "水富市",
+ "530702": "古城区",
+ "530721": "玉龙纳西族自治县",
+ "530722": "永胜县",
+ "530723": "华坪县",
+ "530724": "宁蒗彝族自治县",
+ "530802": "思茅区",
+ "530821": "宁洱哈尼族彝族自治县",
+ "530822": "墨江哈尼族自治县",
+ "530823": "景东彝族自治县",
+ "530824": "景谷傣族彝族自治县",
+ "530825": "镇沅彝族哈尼族拉祜族自治县",
+ "530826": "江城哈尼族彝族自治县",
+ "530827": "孟连傣族拉祜族佤族自治县",
+ "530828": "澜沧拉祜族自治县",
+ "530829": "西盟佤族自治县",
+ "530902": "临翔区",
+ "530921": "凤庆县",
+ "530922": "云县",
+ "530923": "永德县",
+ "530924": "镇康县",
+ "530925": "双江拉祜族佤族布朗族傣族自治县",
+ "530926": "耿马傣族佤族自治县",
+ "530927": "沧源佤族自治县",
+ "532301": "楚雄市",
+ "532302": "禄丰市",
+ "532322": "双柏县",
+ "532323": "牟定县",
+ "532324": "南华县",
+ "532325": "姚安县",
+ "532326": "大姚县",
+ "532327": "永仁县",
+ "532328": "元谋县",
+ "532329": "武定县",
+ "532501": "个旧市",
+ "532502": "开远市",
+ "532503": "蒙自市",
+ "532504": "弥勒市",
+ "532523": "屏边苗族自治县",
+ "532524": "建水县",
+ "532525": "石屏县",
+ "532527": "泸西县",
+ "532528": "元阳县",
+ "532529": "红河县",
+ "532530": "金平苗族瑶族傣族自治县",
+ "532531": "绿春县",
+ "532532": "河口瑶族自治县",
+ "532601": "文山市",
+ "532622": "砚山县",
+ "532623": "西畴县",
+ "532624": "麻栗坡县",
+ "532625": "马关县",
+ "532626": "丘北县",
+ "532627": "广南县",
+ "532628": "富宁县",
+ "532801": "景洪市",
+ "532822": "勐海县",
+ "532823": "勐腊县",
+ "532901": "大理市",
+ "532922": "漾濞彝族自治县",
+ "532923": "祥云县",
+ "532924": "宾川县",
+ "532925": "弥渡县",
+ "532926": "南涧彝族自治县",
+ "532927": "巍山彝族回族自治县",
+ "532928": "永平县",
+ "532929": "云龙县",
+ "532930": "洱源县",
+ "532931": "剑川县",
+ "532932": "鹤庆县",
+ "533102": "瑞丽市",
+ "533103": "芒市",
+ "533122": "梁河县",
+ "533123": "盈江县",
+ "533124": "陇川县",
+ "533301": "泸水市",
+ "533323": "福贡县",
+ "533324": "贡山独龙族怒族自治县",
+ "533325": "兰坪白族普米族自治县",
+ "533401": "香格里拉市",
+ "533422": "德钦县",
+ "533423": "维西傈僳族自治县",
+ "540102": "城关区",
+ "540103": "堆龙德庆区",
+ "540104": "达孜区",
+ "540121": "林周县",
+ "540122": "当雄县",
+ "540123": "尼木县",
+ "540124": "曲水县",
+ "540127": "墨竹工卡县",
+ "540202": "桑珠孜区",
+ "540221": "南木林县",
+ "540222": "江孜县",
+ "540223": "定日县",
+ "540224": "萨迦县",
+ "540225": "拉孜县",
+ "540226": "昂仁县",
+ "540227": "谢通门县",
+ "540228": "白朗县",
+ "540229": "仁布县",
+ "540230": "康马县",
+ "540231": "定结县",
+ "540232": "仲巴县",
+ "540233": "亚东县",
+ "540234": "吉隆县",
+ "540235": "聂拉木县",
+ "540236": "萨嘎县",
+ "540237": "岗巴县",
+ "540302": "卡若区",
+ "540321": "江达县",
+ "540322": "贡觉县",
+ "540323": "类乌齐县",
+ "540324": "丁青县",
+ "540325": "察雅县",
+ "540326": "八宿县",
+ "540327": "左贡县",
+ "540328": "芒康县",
+ "540329": "洛隆县",
+ "540330": "边坝县",
+ "540402": "巴宜区",
+ "540421": "工布江达县",
+ "540423": "墨脱县",
+ "540424": "波密县",
+ "540425": "察隅县",
+ "540426": "朗县",
+ "540481": "米林市",
+ "540502": "乃东区",
+ "540521": "扎囊县",
+ "540522": "贡嘎县",
+ "540523": "桑日县",
+ "540524": "琼结县",
+ "540525": "曲松县",
+ "540526": "措美县",
+ "540527": "洛扎县",
+ "540528": "加查县",
+ "540529": "隆子县",
+ "540531": "浪卡子县",
+ "540581": "错那市",
+ "540602": "色尼区",
+ "540621": "嘉黎县",
+ "540622": "比如县",
+ "540623": "聂荣县",
+ "540624": "安多县",
+ "540625": "申扎县",
+ "540626": "索县",
+ "540627": "班戈县",
+ "540628": "巴青县",
+ "540629": "尼玛县",
+ "540630": "双湖县",
+ "542521": "普兰县",
+ "542522": "札达县",
+ "542523": "噶尔县",
+ "542524": "日土县",
+ "542525": "革吉县",
+ "542526": "改则县",
+ "542527": "措勤县",
+ "610102": "新城区",
+ "610103": "碑林区",
+ "610104": "莲湖区",
+ "610111": "灞桥区",
+ "610112": "未央区",
+ "610113": "雁塔区",
+ "610114": "阎良区",
+ "610115": "临潼区",
+ "610116": "长安区",
+ "610117": "高陵区",
+ "610118": "鄠邑区",
+ "610122": "蓝田县",
+ "610124": "周至县",
+ "610202": "王益区",
+ "610203": "印台区",
+ "610204": "耀州区",
+ "610222": "宜君县",
+ "610302": "渭滨区",
+ "610303": "金台区",
+ "610304": "陈仓区",
+ "610305": "凤翔区",
+ "610323": "岐山县",
+ "610324": "扶风县",
+ "610326": "眉县",
+ "610327": "陇县",
+ "610328": "千阳县",
+ "610329": "麟游县",
+ "610330": "凤县",
+ "610331": "太白县",
+ "610402": "秦都区",
+ "610403": "杨陵区",
+ "610404": "渭城区",
+ "610422": "三原县",
+ "610423": "泾阳县",
+ "610424": "乾县",
+ "610425": "礼泉县",
+ "610426": "永寿县",
+ "610428": "长武县",
+ "610429": "旬邑县",
+ "610430": "淳化县",
+ "610431": "武功县",
+ "610481": "兴平市",
+ "610482": "彬州市",
+ "610502": "临渭区",
+ "610503": "华州区",
+ "610522": "潼关县",
+ "610523": "大荔县",
+ "610524": "合阳县",
+ "610525": "澄城县",
+ "610526": "蒲城县",
+ "610527": "白水县",
+ "610528": "富平县",
+ "610581": "韩城市",
+ "610582": "华阴市",
+ "610602": "宝塔区",
+ "610603": "安塞区",
+ "610621": "延长县",
+ "610622": "延川县",
+ "610625": "志丹县",
+ "610626": "吴起县",
+ "610627": "甘泉县",
+ "610628": "富县",
+ "610629": "洛川县",
+ "610630": "宜川县",
+ "610631": "黄龙县",
+ "610632": "黄陵县",
+ "610681": "子长市",
+ "610702": "汉台区",
+ "610703": "南郑区",
+ "610722": "城固县",
+ "610723": "洋县",
+ "610724": "西乡县",
+ "610725": "勉县",
+ "610726": "宁强县",
+ "610727": "略阳县",
+ "610728": "镇巴县",
+ "610729": "留坝县",
+ "610730": "佛坪县",
+ "610802": "榆阳区",
+ "610803": "横山区",
+ "610822": "府谷县",
+ "610824": "靖边县",
+ "610825": "定边县",
+ "610826": "绥德县",
+ "610827": "米脂县",
+ "610828": "佳县",
+ "610829": "吴堡县",
+ "610830": "清涧县",
+ "610831": "子洲县",
+ "610881": "神木市",
+ "610902": "汉滨区",
+ "610921": "汉阴县",
+ "610922": "石泉县",
+ "610923": "宁陕县",
+ "610924": "紫阳县",
+ "610925": "岚皋县",
+ "610926": "平利县",
+ "610927": "镇坪县",
+ "610929": "白河县",
+ "610981": "旬阳市",
+ "611002": "商州区",
+ "611021": "洛南县",
+ "611022": "丹凤县",
+ "611023": "商南县",
+ "611024": "山阳县",
+ "611025": "镇安县",
+ "611026": "柞水县",
+ "620102": "城关区",
+ "620103": "七里河区",
+ "620104": "西固区",
+ "620105": "安宁区",
+ "620111": "红古区",
+ "620121": "永登县",
+ "620122": "皋兰县",
+ "620123": "榆中县",
+ "620171": "兰州新区",
+ "620201": "市辖区",
+ "620290": "雄关区",
+ "620291": "长城区",
+ "620292": "镜铁区",
+ "620293": "新城镇",
+ "620294": "峪泉镇",
+ "620295": "文殊镇",
+ "620302": "金川区",
+ "620321": "永昌县",
+ "620402": "白银区",
+ "620403": "平川区",
+ "620421": "靖远县",
+ "620422": "会宁县",
+ "620423": "景泰县",
+ "620502": "秦州区",
+ "620503": "麦积区",
+ "620521": "清水县",
+ "620522": "秦安县",
+ "620523": "甘谷县",
+ "620524": "武山县",
+ "620525": "张家川回族自治县",
+ "620602": "凉州区",
+ "620621": "民勤县",
+ "620622": "古浪县",
+ "620623": "天祝藏族自治县",
+ "620702": "甘州区",
+ "620721": "肃南裕固族自治县",
+ "620722": "民乐县",
+ "620723": "临泽县",
+ "620724": "高台县",
+ "620725": "山丹县",
+ "620802": "崆峒区",
+ "620821": "泾川县",
+ "620822": "灵台县",
+ "620823": "崇信县",
+ "620825": "庄浪县",
+ "620826": "静宁县",
+ "620881": "华亭市",
+ "620902": "肃州区",
+ "620921": "金塔县",
+ "620922": "瓜州县",
+ "620923": "肃北蒙古族自治县",
+ "620924": "阿克塞哈萨克族自治县",
+ "620981": "玉门市",
+ "620982": "敦煌市",
+ "621002": "西峰区",
+ "621021": "庆城县",
+ "621022": "环县",
+ "621023": "华池县",
+ "621024": "合水县",
+ "621025": "正宁县",
+ "621026": "宁县",
+ "621027": "镇原县",
+ "621102": "安定区",
+ "621121": "通渭县",
+ "621122": "陇西县",
+ "621123": "渭源县",
+ "621124": "临洮县",
+ "621125": "漳县",
+ "621126": "岷县",
+ "621202": "武都区",
+ "621221": "成县",
+ "621222": "文县",
+ "621223": "宕昌县",
+ "621224": "康县",
+ "621225": "西和县",
+ "621226": "礼县",
+ "621227": "徽县",
+ "621228": "两当县",
+ "622901": "临夏市",
+ "622921": "临夏县",
+ "622922": "康乐县",
+ "622923": "永靖县",
+ "622924": "广河县",
+ "622925": "和政县",
+ "622926": "东乡族自治县",
+ "622927": "积石山保安族东乡族撒拉族自治县",
+ "623001": "合作市",
+ "623021": "临潭县",
+ "623022": "卓尼县",
+ "623023": "舟曲县",
+ "623024": "迭部县",
+ "623025": "玛曲县",
+ "623026": "碌曲县",
+ "623027": "夏河县",
+ "630102": "城东区",
+ "630103": "城中区",
+ "630104": "城西区",
+ "630105": "城北区",
+ "630106": "湟中区",
+ "630121": "大通回族土族自治县",
+ "630123": "湟源县",
+ "630202": "乐都区",
+ "630203": "平安区",
+ "630222": "民和回族土族自治县",
+ "630223": "互助土族自治县",
+ "630224": "化隆回族自治县",
+ "630225": "循化撒拉族自治县",
+ "632221": "门源回族自治县",
+ "632222": "祁连县",
+ "632223": "海晏县",
+ "632224": "刚察县",
+ "632301": "同仁市",
+ "632322": "尖扎县",
+ "632323": "泽库县",
+ "632324": "河南蒙古族自治县",
+ "632521": "共和县",
+ "632522": "同德县",
+ "632523": "贵德县",
+ "632524": "兴海县",
+ "632525": "贵南县",
+ "632621": "玛沁县",
+ "632622": "班玛县",
+ "632623": "甘德县",
+ "632624": "达日县",
+ "632625": "久治县",
+ "632626": "玛多县",
+ "632701": "玉树市",
+ "632722": "杂多县",
+ "632723": "称多县",
+ "632724": "治多县",
+ "632725": "囊谦县",
+ "632726": "曲麻莱县",
+ "632801": "格尔木市",
+ "632802": "德令哈市",
+ "632803": "茫崖市",
+ "632821": "乌兰县",
+ "632822": "都兰县",
+ "632823": "天峻县",
+ "632857": "大柴旦行政委员会",
+ "640104": "兴庆区",
+ "640105": "西夏区",
+ "640106": "金凤区",
+ "640121": "永宁县",
+ "640122": "贺兰县",
+ "640181": "灵武市",
+ "640202": "大武口区",
+ "640205": "惠农区",
+ "640221": "平罗县",
+ "640302": "利通区",
+ "640303": "红寺堡区",
+ "640323": "盐池县",
+ "640324": "同心县",
+ "640381": "青铜峡市",
+ "640402": "原州区",
+ "640422": "西吉县",
+ "640423": "隆德县",
+ "640424": "泾源县",
+ "640425": "彭阳县",
+ "640502": "沙坡头区",
+ "640521": "中宁县",
+ "640522": "海原县",
+ "650102": "天山区",
+ "650103": "沙依巴克区",
+ "650104": "新市区",
+ "650105": "水磨沟区",
+ "650106": "头屯河区",
+ "650107": "达坂城区",
+ "650109": "米东区",
+ "650121": "乌鲁木齐县",
+ "650202": "独山子区",
+ "650203": "克拉玛依区",
+ "650204": "白碱滩区",
+ "650205": "乌尔禾区",
+ "650402": "高昌区",
+ "650421": "鄯善县",
+ "650422": "托克逊县",
+ "650502": "伊州区",
+ "650521": "巴里坤哈萨克自治县",
+ "650522": "伊吾县",
+ "652301": "昌吉市",
+ "652302": "阜康市",
+ "652323": "呼图壁县",
+ "652324": "玛纳斯县",
+ "652325": "奇台县",
+ "652327": "吉木萨尔县",
+ "652328": "木垒哈萨克自治县",
+ "652701": "博乐市",
+ "652702": "阿拉山口市",
+ "652722": "精河县",
+ "652723": "温泉县",
+ "652801": "库尔勒市",
+ "652822": "轮台县",
+ "652823": "尉犁县",
+ "652824": "若羌县",
+ "652825": "且末县",
+ "652826": "焉耆回族自治县",
+ "652827": "和静县",
+ "652828": "和硕县",
+ "652829": "博湖县",
+ "652901": "阿克苏市",
+ "652902": "库车市",
+ "652922": "温宿县",
+ "652924": "沙雅县",
+ "652925": "新和县",
+ "652926": "拜城县",
+ "652927": "乌什县",
+ "652928": "阿瓦提县",
+ "652929": "柯坪县",
+ "653001": "阿图什市",
+ "653022": "阿克陶县",
+ "653023": "阿合奇县",
+ "653024": "乌恰县",
+ "653101": "喀什市",
+ "653121": "疏附县",
+ "653122": "疏勒县",
+ "653123": "英吉沙县",
+ "653124": "泽普县",
+ "653125": "莎车县",
+ "653126": "叶城县",
+ "653127": "麦盖提县",
+ "653128": "岳普湖县",
+ "653129": "伽师县",
+ "653130": "巴楚县",
+ "653131": "塔什库尔干塔吉克自治县",
+ "653201": "和田市",
+ "653221": "和田县",
+ "653222": "墨玉县",
+ "653223": "皮山县",
+ "653224": "洛浦县",
+ "653225": "策勒县",
+ "653226": "于田县",
+ "653227": "民丰县",
+ "654002": "伊宁市",
+ "654003": "奎屯市",
+ "654004": "霍尔果斯市",
+ "654021": "伊宁县",
+ "654022": "察布查尔锡伯自治县",
+ "654023": "霍城县",
+ "654024": "巩留县",
+ "654025": "新源县",
+ "654026": "昭苏县",
+ "654027": "特克斯县",
+ "654028": "尼勒克县",
+ "654201": "塔城市",
+ "654202": "乌苏市",
+ "654203": "沙湾市",
+ "654221": "额敏县",
+ "654224": "托里县",
+ "654225": "裕民县",
+ "654226": "和布克赛尔蒙古自治县",
+ "654301": "阿勒泰市",
+ "654321": "布尔津县",
+ "654322": "富蕴县",
+ "654323": "福海县",
+ "654324": "哈巴河县",
+ "654325": "青河县",
+ "654326": "吉木乃县",
+ "659001": "石河子市",
+ "659002": "阿拉尔市",
+ "659003": "图木舒克市",
+ "659004": "五家渠市",
+ "659005": "北屯市",
+ "659006": "铁门关市",
+ "659007": "双河市",
+ "659008": "可克达拉市",
+ "659009": "昆玉市",
+ "659010": "胡杨河市",
+ "659011": "新星市",
+ "659012": "白杨市",
+ "710101": "中正区",
+ "710102": "大同区",
+ "710103": "中山区",
+ "710104": "松山区",
+ "710105": "大安区",
+ "710106": "万华区",
+ "710107": "信义区",
+ "710108": "士林区",
+ "710109": "北投区",
+ "710110": "内湖区",
+ "710111": "南港区",
+ "710112": "文山区",
+ "710199": "其它区",
+ "710201": "新兴区",
+ "710202": "前金区",
+ "710203": "芩雅区",
+ "710204": "盐埕区",
+ "710205": "鼓山区",
+ "710206": "旗津区",
+ "710207": "前镇区",
+ "710208": "三民区",
+ "710209": "左营区",
+ "710210": "楠梓区",
+ "710211": "小港区",
+ "710241": "苓雅区",
+ "710242": "仁武区",
+ "710243": "大社区",
+ "710244": "冈山区",
+ "710245": "路竹区",
+ "710246": "阿莲区",
+ "710247": "田寮区",
+ "710248": "燕巢区",
+ "710249": "桥头区",
+ "710250": "梓官区",
+ "710251": "弥陀区",
+ "710252": "永安区",
+ "710253": "湖内区",
+ "710254": "凤山区",
+ "710255": "大寮区",
+ "710256": "林园区",
+ "710257": "鸟松区",
+ "710258": "大树区",
+ "710259": "旗山区",
+ "710260": "美浓区",
+ "710261": "六龟区",
+ "710262": "内门区",
+ "710263": "杉林区",
+ "710264": "甲仙区",
+ "710265": "桃源区",
+ "710266": "那玛夏区",
+ "710267": "茂林区",
+ "710268": "茄萣区",
+ "710299": "其它区",
+ "710301": "中西区",
+ "710302": "东区",
+ "710303": "南区",
+ "710304": "北区",
+ "710305": "安平区",
+ "710306": "安南区",
+ "710339": "永康区",
+ "710340": "归仁区",
+ "710341": "新化区",
+ "710342": "左镇区",
+ "710343": "玉井区",
+ "710344": "楠西区",
+ "710345": "南化区",
+ "710346": "仁德区",
+ "710347": "关庙区",
+ "710348": "龙崎区",
+ "710349": "官田区",
+ "710350": "麻豆区",
+ "710351": "佳里区",
+ "710352": "西港区",
+ "710353": "七股区",
+ "710354": "将军区",
+ "710355": "学甲区",
+ "710356": "北门区",
+ "710357": "新营区",
+ "710358": "后壁区",
+ "710359": "白河区",
+ "710360": "东山区",
+ "710361": "六甲区",
+ "710362": "下营区",
+ "710363": "柳营区",
+ "710364": "盐水区",
+ "710365": "善化区",
+ "710366": "大内区",
+ "710367": "山上区",
+ "710368": "新市区",
+ "710369": "安定区",
+ "710399": "其它区",
+ "710401": "中区",
+ "710402": "东区",
+ "710403": "南区",
+ "710404": "西区",
+ "710405": "北区",
+ "710406": "北屯区",
+ "710407": "西屯区",
+ "710408": "南屯区",
+ "710431": "太平区",
+ "710432": "大里区",
+ "710433": "雾峰区",
+ "710434": "乌日区",
+ "710435": "丰原区",
+ "710436": "后里区",
+ "710437": "石冈区",
+ "710438": "东势区",
+ "710439": "和平区",
+ "710440": "新社区",
+ "710441": "潭子区",
+ "710442": "大雅区",
+ "710443": "神冈区",
+ "710444": "大肚区",
+ "710445": "沙鹿区",
+ "710446": "龙井区",
+ "710447": "梧栖区",
+ "710448": "清水区",
+ "710449": "大甲区",
+ "710450": "外埔区",
+ "710451": "大安区",
+ "710499": "其它区",
+ "710507": "金沙镇",
+ "710508": "金湖镇",
+ "710509": "金宁乡",
+ "710510": "金城镇",
+ "710511": "烈屿乡",
+ "710512": "乌坵乡",
+ "710614": "南投市",
+ "710615": "中寮乡",
+ "710616": "草屯镇",
+ "710617": "国姓乡",
+ "710618": "埔里镇",
+ "710619": "仁爱乡",
+ "710620": "名间乡",
+ "710621": "集集镇",
+ "710622": "水里乡",
+ "710623": "鱼池乡",
+ "710624": "信义乡",
+ "710625": "竹山镇",
+ "710626": "鹿谷乡",
+ "710701": "仁爱区",
+ "710702": "信义区",
+ "710703": "中正区",
+ "710704": "中山区",
+ "710705": "安乐区",
+ "710706": "暖暖区",
+ "710707": "七堵区",
+ "710799": "其它区",
+ "710801": "东区",
+ "710802": "北区",
+ "710803": "香山区",
+ "710899": "其它区",
+ "710901": "东区",
+ "710902": "西区",
+ "710999": "其它区",
+ "711130": "万里区",
+ "711132": "板桥区",
+ "711133": "汐止区",
+ "711134": "深坑区",
+ "711135": "石碇区",
+ "711136": "瑞芳区",
+ "711137": "平溪区",
+ "711138": "双溪区",
+ "711139": "贡寮区",
+ "711140": "新店区",
+ "711141": "坪林区",
+ "711142": "乌来区",
+ "711143": "永和区",
+ "711144": "中和区",
+ "711145": "土城区",
+ "711146": "三峡区",
+ "711147": "树林区",
+ "711148": "莺歌区",
+ "711149": "三重区",
+ "711150": "新庄区",
+ "711151": "泰山区",
+ "711152": "林口区",
+ "711153": "芦洲区",
+ "711154": "五股区",
+ "711155": "八里区",
+ "711156": "淡水区",
+ "711157": "三芝区",
+ "711158": "石门区",
+ "711287": "宜兰市",
+ "711288": "头城镇",
+ "711289": "礁溪乡",
+ "711290": "壮围乡",
+ "711291": "员山乡",
+ "711292": "罗东镇",
+ "711293": "三星乡",
+ "711294": "大同乡",
+ "711295": "五结乡",
+ "711296": "冬山乡",
+ "711297": "苏澳镇",
+ "711298": "南澳乡",
+ "711299": "钓鱼台",
+ "711387": "竹北市",
+ "711388": "湖口乡",
+ "711389": "新丰乡",
+ "711390": "新埔镇",
+ "711391": "关西镇",
+ "711392": "芎林乡",
+ "711393": "宝山乡",
+ "711394": "竹东镇",
+ "711395": "五峰乡",
+ "711396": "横山乡",
+ "711397": "尖石乡",
+ "711398": "北埔乡",
+ "711399": "峨眉乡",
+ "711414": "中坜区",
+ "711415": "平镇区",
+ "711417": "杨梅区",
+ "711418": "新屋区",
+ "711419": "观音区",
+ "711420": "桃园区",
+ "711421": "龟山区",
+ "711422": "八德区",
+ "711423": "大溪区",
+ "711425": "大园区",
+ "711426": "芦竹区",
+ "711487": "中坜市",
+ "711488": "平镇市",
+ "711489": "龙潭乡",
+ "711490": "杨梅市",
+ "711491": "新屋乡",
+ "711492": "观音乡",
+ "711493": "桃园市",
+ "711494": "龟山乡",
+ "711495": "八德市",
+ "711496": "大溪镇",
+ "711497": "复兴乡",
+ "711498": "大园乡",
+ "711499": "芦竹乡",
+ "711520": "头份市",
+ "711582": "竹南镇",
+ "711583": "头份镇",
+ "711584": "三湾乡",
+ "711585": "南庄乡",
+ "711586": "狮潭乡",
+ "711587": "后龙镇",
+ "711588": "通霄镇",
+ "711589": "苑里镇",
+ "711590": "苗栗市",
+ "711591": "造桥乡",
+ "711592": "头屋乡",
+ "711593": "公馆乡",
+ "711594": "大湖乡",
+ "711595": "泰安乡",
+ "711596": "铜锣乡",
+ "711597": "三义乡",
+ "711598": "西湖乡",
+ "711599": "卓兰镇",
+ "711736": "员林市",
+ "711774": "彰化市",
+ "711775": "芬园乡",
+ "711776": "花坛乡",
+ "711777": "秀水乡",
+ "711778": "鹿港镇",
+ "711779": "福兴乡",
+ "711780": "线西乡",
+ "711781": "和美镇",
+ "711782": "伸港乡",
+ "711783": "员林镇",
+ "711784": "社头乡",
+ "711785": "永靖乡",
+ "711786": "埔心乡",
+ "711787": "溪湖镇",
+ "711788": "大村乡",
+ "711789": "埔盐乡",
+ "711790": "田中镇",
+ "711791": "北斗镇",
+ "711792": "田尾乡",
+ "711793": "埤头乡",
+ "711794": "溪州乡",
+ "711795": "竹塘乡",
+ "711796": "二林镇",
+ "711797": "大城乡",
+ "711798": "芳苑乡",
+ "711799": "二水乡",
+ "711982": "番路乡",
+ "711983": "梅山乡",
+ "711984": "竹崎乡",
+ "711985": "阿里山乡",
+ "711986": "中埔乡",
+ "711987": "大埔乡",
+ "711988": "水上乡",
+ "711989": "鹿草乡",
+ "711990": "太保市",
+ "711991": "朴子市",
+ "711992": "东石乡",
+ "711993": "六脚乡",
+ "711994": "新港乡",
+ "711995": "民雄乡",
+ "711996": "大林镇",
+ "711997": "溪口乡",
+ "711998": "义竹乡",
+ "711999": "布袋镇",
+ "712180": "斗南镇",
+ "712181": "大埤乡",
+ "712182": "虎尾镇",
+ "712183": "土库镇",
+ "712184": "褒忠乡",
+ "712185": "东势乡",
+ "712186": "台西乡",
+ "712187": "仑背乡",
+ "712188": "麦寮乡",
+ "712189": "斗六市",
+ "712190": "林内乡",
+ "712191": "古坑乡",
+ "712192": "莿桐乡",
+ "712193": "西螺镇",
+ "712194": "二仑乡",
+ "712195": "北港镇",
+ "712196": "水林乡",
+ "712197": "口湖乡",
+ "712198": "四湖乡",
+ "712199": "元长乡",
+ "712451": "崁顶乡",
+ "712467": "屏东市",
+ "712468": "三地门乡",
+ "712469": "雾台乡",
+ "712470": "玛家乡",
+ "712471": "九如乡",
+ "712472": "里港乡",
+ "712473": "高树乡",
+ "712474": "盐埔乡",
+ "712475": "长治乡",
+ "712476": "麟洛乡",
+ "712477": "竹田乡",
+ "712478": "内埔乡",
+ "712479": "万丹乡",
+ "712480": "潮州镇",
+ "712481": "泰武乡",
+ "712482": "来义乡",
+ "712483": "万峦乡",
+ "712484": "莰顶乡",
+ "712485": "新埤乡",
+ "712486": "南州乡",
+ "712487": "林边乡",
+ "712488": "东港镇",
+ "712489": "琉球乡",
+ "712490": "佳冬乡",
+ "712491": "新园乡",
+ "712492": "枋寮乡",
+ "712493": "枋山乡",
+ "712494": "春日乡",
+ "712495": "狮子乡",
+ "712496": "车城乡",
+ "712497": "牡丹乡",
+ "712498": "恒春镇",
+ "712499": "满州乡",
+ "712584": "台东市",
+ "712585": "绿岛乡",
+ "712586": "兰屿乡",
+ "712587": "延平乡",
+ "712588": "卑南乡",
+ "712589": "鹿野乡",
+ "712590": "关山镇",
+ "712591": "海端乡",
+ "712592": "池上乡",
+ "712593": "东河乡",
+ "712594": "成功镇",
+ "712595": "长滨乡",
+ "712596": "金峰乡",
+ "712597": "大武乡",
+ "712598": "达仁乡",
+ "712599": "太麻里乡",
+ "712686": "花莲市",
+ "712687": "新城乡",
+ "712688": "太鲁阁",
+ "712689": "秀林乡",
+ "712690": "吉安乡",
+ "712691": "寿丰乡",
+ "712692": "凤林镇",
+ "712693": "光复乡",
+ "712694": "丰滨乡",
+ "712695": "瑞穗乡",
+ "712696": "万荣乡",
+ "712697": "玉里镇",
+ "712698": "卓溪乡",
+ "712699": "富里乡",
+ "712794": "马公市",
+ "712795": "西屿乡",
+ "712796": "望安乡",
+ "712797": "七美乡",
+ "712798": "白沙乡",
+ "712799": "湖西乡",
+ "712896": "南竿乡",
+ "712897": "北竿乡",
+ "712898": "东引乡",
+ "712899": "莒光乡",
+ "810101": "中西区",
+ "810102": "湾仔区",
+ "810103": "东区",
+ "810104": "南区",
+ "810201": "九龙城区",
+ "810202": "油尖旺区",
+ "810203": "深水埗区",
+ "810204": "黄大仙区",
+ "810205": "观塘区",
+ "810301": "北区",
+ "810302": "大埔区",
+ "810303": "沙田区",
+ "810304": "西贡区",
+ "810305": "元朗区",
+ "810306": "屯门区",
+ "810307": "荃湾区",
+ "810308": "葵青区",
+ "810309": "离岛区",
+ "820102": "花地玛堂区",
+ "820103": "花王堂区",
+ "820104": "望德堂区",
+ "820105": "大堂区",
+ "820106": "风顺堂区",
+ "820202": "嘉模堂区",
+ "820203": "路氹填海区",
+ "820204": "圣方济各堂区"
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/areaData/index.ts b/src/uni_modules/lime-shared/areaData/index.ts
new file mode 100644
index 0000000..401f77f
--- /dev/null
+++ b/src/uni_modules/lime-shared/areaData/index.ts
@@ -0,0 +1,71 @@
+// @ts-nocheck
+import _areaList from './city-china.json';
+export const areaList = _areaList
+// #ifndef UNI-APP-X
+type UTSJSONObject = Record
+// #endif
+// #ifdef UNI-APP-X
+type Object = UTSJSONObject
+// #endif
+type AreaList = {
+ province_list : Map;
+ city_list : Map;
+ county_list : Map;
+}
+// type CascaderOption = {
+// text : string;
+// value : string;
+// children ?: CascaderOption[];
+// };
+
+const makeOption = (
+ label : string,
+ value : string,
+ children ?: UTSJSONObject[],
+) : UTSJSONObject => ({
+ label,
+ value,
+ children,
+});
+
+
+
+export function useCascaderAreaData() : UTSJSONObject[] {
+ const city = areaList['city_list'] as UTSJSONObject
+ const county = areaList['county_list'] as UTSJSONObject
+ const province = areaList['province_list'] as UTSJSONObject
+ const provinceMap = new Map();
+ Object.keys(province).forEach((code) => {
+ provinceMap.set(code.slice(0, 2), makeOption(`${province[code]}`, code, []));
+ });
+
+ const cityMap = new Map();
+
+ Object.keys(city).forEach((code) => {
+ const option = makeOption(`${city[code]}`, code, []);
+ cityMap.set(code.slice(0, 4), option);
+
+ const _province = provinceMap.get(code.slice(0, 2));
+ if (_province != null) {
+ (_province['children'] as UTSJSONObject[]).push(option)
+ }
+ });
+
+ Object.keys(county).forEach((code) => {
+ const _city = cityMap.get(code.slice(0, 4));
+ if (_city != null) {
+ (_city['children'] as UTSJSONObject[]).push(makeOption(`${county[code]}`, code, null));
+ }
+ });
+
+ // #ifndef APP-ANDROID || APP-IOS
+ return Array.from(provinceMap.values());
+ // #endif
+ // #ifdef APP-ANDROID || APP-IOS
+ const obj : UTSJSONObject[] = []
+ provinceMap.forEach((value, code) => {
+ obj.push(value)
+ })
+ return obj
+ // #endif
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/arrayBufferToFile/index.ts b/src/uni_modules/lime-shared/arrayBufferToFile/index.ts
new file mode 100644
index 0000000..49ee530
--- /dev/null
+++ b/src/uni_modules/lime-shared/arrayBufferToFile/index.ts
@@ -0,0 +1,8 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/arrayBufferToFile/uvue.uts b/src/uni_modules/lime-shared/arrayBufferToFile/uvue.uts
new file mode 100644
index 0000000..65c7b14
--- /dev/null
+++ b/src/uni_modules/lime-shared/arrayBufferToFile/uvue.uts
@@ -0,0 +1,10 @@
+// @ts-nocheck
+// import {platform} from '../platform'
+/**
+ * buffer转路径
+ * @param {Object} buffer
+ */
+// @ts-nocheck
+export function arrayBufferToFile(buffer: ArrayBuffer, name?: string, format?:string):Promise<(File|string)> {
+ console.error('[arrayBufferToFile] 当前环境不支持')
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/arrayBufferToFile/vue.ts b/src/uni_modules/lime-shared/arrayBufferToFile/vue.ts
new file mode 100644
index 0000000..9760b20
--- /dev/null
+++ b/src/uni_modules/lime-shared/arrayBufferToFile/vue.ts
@@ -0,0 +1,63 @@
+// @ts-nocheck
+import {platform} from '../platform'
+/**
+ * buffer转路径
+ * @param {Object} buffer
+ */
+// @ts-nocheck
+export function arrayBufferToFile(buffer: ArrayBuffer | Blob, name?: string, format?:string):Promise<(File|string)> {
+ return new Promise((resolve, reject) => {
+ // #ifdef MP
+ const fs = uni.getFileSystemManager()
+ //自定义文件名
+ if (!name && !format) {
+ reject(new Error('ERROR_NAME_PARSE'))
+ }
+ const fileName = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
+ let pre = platform()
+ const filePath = `${pre.env.USER_DATA_PATH}/${fileName}`
+ fs.writeFile({
+ filePath,
+ data: buffer,
+ success() {
+ resolve(filePath)
+ },
+ fail(err) {
+ console.error(err)
+ reject(err)
+ }
+ })
+ // #endif
+
+ // #ifdef H5
+ const file = new File([buffer], name, {
+ type: format,
+ });
+ resolve(file)
+ // #endif
+
+ // #ifdef APP-PLUS
+ const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+ const base64 = uni.arrayBufferToBase64(buffer)
+ bitmap.loadBase64Data(base64, () => {
+ if (!name && !format) {
+ reject(new Error('ERROR_NAME_PARSE'))
+ }
+ const fileNmae = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
+ const filePath = `_doc/uniapp_temp/${fileNmae}`
+ bitmap.save(filePath, {},
+ () => {
+ bitmap.clear()
+ resolve(filePath)
+ },
+ (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ }, (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ // #endif
+ })
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/base64ToArrayBuffer/index.ts b/src/uni_modules/lime-shared/base64ToArrayBuffer/index.ts
new file mode 100644
index 0000000..f83b640
--- /dev/null
+++ b/src/uni_modules/lime-shared/base64ToArrayBuffer/index.ts
@@ -0,0 +1,13 @@
+// @ts-nocheck
+// 未完成
+export function base64ToArrayBuffer(base64 : string) {
+ const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64) || [];
+ if (!format) {
+ new Error('ERROR_BASE64SRC_PARSE')
+ }
+ if(uni.base64ToArrayBuffer) {
+ return uni.base64ToArrayBuffer(bodyData)
+ } else {
+
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/base64ToPath/index.ts b/src/uni_modules/lime-shared/base64ToPath/index.ts
new file mode 100644
index 0000000..af9a9d2
--- /dev/null
+++ b/src/uni_modules/lime-shared/base64ToPath/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
diff --git a/src/uni_modules/lime-shared/base64ToPath/uvue.uts b/src/uni_modules/lime-shared/base64ToPath/uvue.uts
new file mode 100644
index 0000000..364b494
--- /dev/null
+++ b/src/uni_modules/lime-shared/base64ToPath/uvue.uts
@@ -0,0 +1,22 @@
+// @ts-nocheck
+import { processFile, type ProcessFileOptions } from '@/uni_modules/lime-file-utils'
+
+/**
+ * base64转路径
+ * @param {Object} base64
+ */
+export function base64ToPath(base64: string, filename: string | null = null):Promise {
+ return new Promise((resolve,reject) => {
+ processFile({
+ type: 'toDataURL',
+ path: base64,
+ filename,
+ success(res: string){
+ resolve(res)
+ },
+ fail(err){
+ reject(err)
+ }
+ } as ProcessFileOptions)
+ })
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/base64ToPath/vue.ts b/src/uni_modules/lime-shared/base64ToPath/vue.ts
new file mode 100644
index 0000000..735000f
--- /dev/null
+++ b/src/uni_modules/lime-shared/base64ToPath/vue.ts
@@ -0,0 +1,75 @@
+// @ts-nocheck
+import {platform} from '../platform'
+/**
+ * base64转路径
+ * @param {Object} base64
+ */
+export function base64ToPath(base64: string, filename?: string):Promise {
+ const [, format] = /^data:image\/(\w+);base64,/.exec(base64) || [];
+ return new Promise((resolve, reject) => {
+ // #ifdef MP
+ const fs = uni.getFileSystemManager()
+ //自定义文件名
+ if (!filename && !format) {
+ reject(new Error('ERROR_BASE64SRC_PARSE'))
+ }
+ // const time = new Date().getTime();
+ const name = filename || `${new Date().getTime()}.${format}`;
+ let pre = platform()
+ const filePath = `${pre.env.USER_DATA_PATH}/${name}`
+ fs.writeFile({
+ filePath,
+ data: base64.split(',')[1],
+ encoding: 'base64',
+ success() {
+ resolve(filePath)
+ },
+ fail(err) {
+ console.error(err)
+ reject(err)
+ }
+ })
+ // #endif
+
+ // #ifdef H5
+ // mime类型
+ let mimeString = base64.split(',')[0].split(':')[1].split(';')[0];
+ //base64 解码
+ let byteString = atob(base64.split(',')[1]);
+ //创建缓冲数组
+ let arrayBuffer = new ArrayBuffer(byteString.length);
+ //创建视图
+ let intArray = new Uint8Array(arrayBuffer);
+ for (let i = 0; i < byteString.length; i++) {
+ intArray[i] = byteString.charCodeAt(i);
+ }
+ resolve(URL.createObjectURL(new Blob([intArray], {
+ type: mimeString
+ })))
+ // #endif
+
+ // #ifdef APP-PLUS
+ const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+ bitmap.loadBase64Data(base64, () => {
+ if (!filename && !format) {
+ reject(new Error('ERROR_BASE64SRC_PARSE'))
+ }
+ // const time = new Date().getTime();
+ const name = filename || `${new Date().getTime()}.${format}`;
+ const filePath = `_doc/uniapp_temp/${name}`
+ bitmap.save(filePath, {},
+ () => {
+ bitmap.clear()
+ resolve(filePath)
+ },
+ (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ }, (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ // #endif
+ })
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/camelCase/index.ts b/src/uni_modules/lime-shared/camelCase/index.ts
new file mode 100644
index 0000000..dd470ab
--- /dev/null
+++ b/src/uni_modules/lime-shared/camelCase/index.ts
@@ -0,0 +1,21 @@
+/**
+ * 将字符串转换为 camelCase 或 PascalCase 风格的命名约定
+ * @param str 要转换的字符串
+ * @param isPascalCase 指示是否转换为 PascalCase 的布尔值,默认为 false
+ * @returns 转换后的字符串
+ */
+export function camelCase(str: string, isPascalCase: boolean = false): string {
+ // 将字符串分割成单词数组
+ let words: string[] = str.split(/[\s_-]+/);
+
+ // 将数组中的每个单词首字母大写(除了第一个单词)
+ let camelCased: string[] = words.map((word, index):string => {
+ if (index == 0 && !isPascalCase) {
+ return word.toLowerCase(); // 第一个单词全小写
+ }
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
+ });
+
+ // 将数组中的单词拼接成一个字符串
+ return camelCased.join('');
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/canIUseCanvas2d/index.ts b/src/uni_modules/lime-shared/canIUseCanvas2d/index.ts
new file mode 100644
index 0000000..be5623a
--- /dev/null
+++ b/src/uni_modules/lime-shared/canIUseCanvas2d/index.ts
@@ -0,0 +1,67 @@
+// @ts-nocheck
+
+// #ifndef UNI-APP-X && APP
+
+// #ifdef MP-ALIPAY
+interface My {
+ SDKVersion: string
+}
+declare var my: My
+// #endif
+
+function compareVersion(v1:string, v2:string) {
+ let a1 = v1.split('.');
+ let a2 = v2.split('.');
+ const len = Math.max(a1.length, a2.length);
+
+ while (a1.length < len) {
+ a1.push('0');
+ }
+ while (a2.length < len) {
+ a2.push('0');
+ }
+
+ for (let i = 0; i < len; i++) {
+ const num1 = parseInt(a1[i], 10);
+ const num2 = parseInt(a2[i], 10);
+
+ if (num1 > num2) {
+ return 1;
+ }
+ if (num1 < num2) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+function gte(version: string) {
+ let {SDKVersion} = uni.getSystemInfoSync();
+ // #ifdef MP-ALIPAY
+ SDKVersion = my.SDKVersion
+ // #endif
+ return compareVersion(SDKVersion, version) >= 0;
+}
+// #endif
+
+
+/** 环境是否支持canvas 2d */
+export function canIUseCanvas2d(): boolean {
+ // #ifdef MP-WEIXIN
+ return gte('2.9.0');
+ // #endif
+ // #ifdef MP-ALIPAY
+ return gte('2.7.0');
+ // #endif
+ // #ifdef MP-TOUTIAO
+ return gte('1.78.0');
+ // #endif
+ // #ifdef UNI-APP-X && WEB || UNI-APP-X && APP
+ return true;
+ // #endif
+ // #ifndef MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO
+ return false
+ // #endif
+
+}
diff --git a/src/uni_modules/lime-shared/capitalizedAmount/index.ts b/src/uni_modules/lime-shared/capitalizedAmount/index.ts
new file mode 100644
index 0000000..9a0c1f4
--- /dev/null
+++ b/src/uni_modules/lime-shared/capitalizedAmount/index.ts
@@ -0,0 +1,111 @@
+// @ts-nocheck
+import { isString } from "../isString";
+import { isNumber } from "../isNumber";
+/**
+ * 将金额转换为中文大写形式
+ * @param {number | string} amount - 需要转换的金额,可以是数字或字符串
+ * @returns {string} 转换后的中文大写金额
+ */
+function capitalizedAmount(amount : number) : string
+function capitalizedAmount(amount : string) : string
+function capitalizedAmount(amount : any | null) : string {
+ try {
+ let _amountStr :string;
+ let _amountNum :number = 0;
+ // 如果输入是字符串,先将其转换为数字,并去除逗号
+ if (typeof amount == 'string') {
+ _amountNum = parseFloat((amount as string).replace(/,/g, ''));
+ }
+ if(isNumber(amount)) {
+ _amountNum = amount as number
+ }
+ // 判断输入是否为有效的金额 || isNaN(amount)
+ if (amount == null) throw new Error('不是有效的金额!');
+
+ let result = '';
+
+ // 处理负数情况
+ if (_amountNum < 0) {
+ result = '欠';
+ _amountNum = Math.abs(_amountNum);
+ }
+
+ // 金额不能超过千亿以上
+ if (_amountNum >= 10e11) throw new Error('计算金额过大!');
+
+ // 保留两位小数并转换为字符串
+ _amountStr = _amountNum.toFixed(2);
+
+ // 定义数字、单位和小数单位的映射
+ const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
+ const units = ['', '拾', '佰', '仟'];
+ const bigUnits = ['', '万', '亿'];
+ const decimalUnits = ['角', '分'];
+
+ // 分离整数部分和小数部分
+ const amountArray = _amountStr.split('.');
+ let integerPart = amountArray[0]; // string| number[]
+ const decimalPart = amountArray[1];
+
+ // 处理整数部分
+ if (integerPart != '0') {
+ let _integerPart = integerPart.split('').map((item):number => parseInt(item));
+
+ // 将整数部分按四位一级进行分组
+ const levels = _integerPart.reverse().reduce((prev:string[][], item, index):string[][] => {
+ // const level = prev?.[0]?.length < 4 ? prev[0] : [];
+ const level = prev.length > 0 && prev[0].length < 4 ? prev[0]: []
+
+ const value = item == 0 ? digits[item] : digits[item] + units[index % 4];
+
+ level.unshift(value);
+
+ if (level.length == 1) {
+ prev.unshift(level);
+ } else {
+ prev[0] = level;
+ }
+
+ return prev;
+ }, [] as string[][]);
+ // 将分组后的整数部分转换为中文大写形式
+ result += levels.reduce((prev, item, index):string => {
+ let _level = bigUnits[levels.length - index - 1];
+ let _item = item.join('').replace(/(零)\1+/g, '$1');
+
+ if (_item == '零') {
+ _level = '';
+ _item = '';
+ } else if (_item.endsWith('零')) {
+ _item = _item.slice(0, _item.length - 1);
+ }
+
+ return prev + _item + _level;
+ }, '');
+ } else {
+ result += '零';
+ }
+
+ // 添加元
+ result += '元';
+
+ // 处理小数部分
+ if (decimalPart != '00') {
+ if (result == '零元') result = '';
+
+ for (let i = 0; i < decimalPart.length; i++) {
+ const digit = parseInt(decimalPart.charAt(i));
+
+ if (digit != 0) {
+ result += digits[digit] + decimalUnits[i];
+ }
+ }
+ } else {
+ result += '整';
+ }
+
+ return result;
+ } catch (error : Error) {
+ return error.message;
+ }
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/changelog.md b/src/uni_modules/lime-shared/changelog.md
new file mode 100644
index 0000000..0c6691b
--- /dev/null
+++ b/src/uni_modules/lime-shared/changelog.md
@@ -0,0 +1,63 @@
+
+## 0.2.9(2025-02-19)
+- chore: 更新文档
+## 0.2.8(2025-02-11)
+- chore: 更新文档
+## 0.2.7(2025-01-17)
+- fix: 针对canvas 平台判断优化
+## 0.2.6(2025-01-09)
+- feat: 增加`areaData`中国省市区数据
+## 0.2.5(2025-01-07)
+- fix: animation在app上类型问题
+## 0.2.4(2025-01-04)
+- feat: getRect类型问题
+## 0.2.3(2025-01-01)
+- chore: unitConvert使用uni.rpx2px
+## 0.2.2(2024-12-11)
+- chore: 动画使用`requestAnimationFrame`
+## 0.2.1(2024-11-20)
+- feat: 增加`characterLimit`
+## 0.2.0(2024-11-14)
+- fix: vue2的类型问题
+## 0.1.9(2024-11-14)
+- feat: 增加`shuffle`
+## 0.1.8(2024-10-08)
+- fix: vue2 条件编译 // #ifdef APP-IOS || APP-ANDROID 会生效
+## 0.1.7(2024-09-23)
+- fix: raf 类型跟随版本变更
+## 0.1.6(2024-07-24)
+- fix: vue2 app ts需要明确的后缀,所有补全
+- chore: 减少依赖
+## 0.1.5(2024-07-21)
+- feat: 删除 Hooks
+- feat: 兼容uniappx
+## 0.1.4(2023-09-05)
+- feat: 增加 Hooks `useIntersectionObserver`
+- feat: 增加 `floatAdd`
+- feat: 因为本人插件兼容 vue2 需要使用 `composition-api`,故增加vue文件代码插件的条件编译
+## 0.1.3(2023-08-13)
+- feat: 增加 `camelCase`
+## 0.1.2(2023-07-17)
+- feat: 增加 `getClassStr`
+## 0.1.1(2023-07-06)
+- feat: 增加 `isNumeric`, 区别于 `isNumber`
+## 0.1.0(2023-06-30)
+- fix: `clamp`忘记导出了
+## 0.0.9(2023-06-27)
+- feat: 增加`arrayBufferToFile`
+## 0.0.8(2023-06-19)
+- feat: 增加`createAnimation`、`clamp`
+## 0.0.7(2023-06-08)
+- chore: 更新注释
+## 0.0.6(2023-06-08)
+- chore: 增加`createImage`为`lime-watermark`和`lime-qrcode`提供依赖
+## 0.0.5(2023-06-03)
+- chore: 更新注释
+## 0.0.4(2023-05-22)
+- feat: 增加`range`,`exif`,`selectComponent`
+## 0.0.3(2023-05-08)
+- feat: 增加`fillZero`,`debounce`,`throttle`,`random`
+## 0.0.2(2023-05-05)
+- chore: 更新文档
+## 0.0.1(2023-05-05)
+- 无
diff --git a/src/uni_modules/lime-shared/characterLimit/index.ts b/src/uni_modules/lime-shared/characterLimit/index.ts
new file mode 100644
index 0000000..215de23
--- /dev/null
+++ b/src/uni_modules/lime-shared/characterLimit/index.ts
@@ -0,0 +1,63 @@
+// @ts-nocheck
+/**
+ * 计算字符串字符的长度并可以截取字符串。
+ * @param char 传入字符串(maxcharacter条件下,一个汉字表示两个字符)
+ * @param max 规定最大字符串长度
+ * @returns 当没有传入maxCharacter/maxLength 时返回字符串字符长度,当传入maxCharacter/maxLength时返回截取之后的字符串和长度。
+ */
+export type CharacterLengthResult = {
+ length : number;
+ characters : string;
+}
+// #ifdef APP-ANDROID
+type ChartType = any
+// #endif
+// #ifndef APP-ANDROID
+type ChartType = string | number
+// #endif
+
+export function characterLimit(type : string, char : ChartType, max : number) : CharacterLengthResult {
+ const str = `${char}`;
+
+ if (str.length == 0) {
+ return {
+ length: 0,
+ characters: '',
+ } as CharacterLengthResult
+ }
+
+ if (type == 'maxcharacter') {
+ let len = 0;
+ for (let i = 0; i < str.length; i += 1) {
+ let currentStringLength : number// = 0;
+ const code = str.charCodeAt(i)!
+ if (code > 127 || code == 94) {
+ currentStringLength = 2;
+ } else {
+ currentStringLength = 1;
+ }
+ if (len + currentStringLength > max) {
+ return {
+ length: len,
+ characters: str.slice(0, i),
+ } as CharacterLengthResult
+ }
+ len += currentStringLength;
+ }
+ return {
+ length: len,
+ characters: str,
+ } as CharacterLengthResult
+ } else if (type == 'maxlength') {
+ const length = str.length > max ? max : str.length;
+ return {
+ length: length,
+ characters: str.slice(0, length),
+ } as CharacterLengthResult
+ }
+
+ return {
+ length: str.length,
+ characters: str,
+ } as CharacterLengthResult
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/clamp/index.ts b/src/uni_modules/lime-shared/clamp/index.ts
new file mode 100644
index 0000000..0e16358
--- /dev/null
+++ b/src/uni_modules/lime-shared/clamp/index.ts
@@ -0,0 +1,16 @@
+// @ts-nocheck
+/**
+ * 将一个值限制在指定的范围内
+ * @param val 要限制的值
+ * @param min 最小值
+ * @param max 最大值
+ * @returns 限制后的值
+ */
+export function clamp(val: number, min: number, max: number): number {
+ return Math.max(min, Math.min(max, val));
+}
+
+
+// console.log(clamp(5 ,0, 10)); // 输出: 5(在范围内,不做更改)
+// console.log(clamp(-5 ,0, 10)); // 输出: 0(小于最小值,被限制为最小值)
+// console.log(clamp(15 ,0, 10)); // 输出: 10(大于最大值,被限制为最大值)
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/cloneDeep/index.ts b/src/uni_modules/lime-shared/cloneDeep/index.ts
new file mode 100644
index 0000000..3428c49
--- /dev/null
+++ b/src/uni_modules/lime-shared/cloneDeep/index.ts
@@ -0,0 +1,10 @@
+// @ts-nocheck
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.ts'
+// #endif
+
+
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/cloneDeep/uvue.ts b/src/uni_modules/lime-shared/cloneDeep/uvue.ts
new file mode 100644
index 0000000..7929bc2
--- /dev/null
+++ b/src/uni_modules/lime-shared/cloneDeep/uvue.ts
@@ -0,0 +1,17 @@
+// @ts-nocheck
+/**
+ * 深度克隆一个对象或数组
+ * @param obj 要克隆的对象或数组
+ * @returns 克隆后的对象或数组
+ */
+export function cloneDeep(obj: any): T {
+ // 如果传入的对象是基本数据类型(如字符串、数字等),则直接返回
+ // if(['number', 'string'].includes(typeof obj) || Array.isArray(obj)){
+ // return obj as T
+ // }
+ if(typeof obj == 'object'){
+ return JSON.parse(JSON.stringify(obj as T)) as T;
+ }
+ return obj as T
+}
+
diff --git a/src/uni_modules/lime-shared/cloneDeep/vue.ts b/src/uni_modules/lime-shared/cloneDeep/vue.ts
new file mode 100644
index 0000000..ded334d
--- /dev/null
+++ b/src/uni_modules/lime-shared/cloneDeep/vue.ts
@@ -0,0 +1,103 @@
+// @ts-nocheck
+/**
+ * 深度克隆一个对象或数组
+ * @param obj 要克隆的对象或数组
+ * @returns 克隆后的对象或数组
+ */
+export function cloneDeep(obj: any): T {
+ // 如果传入的对象为空,返回空
+ if (obj === null) {
+ return null as unknown as T;
+ }
+
+ // 如果传入的对象是 Set 类型,则将其转换为数组,并通过新的 Set 构造函数创建一个新的 Set 对象
+ if (obj instanceof Set) {
+ return new Set([...obj]) as unknown as T;
+ }
+
+ // 如果传入的对象是 Map 类型,则将其转换为数组,并通过新的 Map 构造函数创建一个新的 Map 对象
+ if (obj instanceof Map) {
+ return new Map([...obj]) as unknown as T;
+ }
+
+ // 如果传入的对象是 WeakMap 类型,则直接用传入的 WeakMap 对象进行赋值
+ if (obj instanceof WeakMap) {
+ let weakMap = new WeakMap();
+ weakMap = obj;
+ return weakMap as unknown as T;
+ }
+
+ // 如果传入的对象是 WeakSet 类型,则直接用传入的 WeakSet 对象进行赋值
+ if (obj instanceof WeakSet) {
+ let weakSet = new WeakSet();
+ weakSet = obj;
+ return weakSet as unknown as T;
+ }
+
+ // 如果传入的对象是 RegExp 类型,则通过新的 RegExp 构造函数创建一个新的 RegExp 对象
+ if (obj instanceof RegExp) {
+ return new RegExp(obj) as unknown as T;
+ }
+
+ // 如果传入的对象是 undefined 类型,则返回 undefined
+ if (typeof obj === 'undefined') {
+ return undefined as unknown as T;
+ }
+
+ // 如果传入的对象是数组,则递归调用 cloneDeep 函数对数组中的每个元素进行克隆
+ if (Array.isArray(obj)) {
+ return obj.map(cloneDeep) as unknown as T;
+ }
+
+ // 如果传入的对象是 Date 类型,则通过新的 Date 构造函数创建一个新的 Date 对象
+ if (obj instanceof Date) {
+ return new Date(obj.getTime()) as unknown as T;
+ }
+
+ // 如果传入的对象是普通对象,则使用递归调用 cloneDeep 函数对对象的每个属性进行克隆
+ if (typeof obj === 'object') {
+ const newObj: any = {};
+ for (const [key, value] of Object.entries(obj)) {
+ newObj[key] = cloneDeep(value);
+ }
+ const symbolKeys = Object.getOwnPropertySymbols(obj);
+ for (const key of symbolKeys) {
+ newObj[key] = cloneDeep(obj[key]);
+ }
+ return newObj;
+ }
+
+ // 如果传入的对象是基本数据类型(如字符串、数字等),则直接返回
+ return obj;
+}
+
+// 示例使用
+
+// // 克隆一个对象
+// const obj = { name: 'John', age: 30 };
+// const clonedObj = cloneDeep(obj);
+
+// console.log(clonedObj); // 输出: { name: 'John', age: 30 }
+// console.log(clonedObj === obj); // 输出: false (副本与原对象是独立的)
+
+// // 克隆一个数组
+// const arr = [1, 2, 3];
+// const clonedArr = cloneDeep(arr);
+
+// console.log(clonedArr); // 输出: [1, 2, 3]
+// console.log(clonedArr === arr); // 输出: false (副本与原数组是独立的)
+
+// // 克隆一个包含嵌套对象的对象
+// const person = {
+// name: 'Alice',
+// age: 25,
+// address: {
+// city: 'New York',
+// country: 'USA',
+// },
+// };
+// const clonedPerson = cloneDeep(person);
+
+// console.log(clonedPerson); // 输出: { name: 'Alice', age: 25, address: { city: 'New York', country: 'USA' } }
+// console.log(clonedPerson === person); // 输出: false (副本与原对象是独立的)
+// console.log(clonedPerson.address === person.address); // 输出: false (嵌套对象的副本也是独立的)
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/closest/index.ts b/src/uni_modules/lime-shared/closest/index.ts
new file mode 100644
index 0000000..e6e79c2
--- /dev/null
+++ b/src/uni_modules/lime-shared/closest/index.ts
@@ -0,0 +1,22 @@
+// @ts-nocheck
+
+/**
+ * 在给定数组中找到最接近目标数字的元素。
+ * @param arr 要搜索的数字数组。
+ * @param target 目标数字。
+ * @returns 最接近目标数字的数组元素。
+ */
+export function closest(arr: number[], target: number):number {
+ return arr.reduce((pre: number, cur: number):number =>
+ Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
+ );
+}
+
+// 示例
+// // 定义一个数字数组
+// const numbers = [1, 3, 5, 7, 9];
+
+// // 在数组中找到最接近目标数字 6 的元素
+// const closestNumber = closest(numbers, 6);
+
+// console.log(closestNumber); // 输出结果: 5
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/components/lime-shared/lime-shared.vue b/src/uni_modules/lime-shared/components/lime-shared/lime-shared.vue
new file mode 100644
index 0000000..e2d7fe2
--- /dev/null
+++ b/src/uni_modules/lime-shared/components/lime-shared/lime-shared.vue
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/createAnimation/index.ts b/src/uni_modules/lime-shared/createAnimation/index.ts
new file mode 100644
index 0000000..999ec1c
--- /dev/null
+++ b/src/uni_modules/lime-shared/createAnimation/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X
+export * from './type.ts'
+export * from './vue.ts'
+// #endif
+
+// #ifdef UNI-APP-X
+export * from './uvue.ts'
+// #endif
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/createAnimation/type.ts b/src/uni_modules/lime-shared/createAnimation/type.ts
new file mode 100644
index 0000000..0f8ad34
--- /dev/null
+++ b/src/uni_modules/lime-shared/createAnimation/type.ts
@@ -0,0 +1,25 @@
+export type CreateAnimationOptions = {
+ /**
+ * 动画持续时间,单位ms
+ */
+ duration ?: number;
+ /**
+ * 定义动画的效果
+ * - linear: 动画从头到尾的速度是相同的
+ * - ease: 动画以低速开始,然后加快,在结束前变慢
+ * - ease-in: 动画以低速开始
+ * - ease-in-out: 动画以低速开始和结束
+ * - ease-out: 动画以低速结束
+ * - step-start: 动画第一帧就跳至结束状态直到结束
+ * - step-end: 动画一直保持开始状态,最后一帧跳到结束状态
+ */
+ timingFunction ?: string //'linear' | 'ease' | 'ease-in' | 'ease-in-out' | 'ease-out' | 'step-start' | 'step-end';
+ /**
+ * 动画延迟时间,单位 ms
+ */
+ delay ?: number;
+ /**
+ * 设置transform-origin
+ */
+ transformOrigin ?: string;
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/createAnimation/uvue.ts b/src/uni_modules/lime-shared/createAnimation/uvue.ts
new file mode 100644
index 0000000..96d8263
--- /dev/null
+++ b/src/uni_modules/lime-shared/createAnimation/uvue.ts
@@ -0,0 +1,5 @@
+// @ts-nocheck
+// export * from '@/uni_modules/lime-animateIt'
+export function createAnimation() {
+ console.error('当前环境不支持,请使用:lime-animateIt')
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/createAnimation/vue.ts b/src/uni_modules/lime-shared/createAnimation/vue.ts
new file mode 100644
index 0000000..6934f27
--- /dev/null
+++ b/src/uni_modules/lime-shared/createAnimation/vue.ts
@@ -0,0 +1,148 @@
+// @ts-nocheck
+// nvue 需要在节点上设置ref或在export里传入
+// const animation = createAnimation({
+// ref: this.$refs['xxx'],
+// duration: 0,
+// timingFunction: 'linear'
+// })
+// animation.opacity(1).translate(x, y).step({duration})
+// animation.export(ref)
+
+// 抹平nvue 与 uni.createAnimation的使用差距
+// 但是nvue动画太慢
+
+
+
+import { type CreateAnimationOptions } from './type'
+// #ifdef APP-NVUE
+const nvueAnimation = uni.requireNativePlugin('animation')
+
+type AnimationTypes = 'matrix' | 'matrix3d' | 'rotate' | 'rotate3d' | 'rotateX' | 'rotateY' | 'rotateZ' | 'scale' | 'scale3d' | 'scaleX' | 'scaleY' | 'scaleZ' | 'skew' | 'skewX' | 'skewY' | 'translate' | 'translate3d' | 'translateX' | 'translateY' | 'translateZ'
+ | 'opacity' | 'backgroundColor' | 'width' | 'height' | 'left' | 'right' | 'top' | 'bottom'
+
+interface Styles {
+ [key : string] : any
+}
+
+interface StepConfig {
+ duration?: number
+ timingFunction?: string
+ delay?: number
+ needLayout?: boolean
+ transformOrigin?: string
+}
+interface StepAnimate {
+ styles?: Styles
+ config?: StepConfig
+}
+interface StepAnimates {
+ [key: number]: StepAnimate
+}
+// export interface CreateAnimationOptions extends UniApp.CreateAnimationOptions {
+// ref?: string
+// }
+
+type Callback = (time: number) => void
+const animateTypes1 : AnimationTypes[] = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
+ 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
+ 'translateZ'
+]
+const animateTypes2 : AnimationTypes[] = ['opacity', 'backgroundColor']
+const animateTypes3 : AnimationTypes[] = ['width', 'height', 'left', 'right', 'top', 'bottom']
+
+class LimeAnimation {
+ ref : any
+ context : any
+ options : UniApp.CreateAnimationOptions
+ // stack : any[] = []
+ next : number = 0
+ currentStepAnimates : StepAnimates = {}
+ duration : number = 0
+ constructor(options : CreateAnimationOptions) {
+ const {ref} = options
+ this.ref = ref
+ this.options = options
+ }
+ addAnimate(type : AnimationTypes, args: (string | number)[]) {
+ let aniObj = this.currentStepAnimates[this.next]
+ let stepAnimate:StepAnimate = {}
+ if (!aniObj) {
+ stepAnimate = {styles: {}, config: {}}
+ } else {
+ stepAnimate = aniObj
+ }
+
+ if (animateTypes1.includes(type)) {
+ if (!stepAnimate.styles.transform) {
+ stepAnimate.styles.transform = ''
+ }
+ let unit = ''
+ if (type === 'rotate') {
+ unit = 'deg'
+ }
+ stepAnimate.styles.transform += `${type}(${args.map((v: number) => v + unit).join(',')}) `
+ } else {
+ stepAnimate.styles[type] = `${args.join(',')}`
+ }
+ this.currentStepAnimates[this.next] = stepAnimate
+ }
+ animateRun(styles: Styles = {}, config:StepConfig = {}, ref: any) {
+ const el = ref || this.ref
+ if (!el) return
+ return new Promise((resolve) => {
+ const time = +new Date()
+ nvueAnimation.transition(el, {
+ styles,
+ ...config
+ }, () => {
+ resolve(+new Date() - time)
+ })
+ })
+ }
+ nextAnimate(animates: StepAnimates, step: number = 0, ref: any, cb: Callback) {
+ let obj = animates[step]
+ if (obj) {
+ let { styles, config } = obj
+ // this.duration += config.duration
+ this.animateRun(styles, config, ref).then((time: number) => {
+ step += 1
+ this.duration += time
+ this.nextAnimate(animates, step, ref, cb)
+ })
+ } else {
+ this.currentStepAnimates = {}
+ cb && cb(this.duration)
+ }
+ }
+ step(config:StepConfig = {}) {
+ this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
+ this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
+ this.next++
+ return this
+ }
+ export(ref: any, cb?: Callback) {
+ ref = ref || this.ref
+ if(!ref) return
+ this.duration = 0
+ this.next = 0
+ this.nextAnimate(this.currentStepAnimates, 0, ref, cb)
+ return null
+ }
+}
+
+
+animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
+ LimeAnimation.prototype[type] = function(...args: (string | number)[]) {
+ this.addAnimate(type, args)
+ return this
+ }
+})
+// #endif
+export function createAnimation(options : CreateAnimationOptions) {
+ // #ifndef APP-NVUE
+ return uni.createAnimation({ ...options })
+ // #endif
+ // #ifdef APP-NVUE
+ return new LimeAnimation(options)
+ // #endif
+}
diff --git a/src/uni_modules/lime-shared/createCanvas/index.ts b/src/uni_modules/lime-shared/createCanvas/index.ts
new file mode 100644
index 0000000..987be92
--- /dev/null
+++ b/src/uni_modules/lime-shared/createCanvas/index.ts
@@ -0,0 +1,73 @@
+
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+import type { ComponentInternalInstance } from '@/uni_modules/lime-shared/vue'
+import { getRect } from '@/uni_modules/lime-shared/getRect'
+import { canIUseCanvas2d } from '@/uni_modules/lime-shared/canIUseCanvas2d'
+export const isCanvas2d = canIUseCanvas2d()
+// #endif
+
+
+export function createCanvas(canvasId : string, component : ComponentInternalInstance) {
+ // #ifdef UNI-APP-X
+ uni.createCanvasContextAsync({
+ canvasId,
+ component,
+ success(context : CanvasContext) {
+
+ },
+ fail(error : UniError) {
+
+ }
+ })
+ // #endif
+ // #ifndef UNI-APP-X
+ const isCanvas2d = canIUseCanvas2d()
+ getRect('#' + canvasId, context, isCanvas2d).then(res => {
+ if (res.node) {
+ res.node.width = res.width
+ res.node.height = res.height
+ return res.node
+ } else {
+ const ctx = uni.createCanvasContext(canvasId, context)
+ if (!ctx._drawImage) {
+ ctx._drawImage = ctx.drawImage
+ ctx.drawImage = function (...args) {
+ const { path } = args.shift()
+ ctx._drawImage(path, ...args)
+ }
+ }
+ if (!ctx.getImageData) {
+ ctx.getImageData = function () {
+ return new Promise((resolve, reject) => {
+ uni.canvasGetImageData({
+ canvasId,
+ x: parseInt(arguments[0]),
+ y: parseInt(arguments[1]),
+ width: parseInt(arguments[2]),
+ height: parseInt(arguments[3]),
+ success(res) {
+ resolve(res)
+ },
+ fail(err) {
+ reject(err)
+ }
+ }, context)
+ })
+
+ }
+ return {
+ getContext(type: string) {
+ if(type == '2d') {
+ return ctx
+ }
+ },
+ width: res.width,
+ height: res.height,
+ createImage
+ }
+ }
+ }
+ })
+ // #endif
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/createImage/index.ts b/src/uni_modules/lime-shared/createImage/index.ts
new file mode 100644
index 0000000..c9e72fe
--- /dev/null
+++ b/src/uni_modules/lime-shared/createImage/index.ts
@@ -0,0 +1,71 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+import {isBrowser} from '../isBrowser'
+class Image {
+ currentSrc: string | null = null
+ naturalHeight: number = 0
+ naturalWidth: number = 0
+ width: number = 0
+ height: number = 0
+ tagName: string = 'IMG'
+ path: string = ''
+ crossOrigin: string = ''
+ referrerPolicy: string = ''
+ onload: () => void = () => {}
+ onerror: () => void = () => {}
+ complete: boolean = false
+ constructor() {}
+ set src(src: string) {
+ console.log('src', src)
+ if(!src) {
+ return this.onerror()
+ }
+ src = src.replace(/^@\//,'/')
+ this.currentSrc = src
+ uni.getImageInfo({
+ src,
+ success: (res) => {
+ const localReg = /^\.|^\/(?=[^\/])/;
+ // #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO
+ res.path = localReg.test(src) ? `/${res.path}` : res.path;
+ // #endif
+ this.complete = true
+ this.path = res.path
+ this.naturalWidth = this.width = res.width
+ this.naturalHeight = this.height = res.height
+ this.onload()
+ },
+ fail: () => {
+ this.onerror()
+ }
+ })
+ }
+ get src() {
+ return this.currentSrc
+ }
+}
+interface UniImage extends WechatMiniprogram.Image {
+ complete?: boolean
+ naturalHeight?: number
+ naturalWidth?: number
+}
+/** 创建用于 canvas 的 img */
+export function createImage(canvas?: any): HTMLImageElement | UniImage {
+ if(canvas && canvas.createImage) {
+ return (canvas as WechatMiniprogram.Canvas).createImage()
+ } else if(this && this['tagName'] == 'canvas' && !('toBlob' in this) || canvas && !('toBlob' in canvas)){
+ return new Image()
+ } else if(isBrowser) {
+ return new window.Image()
+ }
+ return new Image()
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export function createImage():Image{
+ // console.error('当前环境不支持')
+ return new Image()
+}
+// #endif
diff --git a/src/uni_modules/lime-shared/debounce/index.ts b/src/uni_modules/lime-shared/debounce/index.ts
new file mode 100644
index 0000000..a168ca3
--- /dev/null
+++ b/src/uni_modules/lime-shared/debounce/index.ts
@@ -0,0 +1,10 @@
+// @ts-nocheck
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.ts'
+
+// #endif
+
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/debounce/uvue.ts b/src/uni_modules/lime-shared/debounce/uvue.ts
new file mode 100644
index 0000000..f1fc29d
--- /dev/null
+++ b/src/uni_modules/lime-shared/debounce/uvue.ts
@@ -0,0 +1,36 @@
+// @ts-nocheck
+/**
+ * 防抖函数,通过延迟一定时间来限制函数的执行频率。
+ * @param fn 要防抖的函数。
+ * @param wait 触发防抖的等待时间,单位为毫秒。
+ * @returns 防抖函数。
+ */
+export function debounce(fn : (args: A)=> void, wait = 300): (args: A)=> void {
+ let timer = -1
+
+ return (args: A) => {
+ if (timer >-1) {clearTimeout(timer)};
+
+ timer = setTimeout(()=>{
+ fn(args)
+ }, wait)
+ }
+};
+
+
+
+// 示例
+// 定义一个函数
+// function saveData(data: string) {
+// // 模拟保存数据的操作
+// console.log(`Saving data: ${data}`);
+// }
+
+// // 创建一个防抖函数,延迟 500 毫秒后调用 saveData 函数
+// const debouncedSaveData = debounce(saveData, 500);
+
+// // 连续调用防抖函数
+// debouncedSaveData('Data 1'); // 不会立即调用 saveData 函数
+// debouncedSaveData('Data 2'); // 不会立即调用 saveData 函数
+
+// 在 500 毫秒后,只会调用一次 saveData 函数,输出结果为 "Saving data: Data 2"
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/debounce/vue.ts b/src/uni_modules/lime-shared/debounce/vue.ts
new file mode 100644
index 0000000..694b44d
--- /dev/null
+++ b/src/uni_modules/lime-shared/debounce/vue.ts
@@ -0,0 +1,40 @@
+// @ts-nocheck
+type Timeout = ReturnType | null;
+/**
+ * 防抖函数,通过延迟一定时间来限制函数的执行频率。
+ * @param fn 要防抖的函数。
+ * @param wait 触发防抖的等待时间,单位为毫秒。
+ * @returns 防抖函数。
+ */
+export function debounce(
+ fn : (...args : A) => R,
+ wait : number = 300) : (...args : A) => void {
+ let timer : Timeout = null;
+
+ return function (...args : A) {
+ if (timer) clearTimeout(timer); // 如果上一个 setTimeout 存在,则清除它
+
+ // 设置一个新的 setTimeout,在指定的等待时间后调用防抖函数
+ timer = setTimeout(() => {
+ fn.apply(this, args); // 使用提供的参数调用原始函数
+ }, wait);
+ };
+};
+
+
+
+// 示例
+// 定义一个函数
+// function saveData(data: string) {
+// // 模拟保存数据的操作
+// console.log(`Saving data: ${data}`);
+// }
+
+// // 创建一个防抖函数,延迟 500 毫秒后调用 saveData 函数
+// const debouncedSaveData = debounce(saveData, 500);
+
+// // 连续调用防抖函数
+// debouncedSaveData('Data 1'); // 不会立即调用 saveData 函数
+// debouncedSaveData('Data 2'); // 不会立即调用 saveData 函数
+
+// 在 500 毫秒后,只会调用一次 saveData 函数,输出结果为 "Saving data: Data 2"
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/exif/index.ts b/src/uni_modules/lime-shared/exif/index.ts
new file mode 100644
index 0000000..c1e7e3f
--- /dev/null
+++ b/src/uni_modules/lime-shared/exif/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.ts'
+// #endif
diff --git a/src/uni_modules/lime-shared/exif/uvue.ts b/src/uni_modules/lime-shared/exif/uvue.ts
new file mode 100644
index 0000000..01d21a2
--- /dev/null
+++ b/src/uni_modules/lime-shared/exif/uvue.ts
@@ -0,0 +1,7 @@
+class EXIF {
+ constructor(){
+ console.error('当前环境不支持')
+ }
+}
+
+export const exif = new EXIF()
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/exif/vue.ts b/src/uni_modules/lime-shared/exif/vue.ts
new file mode 100644
index 0000000..86f2454
--- /dev/null
+++ b/src/uni_modules/lime-shared/exif/vue.ts
@@ -0,0 +1,1057 @@
+// @ts-nocheck
+import { base64ToArrayBuffer } from '../base64ToArrayBuffer';
+import { pathToBase64 } from '../pathToBase64';
+// import { isBase64 } from '../isBase64';
+import { isBase64DataUri } from '../isBase64';
+import { isString } from '../isString';
+
+interface File {
+ exifdata : any
+ iptcdata : any
+ xmpdata : any
+ src : string
+}
+class EXIF {
+ isXmpEnabled = false
+ debug = false
+ Tags = {
+ // version tags
+ 0x9000: "ExifVersion", // EXIF version
+ 0xA000: "FlashpixVersion", // Flashpix format version
+
+ // colorspace tags
+ 0xA001: "ColorSpace", // Color space information tag
+
+ // image configuration
+ 0xA002: "PixelXDimension", // Valid width of meaningful image
+ 0xA003: "PixelYDimension", // Valid height of meaningful image
+ 0x9101: "ComponentsConfiguration", // Information about channels
+ 0x9102: "CompressedBitsPerPixel", // Compressed bits per pixel
+
+ // user information
+ 0x927C: "MakerNote", // Any desired information written by the manufacturer
+ 0x9286: "UserComment", // Comments by user
+
+ // related file
+ 0xA004: "RelatedSoundFile", // Name of related sound file
+
+ // date and time
+ 0x9003: "DateTimeOriginal", // Date and time when the original image was generated
+ 0x9004: "DateTimeDigitized", // Date and time when the image was stored digitally
+ 0x9290: "SubsecTime", // Fractions of seconds for DateTime
+ 0x9291: "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal
+ 0x9292: "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized
+
+ // picture-taking conditions
+ 0x829A: "ExposureTime", // Exposure time (in seconds)
+ 0x829D: "FNumber", // F number
+ 0x8822: "ExposureProgram", // Exposure program
+ 0x8824: "SpectralSensitivity", // Spectral sensitivity
+ 0x8827: "ISOSpeedRatings", // ISO speed rating
+ 0x8828: "OECF", // Optoelectric conversion factor
+ 0x9201: "ShutterSpeedValue", // Shutter speed
+ 0x9202: "ApertureValue", // Lens aperture
+ 0x9203: "BrightnessValue", // Value of brightness
+ 0x9204: "ExposureBias", // Exposure bias
+ 0x9205: "MaxApertureValue", // Smallest F number of lens
+ 0x9206: "SubjectDistance", // Distance to subject in meters
+ 0x9207: "MeteringMode", // Metering mode
+ 0x9208: "LightSource", // Kind of light source
+ 0x9209: "Flash", // Flash status
+ 0x9214: "SubjectArea", // Location and area of main subject
+ 0x920A: "FocalLength", // Focal length of the lens in mm
+ 0xA20B: "FlashEnergy", // Strobe energy in BCPS
+ 0xA20C: "SpatialFrequencyResponse", //
+ 0xA20E: "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit
+ 0xA20F: "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit
+ 0xA210: "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
+ 0xA214: "SubjectLocation", // Location of subject in image
+ 0xA215: "ExposureIndex", // Exposure index selected on camera
+ 0xA217: "SensingMethod", // Image sensor type
+ 0xA300: "FileSource", // Image source (3 == DSC)
+ 0xA301: "SceneType", // Scene type (1 == directly photographed)
+ 0xA302: "CFAPattern", // Color filter array geometric pattern
+ 0xA401: "CustomRendered", // Special processing
+ 0xA402: "ExposureMode", // Exposure mode
+ 0xA403: "WhiteBalance", // 1 = auto white balance, 2 = manual
+ 0xA404: "DigitalZoomRation", // Digital zoom ratio
+ 0xA405: "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm)
+ 0xA406: "SceneCaptureType", // Type of scene
+ 0xA407: "GainControl", // Degree of overall image gain adjustment
+ 0xA408: "Contrast", // Direction of contrast processing applied by camera
+ 0xA409: "Saturation", // Direction of saturation processing applied by camera
+ 0xA40A: "Sharpness", // Direction of sharpness processing applied by camera
+ 0xA40B: "DeviceSettingDescription", //
+ 0xA40C: "SubjectDistanceRange", // Distance to subject
+
+ // other tags
+ 0xA005: "InteroperabilityIFDPointer",
+ 0xA420: "ImageUniqueID" // Identifier assigned uniquely to each image
+ }
+ TiffTags = {
+ 0x0100: "ImageWidth",
+ 0x0101: "ImageHeight",
+ 0x8769: "ExifIFDPointer",
+ 0x8825: "GPSInfoIFDPointer",
+ 0xA005: "InteroperabilityIFDPointer",
+ 0x0102: "BitsPerSample",
+ 0x0103: "Compression",
+ 0x0106: "PhotometricInterpretation",
+ 0x0112: "Orientation",
+ 0x0115: "SamplesPerPixel",
+ 0x011C: "PlanarConfiguration",
+ 0x0212: "YCbCrSubSampling",
+ 0x0213: "YCbCrPositioning",
+ 0x011A: "XResolution",
+ 0x011B: "YResolution",
+ 0x0128: "ResolutionUnit",
+ 0x0111: "StripOffsets",
+ 0x0116: "RowsPerStrip",
+ 0x0117: "StripByteCounts",
+ 0x0201: "JPEGInterchangeFormat",
+ 0x0202: "JPEGInterchangeFormatLength",
+ 0x012D: "TransferFunction",
+ 0x013E: "WhitePoint",
+ 0x013F: "PrimaryChromaticities",
+ 0x0211: "YCbCrCoefficients",
+ 0x0214: "ReferenceBlackWhite",
+ 0x0132: "DateTime",
+ 0x010E: "ImageDescription",
+ 0x010F: "Make",
+ 0x0110: "Model",
+ 0x0131: "Software",
+ 0x013B: "Artist",
+ 0x8298: "Copyright"
+ }
+ GPSTags = {
+ 0x0000: "GPSVersionID",
+ 0x0001: "GPSLatitudeRef",
+ 0x0002: "GPSLatitude",
+ 0x0003: "GPSLongitudeRef",
+ 0x0004: "GPSLongitude",
+ 0x0005: "GPSAltitudeRef",
+ 0x0006: "GPSAltitude",
+ 0x0007: "GPSTimeStamp",
+ 0x0008: "GPSSatellites",
+ 0x0009: "GPSStatus",
+ 0x000A: "GPSMeasureMode",
+ 0x000B: "GPSDOP",
+ 0x000C: "GPSSpeedRef",
+ 0x000D: "GPSSpeed",
+ 0x000E: "GPSTrackRef",
+ 0x000F: "GPSTrack",
+ 0x0010: "GPSImgDirectionRef",
+ 0x0011: "GPSImgDirection",
+ 0x0012: "GPSMapDatum",
+ 0x0013: "GPSDestLatitudeRef",
+ 0x0014: "GPSDestLatitude",
+ 0x0015: "GPSDestLongitudeRef",
+ 0x0016: "GPSDestLongitude",
+ 0x0017: "GPSDestBearingRef",
+ 0x0018: "GPSDestBearing",
+ 0x0019: "GPSDestDistanceRef",
+ 0x001A: "GPSDestDistance",
+ 0x001B: "GPSProcessingMethod",
+ 0x001C: "GPSAreaInformation",
+ 0x001D: "GPSDateStamp",
+ 0x001E: "GPSDifferential"
+ }
+ // EXIF 2.3 Spec
+ IFD1Tags = {
+ 0x0100: "ImageWidth",
+ 0x0101: "ImageHeight",
+ 0x0102: "BitsPerSample",
+ 0x0103: "Compression",
+ 0x0106: "PhotometricInterpretation",
+ 0x0111: "StripOffsets",
+ 0x0112: "Orientation",
+ 0x0115: "SamplesPerPixel",
+ 0x0116: "RowsPerStrip",
+ 0x0117: "StripByteCounts",
+ 0x011A: "XResolution",
+ 0x011B: "YResolution",
+ 0x011C: "PlanarConfiguration",
+ 0x0128: "ResolutionUnit",
+ 0x0201: "JpegIFOffset", // When image format is JPEG, this value show offset to JPEG data stored.(aka "ThumbnailOffset" or "JPEGInterchangeFormat")
+ 0x0202: "JpegIFByteCount", // When image format is JPEG, this value shows data size of JPEG image (aka "ThumbnailLength" or "JPEGInterchangeFormatLength")
+ 0x0211: "YCbCrCoefficients",
+ 0x0212: "YCbCrSubSampling",
+ 0x0213: "YCbCrPositioning",
+ 0x0214: "ReferenceBlackWhite"
+ }
+ StringValues = {
+ ExposureProgram: {
+ 0: "Not defined",
+ 1: "Manual",
+ 2: "Normal program",
+ 3: "Aperture priority",
+ 4: "Shutter priority",
+ 5: "Creative program",
+ 6: "Action program",
+ 7: "Portrait mode",
+ 8: "Landscape mode"
+ },
+ MeteringMode: {
+ 0: "Unknown",
+ 1: "Average",
+ 2: "CenterWeightedAverage",
+ 3: "Spot",
+ 4: "MultiSpot",
+ 5: "Pattern",
+ 6: "Partial",
+ 255: "Other"
+ },
+ LightSource: {
+ 0: "Unknown",
+ 1: "Daylight",
+ 2: "Fluorescent",
+ 3: "Tungsten (incandescent light)",
+ 4: "Flash",
+ 9: "Fine weather",
+ 10: "Cloudy weather",
+ 11: "Shade",
+ 12: "Daylight fluorescent (D 5700 - 7100K)",
+ 13: "Day white fluorescent (N 4600 - 5400K)",
+ 14: "Cool white fluorescent (W 3900 - 4500K)",
+ 15: "White fluorescent (WW 3200 - 3700K)",
+ 17: "Standard light A",
+ 18: "Standard light B",
+ 19: "Standard light C",
+ 20: "D55",
+ 21: "D65",
+ 22: "D75",
+ 23: "D50",
+ 24: "ISO studio tungsten",
+ 255: "Other"
+ },
+ Flash: {
+ 0x0000: "Flash did not fire",
+ 0x0001: "Flash fired",
+ 0x0005: "Strobe return light not detected",
+ 0x0007: "Strobe return light detected",
+ 0x0009: "Flash fired, compulsory flash mode",
+ 0x000D: "Flash fired, compulsory flash mode, return light not detected",
+ 0x000F: "Flash fired, compulsory flash mode, return light detected",
+ 0x0010: "Flash did not fire, compulsory flash mode",
+ 0x0018: "Flash did not fire, auto mode",
+ 0x0019: "Flash fired, auto mode",
+ 0x001D: "Flash fired, auto mode, return light not detected",
+ 0x001F: "Flash fired, auto mode, return light detected",
+ 0x0020: "No flash function",
+ 0x0041: "Flash fired, red-eye reduction mode",
+ 0x0045: "Flash fired, red-eye reduction mode, return light not detected",
+ 0x0047: "Flash fired, red-eye reduction mode, return light detected",
+ 0x0049: "Flash fired, compulsory flash mode, red-eye reduction mode",
+ 0x004D: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
+ 0x004F: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
+ 0x0059: "Flash fired, auto mode, red-eye reduction mode",
+ 0x005D: "Flash fired, auto mode, return light not detected, red-eye reduction mode",
+ 0x005F: "Flash fired, auto mode, return light detected, red-eye reduction mode"
+ },
+ SensingMethod: {
+ 1: "Not defined",
+ 2: "One-chip color area sensor",
+ 3: "Two-chip color area sensor",
+ 4: "Three-chip color area sensor",
+ 5: "Color sequential area sensor",
+ 7: "Trilinear sensor",
+ 8: "Color sequential linear sensor"
+ },
+ SceneCaptureType: {
+ 0: "Standard",
+ 1: "Landscape",
+ 2: "Portrait",
+ 3: "Night scene"
+ },
+ SceneType: {
+ 1: "Directly photographed"
+ },
+ CustomRendered: {
+ 0: "Normal process",
+ 1: "Custom process"
+ },
+ WhiteBalance: {
+ 0: "Auto white balance",
+ 1: "Manual white balance"
+ },
+ GainControl: {
+ 0: "None",
+ 1: "Low gain up",
+ 2: "High gain up",
+ 3: "Low gain down",
+ 4: "High gain down"
+ },
+ Contrast: {
+ 0: "Normal",
+ 1: "Soft",
+ 2: "Hard"
+ },
+ Saturation: {
+ 0: "Normal",
+ 1: "Low saturation",
+ 2: "High saturation"
+ },
+ Sharpness: {
+ 0: "Normal",
+ 1: "Soft",
+ 2: "Hard"
+ },
+ SubjectDistanceRange: {
+ 0: "Unknown",
+ 1: "Macro",
+ 2: "Close view",
+ 3: "Distant view"
+ },
+ FileSource: {
+ 3: "DSC"
+ },
+
+ Components: {
+ 0: "",
+ 1: "Y",
+ 2: "Cb",
+ 3: "Cr",
+ 4: "R",
+ 5: "G",
+ 6: "B"
+ }
+ }
+ enableXmp() {
+ this.isXmpEnabled = true
+ }
+ disableXmp() {
+ this.isXmpEnabled = false;
+ }
+ /**
+ * 获取图片数据
+ * @param img 图片地址
+ * @param callback 回调 返回图片数据
+ * */
+ getData(img : any, callback : Function) {
+ // if (((self.Image && img instanceof self.Image) || (self.HTMLImageElement && img instanceof self.HTMLImageElement)) && !img.complete)
+ // return false;
+ let file : File = {
+ src: '',
+ exifdata: null,
+ iptcdata: null,
+ xmpdata: null,
+ }
+ if (isBase64(img)) {
+ file.src = img
+ } else if (img.path) {
+ file.src = img.path
+ } else if (isString(img)) {
+ file.src = img
+ } else {
+ return false;
+ }
+
+
+ if (!imageHasData(file)) {
+ getImageData(file, callback);
+ } else {
+ if (callback) {
+ callback.call(file);
+ }
+ }
+ return true;
+ }
+ /**
+ * 获取图片tag
+ * @param img 图片数据
+ * @param tag tag 类型
+ * */
+ getTag(img : File, tag : string) {
+ if (!imageHasData(img)) return;
+ return img.exifdata[tag];
+ }
+ getIptcTag(img : File, tag : string) {
+ if (!imageHasData(img)) return;
+ return img.iptcdata[tag];
+ }
+ getAllTags(img : File) {
+ if (!imageHasData(img)) return {};
+ let a,
+ data = img.exifdata,
+ tags = {};
+ for (a in data) {
+ if (data.hasOwnProperty(a)) {
+ tags[a] = data[a];
+ }
+ }
+ return tags;
+ }
+ getAllIptcTags(img : File) {
+ if (!imageHasData(img)) return {};
+ let a,
+ data = img.iptcdata,
+ tags = {};
+ for (a in data) {
+ if (data.hasOwnProperty(a)) {
+ tags[a] = data[a];
+ }
+ }
+ return tags;
+ }
+ pretty(img : File) {
+ if (!imageHasData(img)) return "";
+ let a,
+ data = img.exifdata,
+ strPretty = "";
+ for (a in data) {
+ if (data.hasOwnProperty(a)) {
+ if (typeof data[a] == "object") {
+ if (data[a] instanceof Number) {
+ strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a]
+ .denominator + "]\r\n";
+ } else {
+ strPretty += a + " : [" + data[a].length + " values]\r\n";
+ }
+ } else {
+ strPretty += a + " : " + data[a] + "\r\n";
+ }
+ }
+ }
+ return strPretty;
+ }
+ readFromBinaryFile(file: ArrayBuffer) {
+ return findEXIFinJPEG(file);
+ }
+}
+
+export const exif = new EXIF()
+// export function getData(img, callback) {
+// const exif = new EXIF()
+// exif.getData(img, callback)
+// }
+
+// export default {getData}
+const ExifTags = exif.Tags
+const TiffTags = exif.TiffTags
+const IFD1Tags = exif.IFD1Tags
+const GPSTags = exif.GPSTags
+const StringValues = exif.StringValues
+
+
+function imageHasData(img : File) : boolean {
+ return !!(img.exifdata);
+}
+
+function objectURLToBlob(url : string, callback : Function) {
+ try {
+ const http = new XMLHttpRequest();
+ http.open("GET", url, true);
+ http.responseType = "blob";
+ http.onload = function (e) {
+ if (this.status == 200 || this.status === 0) {
+ callback(this.response);
+ }
+ };
+ http.send();
+ } catch (e) {
+ console.warn(e)
+ }
+}
+
+
+function getImageData(img : File, callback : Function) {
+ function handleBinaryFile(binFile: ArrayBuffer) {
+ const data = findEXIFinJPEG(binFile);
+ img.exifdata = data ?? {};
+ const iptcdata = findIPTCinJPEG(binFile);
+ img.iptcdata = iptcdata ?? {};
+ if (exif.isXmpEnabled) {
+ const xmpdata = findXMPinJPEG(binFile);
+ img.xmpdata = xmpdata ?? {};
+ }
+ if (callback) {
+ callback.call(img);
+ }
+ }
+
+ if (img.src) {
+ if (/^data\:/i.test(img.src)) { // Data URI
+ // var arrayBuffer = base64ToArrayBuffer(img.src);
+ handleBinaryFile(base64ToArrayBuffer(img.src));
+
+ } else if (/^blob\:/i.test(img.src) && typeof FileReader !== 'undefined') { // Object URL
+ var fileReader = new FileReader();
+ fileReader.onload = function (e) {
+ handleBinaryFile(e.target.result);
+ };
+ objectURLToBlob(img.src, function (blob : Blob) {
+ fileReader.readAsArrayBuffer(blob);
+ });
+ } else if (typeof XMLHttpRequest !== 'undefined') {
+ var http = new XMLHttpRequest();
+ http.onload = function () {
+ if (this.status == 200 || this.status === 0) {
+ handleBinaryFile(http.response);
+ } else {
+ throw "Could not load image";
+ }
+ http = null;
+ };
+ http.open("GET", img.src, true);
+ http.responseType = "arraybuffer";
+ http.send(null);
+ } else {
+ pathToBase64(img.src).then(res => {
+ handleBinaryFile(base64ToArrayBuffer(res));
+ })
+ }
+ } else if (typeof FileReader !== 'undefined' && self.FileReader && (img instanceof self.Blob || img instanceof self.File)) {
+ var fileReader = new FileReader();
+ fileReader.onload = function (e : any) {
+ if (exif.debug) console.log("Got file of length " + e.target.result.byteLength);
+ handleBinaryFile(e.target.result);
+ };
+
+ fileReader.readAsArrayBuffer(img);
+ }
+}
+
+function findEXIFinJPEG(file: ArrayBuffer) {
+ const dataView = new DataView(file);
+
+ if (exif.debug) console.log("Got file of length " + file.byteLength);
+ if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
+ if (exif.debug) console.log("Not a valid JPEG");
+ return false; // not a valid jpeg
+ }
+
+ let offset = 2,
+ length = file.byteLength,
+ marker;
+
+ while (offset < length) {
+ if (dataView.getUint8(offset) != 0xFF) {
+ if (exif.debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(
+ offset));
+ return false; // not a valid marker, something is wrong
+ }
+
+ marker = dataView.getUint8(offset + 1);
+ if (exif.debug) console.log(marker);
+
+ // we could implement handling for other markers here,
+ // but we're only looking for 0xFFE1 for EXIF data
+
+ if (marker == 225) {
+ if (exif.debug) console.log("Found 0xFFE1 marker");
+
+ return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);
+
+ // offset += 2 + file.getShortAt(offset+2, true);
+
+ } else {
+ offset += 2 + dataView.getUint16(offset + 2);
+ }
+
+ }
+
+}
+
+function findIPTCinJPEG(file: ArrayBuffer) {
+ const dataView = new DataView(file);
+
+ if (exif.debug) console.log("Got file of length " + file.byteLength);
+ if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
+ if (exif.debug) console.log("Not a valid JPEG");
+ return false; // not a valid jpeg
+ }
+
+ let offset = 2,
+ length = file.byteLength;
+
+
+ const isFieldSegmentStart = function (dataView, offset: number) {
+ return (
+ dataView.getUint8(offset) === 0x38 &&
+ dataView.getUint8(offset + 1) === 0x42 &&
+ dataView.getUint8(offset + 2) === 0x49 &&
+ dataView.getUint8(offset + 3) === 0x4D &&
+ dataView.getUint8(offset + 4) === 0x04 &&
+ dataView.getUint8(offset + 5) === 0x04
+ );
+ };
+
+ while (offset < length) {
+
+ if (isFieldSegmentStart(dataView, offset)) {
+
+ // Get the length of the name header (which is padded to an even number of bytes)
+ var nameHeaderLength = dataView.getUint8(offset + 7);
+ if (nameHeaderLength % 2 !== 0) nameHeaderLength += 1;
+ // Check for pre photoshop 6 format
+ if (nameHeaderLength === 0) {
+ // Always 4
+ nameHeaderLength = 4;
+ }
+
+ var startOffset = offset + 8 + nameHeaderLength;
+ var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength);
+
+ return readIPTCData(file, startOffset, sectionLength);
+
+ break;
+
+ }
+
+
+ // Not the marker, continue searching
+ offset++;
+
+ }
+
+}
+
+const IptcFieldMap = {
+ 0x78: 'caption',
+ 0x6E: 'credit',
+ 0x19: 'keywords',
+ 0x37: 'dateCreated',
+ 0x50: 'byline',
+ 0x55: 'bylineTitle',
+ 0x7A: 'captionWriter',
+ 0x69: 'headline',
+ 0x74: 'copyright',
+ 0x0F: 'category'
+};
+
+function readIPTCData(file: ArrayBuffer, startOffset: number, sectionLength: number) {
+ const dataView = new DataView(file);
+ let data = {};
+ let fieldValue, fieldName, dataSize, segmentType, segmentSize;
+ let segmentStartPos = startOffset;
+ while (segmentStartPos < startOffset + sectionLength) {
+ if (dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos + 1) === 0x02) {
+ segmentType = dataView.getUint8(segmentStartPos + 2);
+ if (segmentType in IptcFieldMap) {
+ dataSize = dataView.getInt16(segmentStartPos + 3);
+ segmentSize = dataSize + 5;
+ fieldName = IptcFieldMap[segmentType];
+ fieldValue = getStringFromDB(dataView, segmentStartPos + 5, dataSize);
+ // Check if we already stored a value with this name
+ if (data.hasOwnProperty(fieldName)) {
+ // Value already stored with this name, create multivalue field
+ if (data[fieldName] instanceof Array) {
+ data[fieldName].push(fieldValue);
+ } else {
+ data[fieldName] = [data[fieldName], fieldValue];
+ }
+ } else {
+ data[fieldName] = fieldValue;
+ }
+ }
+
+ }
+ segmentStartPos++;
+ }
+ return data;
+}
+
+function readTags(file: DataView, tiffStart: number, dirStart: number, strings: any[], bigEnd: number) {
+ let entries = file.getUint16(dirStart, !bigEnd),
+ tags = {},
+ entryOffset, tag;
+
+ for (let i = 0; i < entries; i++) {
+ entryOffset = dirStart + i * 12 + 2;
+ tag = strings[file.getUint16(entryOffset, !bigEnd)];
+ if (!tag && exif.debug) console.log("Unknown tag: " + file.getUint16(entryOffset, !bigEnd));
+ tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd);
+ }
+ return tags;
+}
+
+function readTagValue(file: DataView, entryOffset: number, tiffStart: number, dirStart: number, bigEnd: number) {
+ let type = file.getUint16(entryOffset + 2, !bigEnd),
+ numValues = file.getUint32(entryOffset + 4, !bigEnd),
+ valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart,
+ offset,
+ vals, val, n,
+ numerator, denominator;
+
+ switch (type) {
+ case 1: // byte, 8-bit unsigned int
+ case 7: // undefined, 8-bit byte, value depending on field
+ if (numValues == 1) {
+ return file.getUint8(entryOffset + 8, !bigEnd);
+ } else {
+ offset = numValues > 4 ? valueOffset : (entryOffset + 8);
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getUint8(offset + n);
+ }
+ return vals;
+ }
+
+ case 2: // ascii, 8-bit byte
+ offset = numValues > 4 ? valueOffset : (entryOffset + 8);
+ return getStringFromDB(file, offset, numValues - 1);
+
+ case 3: // short, 16 bit int
+ if (numValues == 1) {
+ return file.getUint16(entryOffset + 8, !bigEnd);
+ } else {
+ offset = numValues > 2 ? valueOffset : (entryOffset + 8);
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getUint16(offset + 2 * n, !bigEnd);
+ }
+ return vals;
+ }
+
+ case 4: // long, 32 bit int
+ if (numValues == 1) {
+ return file.getUint32(entryOffset + 8, !bigEnd);
+ } else {
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getUint32(valueOffset + 4 * n, !bigEnd);
+ }
+ return vals;
+ }
+
+ case 5: // rational = two long values, first is numerator, second is denominator
+ if (numValues == 1) {
+ numerator = file.getUint32(valueOffset, !bigEnd);
+ denominator = file.getUint32(valueOffset + 4, !bigEnd);
+ val = new Number(numerator / denominator);
+ val.numerator = numerator;
+ val.denominator = denominator;
+ return val;
+ } else {
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ numerator = file.getUint32(valueOffset + 8 * n, !bigEnd);
+ denominator = file.getUint32(valueOffset + 4 + 8 * n, !bigEnd);
+ vals[n] = new Number(numerator / denominator);
+ vals[n].numerator = numerator;
+ vals[n].denominator = denominator;
+ }
+ return vals;
+ }
+
+ case 9: // slong, 32 bit signed int
+ if (numValues == 1) {
+ return file.getInt32(entryOffset + 8, !bigEnd);
+ } else {
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getInt32(valueOffset + 4 * n, !bigEnd);
+ }
+ return vals;
+ }
+
+ case 10: // signed rational, two slongs, first is numerator, second is denominator
+ if (numValues == 1) {
+ return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset + 4, !bigEnd);
+ } else {
+ vals = [];
+ for (n = 0; n < numValues; n++) {
+ vals[n] = file.getInt32(valueOffset + 8 * n, !bigEnd) / file.getInt32(valueOffset + 4 + 8 *
+ n, !bigEnd);
+ }
+ return vals;
+ }
+ }
+}
+/**
+ * Given an IFD (Image File Directory) start offset
+ * returns an offset to next IFD or 0 if it's the last IFD.
+ */
+function getNextIFDOffset(dataView: DataView, dirStart: number, bigEnd: number) {
+ //the first 2bytes means the number of directory entries contains in this IFD
+ var entries = dataView.getUint16(dirStart, !bigEnd);
+
+ // After last directory entry, there is a 4bytes of data,
+ // it means an offset to next IFD.
+ // If its value is '0x00000000', it means this is the last IFD and there is no linked IFD.
+
+ return dataView.getUint32(dirStart + 2 + entries * 12, !bigEnd); // each entry is 12 bytes long
+}
+
+function readThumbnailImage(dataView: DataView, tiffStart: number, firstIFDOffset: number, bigEnd: number) {
+ // get the IFD1 offset
+ const IFD1OffsetPointer = getNextIFDOffset(dataView, tiffStart + firstIFDOffset, bigEnd);
+
+ if (!IFD1OffsetPointer) {
+ // console.log('******** IFD1Offset is empty, image thumb not found ********');
+ return {};
+ } else if (IFD1OffsetPointer > dataView.byteLength) { // this should not happen
+ // console.log('******** IFD1Offset is outside the bounds of the DataView ********');
+ return {};
+ }
+ // console.log('******* thumbnail IFD offset (IFD1) is: %s', IFD1OffsetPointer);
+
+ let thumbTags : any = readTags(dataView, tiffStart, tiffStart + IFD1OffsetPointer, IFD1Tags, bigEnd)
+
+ // EXIF 2.3 specification for JPEG format thumbnail
+
+ // If the value of Compression(0x0103) Tag in IFD1 is '6', thumbnail image format is JPEG.
+ // Most of Exif image uses JPEG format for thumbnail. In that case, you can get offset of thumbnail
+ // by JpegIFOffset(0x0201) Tag in IFD1, size of thumbnail by JpegIFByteCount(0x0202) Tag.
+ // Data format is ordinary JPEG format, starts from 0xFFD8 and ends by 0xFFD9. It seems that
+ // JPEG format and 160x120pixels of size are recommended thumbnail format for Exif2.1 or later.
+
+ if (thumbTags['Compression'] && typeof Blob !== 'undefined') {
+ // console.log('Thumbnail image found!');
+
+ switch (thumbTags['Compression']) {
+ case 6:
+ // console.log('Thumbnail image format is JPEG');
+ if (thumbTags.JpegIFOffset && thumbTags.JpegIFByteCount) {
+ // extract the thumbnail
+ var tOffset = tiffStart + thumbTags.JpegIFOffset;
+ var tLength = thumbTags.JpegIFByteCount;
+ thumbTags['blob'] = new Blob([new Uint8Array(dataView.buffer, tOffset, tLength)], {
+ type: 'image/jpeg'
+ });
+ }
+ break;
+
+ case 1:
+ console.log("Thumbnail image format is TIFF, which is not implemented.");
+ break;
+ default:
+ console.log("Unknown thumbnail image format '%s'", thumbTags['Compression']);
+ }
+ } else if (thumbTags['PhotometricInterpretation'] == 2) {
+ console.log("Thumbnail image format is RGB, which is not implemented.");
+ }
+ return thumbTags;
+}
+
+function getStringFromDB(buffer: DataView, start: number, length: number) {
+ let outstr = "";
+ for (let n = start; n < start + length; n++) {
+ outstr += String.fromCharCode(buffer.getUint8(n));
+ }
+ return outstr;
+}
+
+function readEXIFData(file: DataView, start: number) {
+ if (getStringFromDB(file, start, 4) != "Exif") {
+ if (exif.debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4));
+ return false;
+ }
+
+ let bigEnd,
+ tags, tag,
+ exifData, gpsData,
+ tiffOffset = start + 6;
+
+ // test for TIFF validity and endianness
+ if (file.getUint16(tiffOffset) == 0x4949) {
+ bigEnd = false;
+ } else if (file.getUint16(tiffOffset) == 0x4D4D) {
+ bigEnd = true;
+ } else {
+ if (exif.debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
+ return false;
+ }
+
+ if (file.getUint16(tiffOffset + 2, !bigEnd) != 0x002A) {
+ if (exif.debug) console.log("Not valid TIFF data! (no 0x002A)");
+ return false;
+ }
+
+ const firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd);
+
+ if (firstIFDOffset < 0x00000008) {
+ if (exif.debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset + 4,
+ !bigEnd));
+ return false;
+ }
+
+ tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd);
+
+ if (tags.ExifIFDPointer) {
+ exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd);
+ for (tag in exifData) {
+ switch (tag) {
+ case "LightSource":
+ case "Flash":
+ case "MeteringMode":
+ case "ExposureProgram":
+ case "SensingMethod":
+ case "SceneCaptureType":
+ case "SceneType":
+ case "CustomRendered":
+ case "WhiteBalance":
+ case "GainControl":
+ case "Contrast":
+ case "Saturation":
+ case "Sharpness":
+ case "SubjectDistanceRange":
+ case "FileSource":
+ exifData[tag] = StringValues[tag][exifData[tag]];
+ break;
+
+ case "ExifVersion":
+ case "FlashpixVersion":
+ exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2],
+ exifData[tag][3]);
+ break;
+
+ case "ComponentsConfiguration":
+ exifData[tag] =
+ StringValues.Components[exifData[tag][0]] +
+ StringValues.Components[exifData[tag][1]] +
+ StringValues.Components[exifData[tag][2]] +
+ StringValues.Components[exifData[tag][3]];
+ break;
+ }
+ tags[tag] = exifData[tag];
+ }
+ }
+
+ if (tags.GPSInfoIFDPointer) {
+ gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);
+ for (tag in gpsData) {
+ switch (tag) {
+ case "GPSVersionID":
+ gpsData[tag] = gpsData[tag][0] +
+ "." + gpsData[tag][1] +
+ "." + gpsData[tag][2] +
+ "." + gpsData[tag][3];
+ break;
+ }
+ tags[tag] = gpsData[tag];
+ }
+ }
+
+ // extract thumbnail
+ tags['thumbnail'] = readThumbnailImage(file, tiffOffset, firstIFDOffset, bigEnd);
+
+ return tags;
+}
+
+function findXMPinJPEG(file: ArrayBuffer) {
+
+ if (!('DOMParser' in self)) {
+ // console.warn('XML parsing not supported without DOMParser');
+ return;
+ }
+ const dataView = new DataView(file);
+
+ if (exif.debug) console.log("Got file of length " + file.byteLength);
+ if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
+ if (exif.debug) console.log("Not a valid JPEG");
+ return false; // not a valid jpeg
+ }
+
+ let offset = 2,
+ length = file.byteLength,
+ dom = new DOMParser();
+
+ while (offset < (length - 4)) {
+ if (getStringFromDB(dataView, offset, 4) == "http") {
+ const startOffset = offset - 1;
+ const sectionLength = dataView.getUint16(offset - 2) - 1;
+ let xmpString = getStringFromDB(dataView, startOffset, sectionLength)
+ const xmpEndIndex = xmpString.indexOf('xmpmeta>') + 8;
+ xmpString = xmpString.substring(xmpString.indexOf(' 0) {
+ json['@attributes'] = {};
+ for (var j = 0; j < xml.attributes.length; j++) {
+ var attribute = xml.attributes.item(j);
+ json['@attributes'][attribute.nodeName] = attribute.nodeValue;
+ }
+ }
+ } else if (xml.nodeType == 3) { // text node
+ return xml.nodeValue;
+ }
+
+ // deal with children
+ if (xml.hasChildNodes()) {
+ for (var i = 0; i < xml.childNodes.length; i++) {
+ var child = xml.childNodes.item(i);
+ var nodeName = child.nodeName;
+ if (json[nodeName] == null) {
+ json[nodeName] = xml2json(child);
+ } else {
+ if (json[nodeName].push == null) {
+ var old = json[nodeName];
+ json[nodeName] = [];
+ json[nodeName].push(old);
+ }
+ json[nodeName].push(xml2json(child));
+ }
+ }
+ }
+
+ return json;
+}
+
+function xml2Object(xml: any) {
+ try {
+ var obj = {};
+ if (xml.children.length > 0) {
+ for (var i = 0; i < xml.children.length; i++) {
+ var item = xml.children.item(i);
+ var attributes = item.attributes;
+ for (var idx in attributes) {
+ var itemAtt = attributes[idx];
+ var dataKey = itemAtt.nodeName;
+ var dataValue = itemAtt.nodeValue;
+
+ if (dataKey !== undefined) {
+ obj[dataKey] = dataValue;
+ }
+ }
+ var nodeName = item.nodeName;
+
+ if (typeof (obj[nodeName]) == "undefined") {
+ obj[nodeName] = xml2json(item);
+ } else {
+ if (typeof (obj[nodeName].push) == "undefined") {
+ var old = obj[nodeName];
+
+ obj[nodeName] = [];
+ obj[nodeName].push(old);
+ }
+ obj[nodeName].push(xml2json(item));
+ }
+ }
+ } else {
+ obj = xml.textContent;
+ }
+ return obj;
+ } catch (e) {
+ console.log(e.message);
+ }
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/fillZero/index.ts b/src/uni_modules/lime-shared/fillZero/index.ts
new file mode 100644
index 0000000..9952c45
--- /dev/null
+++ b/src/uni_modules/lime-shared/fillZero/index.ts
@@ -0,0 +1,11 @@
+// @ts-nocheck
+/**
+ * 在数字前填充零,返回字符串形式的结果
+ * @param number 要填充零的数字
+ * @param length 填充零后的字符串长度,默认为2
+ * @returns 填充零后的字符串
+ */
+export function fillZero(number: number, length: number = 2): string {
+ // 将数字转换为字符串,然后使用 padStart 方法填充零到指定长度
+ return `${number}`.padStart(length, '0');
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/floatAdd/index.ts b/src/uni_modules/lime-shared/floatAdd/index.ts
new file mode 100644
index 0000000..aad3929
--- /dev/null
+++ b/src/uni_modules/lime-shared/floatAdd/index.ts
@@ -0,0 +1,36 @@
+import { isNumber } from '../isNumber'
+/**
+ * 返回两个浮点数相加的结果
+ * @param num1 第一个浮点数
+ * @param num2 第二个浮点数
+ * @returns 两个浮点数的相加结果
+ */
+export function floatAdd(num1 : number, num2 : number) : number {
+ // 检查 num1 和 num2 是否为数字类型
+ if (!(isNumber(num1) || isNumber(num2))) {
+ console.warn('Please pass in the number type');
+ return NaN;
+ }
+
+ let r1 : number, r2 : number, m : number;
+
+ try {
+ // 获取 num1 小数点后的位数
+ r1 = num1.toString().split('.')[1].length;
+ } catch (error) {
+ r1 = 0;
+ }
+
+ try {
+ // 获取 num2 小数点后的位数
+ r2 = num2.toString().split('.')[1].length;
+ } catch (error) {
+ r2 = 0;
+ }
+
+ // 计算需要扩大的倍数
+ m = Math.pow(10, Math.max(r1, r2));
+
+ // 返回相加结果
+ return (num1 * m + num2 * m) / m;
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/floatDiv/index.ts b/src/uni_modules/lime-shared/floatDiv/index.ts
new file mode 100644
index 0000000..195d4ab
--- /dev/null
+++ b/src/uni_modules/lime-shared/floatDiv/index.ts
@@ -0,0 +1,45 @@
+import { floatMul } from '../floatMul';
+import { isNumber } from '../isNumber';
+
+/**
+ * 除法函数,用于处理浮点数除法并保持精度。
+ * @param {number} num1 - 被除数。
+ * @param {number} num2 - 除数。
+ * @returns {number} 除法运算的结果,保留正确的精度。
+ */
+export function floatDiv(num1:number, num2:number):number {
+ // 如果传入的不是数字类型,则打印警告并返回NaN
+ if (!isNumber(num1) || !isNumber(num2)) {
+ console.warn('请传入数字类型');
+ return NaN;
+ }
+
+ let m1 = 0, // 被除数小数点后的位数
+ m2 = 0, // 除数小数点后的位数
+ s1 = num1.toString(), // 将被除数转换为字符串
+ s2 = num2.toString(); // 将除数转换为字符串
+
+ // 计算被除数小数点后的位数
+ try {
+ m1 += s1.split('.')[1].length;
+ } catch (error) {}
+
+ // 计算除数小数点后的位数
+ try {
+ m2 += s2.split('.')[1].length;
+ } catch (error) {}
+
+ // 进行除法运算并处理小数点后的位数,使用之前定义的乘法函数保持精度
+ // #ifdef APP-ANDROID
+ return floatMul(
+ parseFloat(s1.replace('.', '')) / parseFloat(s2.replace('.', '')),
+ Math.pow(10, m2 - m1),
+ );
+ // #endif
+ // #ifndef APP-ANDROID
+ return floatMul(
+ Number(s1.replace('.', '')) / Number(s2.replace('.', '')),
+ Math.pow(10, m2 - m1),
+ );
+ // #endif
+}
diff --git a/src/uni_modules/lime-shared/floatMul/index.ts b/src/uni_modules/lime-shared/floatMul/index.ts
new file mode 100644
index 0000000..51a867e
--- /dev/null
+++ b/src/uni_modules/lime-shared/floatMul/index.ts
@@ -0,0 +1,44 @@
+// @ts-nocheck
+import {isNumber} from '../isNumber';
+// #ifdef APP-ANDROID
+import BigDecimal from 'java.math.BigDecimal'
+// import BigDecimal from 'java.math.BigDecimal'
+// import StringBuilder from 'java.lang.StringBuilder'
+// import java.math.BigDecimal;
+// #endif
+
+/**
+ * 乘法函数,用于处理浮点数乘法并保持精度。
+ * @param {number} num1 - 第一个乘数。
+ * @param {number} num2 - 第二个乘数。
+ * @returns {number} 乘法运算的结果,保留正确的精度。
+ */
+export function floatMul(num1 : number, num2 : number) : number {
+ if (!(isNumber(num1) || isNumber(num2))) {
+ console.warn('Please pass in the number type');
+ return NaN;
+ }
+ let m = 0;
+ // #ifdef APP-ANDROID
+ let s1 = BigDecimal.valueOf(num1.toDouble()).toPlainString(); //new UTSNumber(num1).toString() // //`${num1.toFloat()}`// num1.toString(),
+ let s2 = BigDecimal.valueOf(num2.toDouble()).toPlainString(); //new UTSNumber(num2).toString() //`${num2.toFloat()}`//.toString();
+ // #endif
+ // #ifndef APP-ANDROID
+ let s1:string = `${num1}`// num1.toString(),
+ let s2:string = `${num2}`//.toString();
+ // #endif
+
+ try {
+ m += s1.split('.')[1].length;
+ } catch (error) { }
+ try {
+ m += s2.split('.')[1].length;
+ } catch (error) { }
+
+ // #ifdef APP-ANDROID
+ return parseFloat(s1.replace('.', '')) * parseFloat(s2.replace('.', '')) / Math.pow(10, m);
+ // #endif
+ // #ifndef APP-ANDROID
+ return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m);
+ // #endif
+}
diff --git a/src/uni_modules/lime-shared/floatSub/index.ts b/src/uni_modules/lime-shared/floatSub/index.ts
new file mode 100644
index 0000000..9bc25cb
--- /dev/null
+++ b/src/uni_modules/lime-shared/floatSub/index.ts
@@ -0,0 +1,32 @@
+import { isNumber } from '../isNumber';
+/**
+ * 减法函数,用于处理浮点数减法并保持精度。
+ * @param {number} num1 - 被减数。
+ * @param {number} num2 - 减数。
+ * @returns {number} 减法运算的结果,保留正确的精度。
+ */
+export function floatSub(num1 : number, num2 : number) : number {
+ if (!(isNumber(num1) || isNumber(num2))) {
+ console.warn('Please pass in the number type');
+ return NaN;
+ }
+ let r1:number, r2:number, m:number, n:number;
+ try {
+ r1 = num1.toString().split('.')[1].length;
+ } catch (error) {
+ r1 = 0;
+ }
+ try {
+ r2 = num2.toString().split('.')[1].length;
+ } catch (error) {
+ r2 = 0;
+ }
+ m = Math.pow(10, Math.max(r1, r2));
+ n = r1 >= r2 ? r1 : r2;
+ // #ifndef APP-ANDROID
+ return Number(((num1 * m - num2 * m) / m).toFixed(n));
+ // #endif
+ // #ifdef APP-ANDROID
+ return parseFloat(((num1 * m - num2 * m) / m).toFixed(n));
+ // #endif
+}
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/getClassStr/index.ts b/src/uni_modules/lime-shared/getClassStr/index.ts
new file mode 100644
index 0000000..ef8c7d6
--- /dev/null
+++ b/src/uni_modules/lime-shared/getClassStr/index.ts
@@ -0,0 +1,53 @@
+// @ts-nocheck
+
+// #ifdef UNI-APP-X && APP
+import { isNumber } from '../isNumber'
+import { isString } from '../isString'
+import { isDef } from '../isDef'
+// #endif
+
+/**
+ * 获取对象的类名字符串
+ * @param obj - 需要处理的对象
+ * @returns 由对象属性作为类名组成的字符串
+ */
+export function getClassStr(obj : T) : string {
+ let classNames : string[] = [];
+ // #ifdef UNI-APP-X && APP
+ if (obj instanceof UTSJSONObject) {
+ (obj as UTSJSONObject).toMap().forEach((value, key) => {
+ if (isDef(value)) {
+ if (isNumber(value)) {
+ classNames.push(key);
+ }
+ if (isString(value) && value !== '') {
+ classNames.push(key);
+ }
+ if (typeof value == 'boolean' && (value as boolean)) {
+ classNames.push(key);
+ }
+ }
+ })
+ }
+ // #endif
+ // #ifndef UNI-APP-X && APP
+ // 遍历对象的属性
+ for (let key in obj) {
+ // 检查属性确实属于对象自身且其值为true
+ if ((obj as any).hasOwnProperty(key) && obj[key]) {
+ // 将属性名添加到类名数组中
+ classNames.push(key);
+ }
+ }
+ // #endif
+
+
+ // 将类名数组用空格连接成字符串并返回
+ return classNames.join(' ');
+}
+
+
+// 示例
+// const obj = { foo: true, bar: false, baz: true };
+// const classNameStr = getClassStr(obj);
+// console.log(classNameStr); // 输出: "foo baz"
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/getCurrentPage/index.ts b/src/uni_modules/lime-shared/getCurrentPage/index.ts
new file mode 100644
index 0000000..af9a9d2
--- /dev/null
+++ b/src/uni_modules/lime-shared/getCurrentPage/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
diff --git a/src/uni_modules/lime-shared/getCurrentPage/uvue.uts b/src/uni_modules/lime-shared/getCurrentPage/uvue.uts
new file mode 100644
index 0000000..9e96d2b
--- /dev/null
+++ b/src/uni_modules/lime-shared/getCurrentPage/uvue.uts
@@ -0,0 +1,5 @@
+// @ts-nocheck
+export const getCurrentPage = ():Page => {
+ const pages = getCurrentPages();
+ return pages[pages.length - 1]
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/getCurrentPage/vue.ts b/src/uni_modules/lime-shared/getCurrentPage/vue.ts
new file mode 100644
index 0000000..79ecac8
--- /dev/null
+++ b/src/uni_modules/lime-shared/getCurrentPage/vue.ts
@@ -0,0 +1,6 @@
+// @ts-nocheck
+/** 获取当前页 */
+export const getCurrentPage = () => {
+ const pages = getCurrentPages();
+ return pages[pages.length - 1] //as T & WechatMiniprogram.Page.TrivialInstance;
+};
\ No newline at end of file
diff --git a/src/uni_modules/lime-shared/getLocalFilePath/index.ts b/src/uni_modules/lime-shared/getLocalFilePath/index.ts
new file mode 100644
index 0000000..c496a07
--- /dev/null
+++ b/src/uni_modules/lime-shared/getLocalFilePath/index.ts
@@ -0,0 +1,62 @@
+// @ts-nocheck
+// #ifdef APP-NVUE || APP-VUE
+export const getLocalFilePath = (path : string) => {
+ if (typeof plus == 'undefined') return path
+ if (/^(_www|_doc|_documents|_downloads|file:\/\/|\/storage\/emulated\/0\/)/.test(path)) return path
+ if (/^\//.test(path)) {
+ const localFilePath = plus.io.convertAbsoluteFileSystem(path)
+ if (localFilePath !== path) {
+ return localFilePath
+ } else {
+ path = path.slice(1)
+ }
+ }
+ return '_www/' + path
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export { getResourcePath as getLocalFilePath } from '@/uni_modules/lime-file-utils'
+// export const getLocalFilePath = (path : string) : string => {
+// let uri = path
+// if (uri.startsWith("http") || uri.startsWith("