Pārlūkot izejas kodu

增加团餐使用图片;
增加组件modal和api滚动列表;
优化uview的navbar和upload组件;
优化项目的菜单跳转的代码(full和index_nav);

郭鹏飞 11 mēneši atpakaļ
vecāks
revīzija
e261167bfe
72 mainītis faili ar 1366 papildinājumiem un 4341 dzēšanām
  1. 21 0
      common/router/modules/routes.js
  2. 21 42
      components/index_nav.vue
  3. 158 0
      components/list-scroll-view/index.vue
  4. 75 0
      components/list-scroll-view/list-expand.vue
  5. 176 0
      components/modal/index.vue
  6. 0 546
      components/uni-calendar/calendar.js
  7. 0 179
      components/uni-calendar/uni-calendar-item.vue
  8. 0 512
      components/uni-calendar/uni-calendar.vue
  9. 0 352
      components/uni-calendar/util.js
  10. 0 100
      components/uni-forms/changelog.md
  11. 0 632
      components/uni-forms/components/uni-forms-item/uni-forms-item.vue
  12. 0 404
      components/uni-forms/components/uni-forms/uni-forms.vue
  13. 0 293
      components/uni-forms/components/uni-forms/utils.js
  14. 0 486
      components/uni-forms/components/uni-forms/validate.js
  15. 0 89
      components/uni-forms/package.json
  16. 0 23
      components/uni-forms/readme.md
  17. 30 43
      main.js
  18. 8 0
      pages.json
  19. 7 4
      pages/financial/balanceBill.vue
  20. 10 2
      pages/financial/management.vue
  21. 8 0
      pages/groupMeal/goods/form-step1.vue
  22. 28 0
      pages/groupMeal/goods/list.vue
  23. 21 0
      pages/groupMeal/localDict.js
  24. 9 8
      pages/groupMeal/orders/order-alist.vue
  25. 417 395
      pages/groupMeal/orders/order-details.vue
  26. 119 149
      pages/groupMeal/orders/refund.vue
  27. 59 0
      pages/groupMeal/tabbar/index.vue
  28. 29 35
      pages/groupMeal/users/bankCard-list.vue
  29. 7 9
      pages/groupMeal/users/bankCard-select.vue
  30. 13 5
      pages/groupMeal/users/index.vue
  31. 116 0
      pages/groupMeal/users/team-member.vue
  32. 8 8
      pages/groupMeal/users/withdrawal.vue
  33. 13 18
      pages/index/full.vue
  34. BIN
      static/groupMeal/icon_bankadd.png
  35. BIN
      static/groupMeal/icon_build.png
  36. BIN
      static/groupMeal/icon_file.png
  37. BIN
      static/groupMeal/icon_more.png
  38. BIN
      static/groupMeal/icon_user.png
  39. BIN
      static/groupMeal/iconback/yinhang-dongya.png
  40. BIN
      static/groupMeal/iconback/yinhang-gongshang.png
  41. BIN
      static/groupMeal/iconback/yinhang-guangda.png
  42. BIN
      static/groupMeal/iconback/yinhang-hangzhou.png
  43. BIN
      static/groupMeal/iconback/yinhang-hengfeng.png
  44. BIN
      static/groupMeal/iconback/yinhang-huaqi.png
  45. BIN
      static/groupMeal/iconback/yinhang-huaxia.png
  46. BIN
      static/groupMeal/iconback/yinhang-huifeng.png
  47. BIN
      static/groupMeal/iconback/yinhang-jianshe.png
  48. BIN
      static/groupMeal/iconback/yinhang-jiaotong.png
  49. BIN
      static/groupMeal/iconback/yinhang-minsheng.png
  50. BIN
      static/groupMeal/iconback/yinhang-nanjing.png
  51. BIN
      static/groupMeal/iconback/yinhang-ningbo.png
  52. BIN
      static/groupMeal/iconback/yinhang-nonghang.png
  53. BIN
      static/groupMeal/iconback/yinhang-pingan.png
  54. BIN
      static/groupMeal/iconback/yinhang-pufa.png
  55. BIN
      static/groupMeal/iconback/yinhang-shanghai.png
  56. BIN
      static/groupMeal/iconback/yinhang-suning.png
  57. BIN
      static/groupMeal/iconback/yinhang-xingye.png
  58. BIN
      static/groupMeal/iconback/yinhang-youzhengchuxu.png
  59. BIN
      static/groupMeal/iconback/yinhang-zhada.png
  60. BIN
      static/groupMeal/iconback/yinhang-zhaoshang.png
  61. BIN
      static/groupMeal/iconback/yinhang-zheshang.png
  62. BIN
      static/groupMeal/iconback/yinhang-zhongguoyinhang.png
  63. BIN
      static/groupMeal/iconback/yinhang-zhongxin.png
  64. BIN
      static/groupMeal/tab_1.png
  65. BIN
      static/groupMeal/tab_2.png
  66. BIN
      static/groupMeal/tab_3.png
  67. BIN
      static/groupMeal/tab_un1.png
  68. BIN
      static/groupMeal/tab_un2.png
  69. BIN
      static/groupMeal/tab_un3.png
  70. BIN
      static/index/groupMeal.png
  71. 8 2
      uni_modules/uview-ui/components/u-navbar/u-navbar.vue
  72. 5 5
      uni_modules/uview-ui/components/u-upload/u-upload.vue

+ 21 - 0
common/router/modules/routes.js

@@ -606,6 +606,20 @@ const routes = [{
 			title: '订单明细',
 		},
 	},
+	{
+		path: '/pages/groupMeal/orders/order-details',
+		name: 'groupMealOrdersDetails',
+		meta: {
+			title: '订单详情',
+		},
+	},
+	{
+		path: '/pages/groupMeal/orders/refund',
+		name: 'groupMealOrdersRefund',
+		meta: {
+			title: '协商记录(退款)',
+		},
+	},
 	{
 		path: '/pages/groupMeal/users/index',
 		name: 'groupMealUsersIndex',
@@ -640,6 +654,13 @@ const routes = [{
 		meta: {
 			title: '银行卡编辑',
 		},
+	},
+	{
+		path: '/pages/groupMeal/users/team-member',
+		name: 'groupMealUsersTeamMember',
+		meta: {
+			title: '我的团长',
+		},
 	}
 ]
 export default routes

+ 21 - 42
components/index_nav.vue

@@ -21,15 +21,18 @@
 				dotStyle: true,
 				swiperList: [{
 						name: '店铺设置',
-						url: '/static/index/shop.png'
+						url: '/static/index/shop.png',
+						path: '/pages/store/settings'
 					},
 					{
-						name: '平台活动',
-						url: '/static/index/activity.png'
+						name: '团餐活动',
+						url: '/static/index/groupMeal.png',
+						path: '/pages/groupMeal/goods/list'
 					},
 					{
 						name: '优惠券',
-						url: '/static/index/coupon.png'
+						url: '/static/index/coupon.png',
+						path: '/pages/coupon/coupon'
 					},
 					{
 						name: '退款管理',
@@ -41,65 +44,41 @@
 					},
 					// {
 					// 	name: '审核查询',
-					// 	url: '/static/index/audit.png'
+					// 	url: '/static/index/audit.png',
+					// 	path: '/pages/store/examine'
 					// },
 					{
 						name: '商品管理',
-						url: '/static/index/product.png'
+						url: '/static/index/product.png',
+						path: '/pages/product/index'
 					},
 					{
 						name: '提现管理',
-					url: '/static/index/withdraw.png'
+						url: '/static/index/withdraw.png'
 					},
 					{
 						name: '秒杀活动',
-					url: '/static/index/seckill.png'
+						url: '/static/index/seckill.png'
 					},
 					{
 						name: '客户评价',
-					url: '/static/index/evaluate.png'
+						url: '/static/index/evaluate.png',
+						path: '/pages/evaluate/evaluate'
 					},
 					{
 						name: '全部服务',
-					url: '/static/index/all.png'
+						url: '/static/index/all.png',
+						path: '/pages/index/full'
 					},
 				]
 			}
 		},
 		methods: {
 			jump(item) {
-				
-				if (item.name == '客户评价') {
-					uni.navigateTo({
-						url: '/pages/evaluate/evaluate'
-					})
-				} else if (item.name == '商品管理') {
-					uni.navigateTo({
-						url: '/pages/product/index'
-					})
-				} else if (item.name == '全部服务') {
-					uni.navigateTo({
-						url: '/pages/index/full'
-					})
-				} else if (item.name == '店铺设置') {
-					uni.navigateTo({
-						url: '/pages/store/settings'
-					})
-				} else if (item.name == '优惠券') {
-					uni.navigateTo({
-						url: '/pages/coupon/coupon'
-					})
-				} else if (item.name == '平台活动') {
-					uni.navigateTo({
-						url: '/pages/groupMeal/goods/list'
-					})
-				}
-				// if (item.name == '审核查询') {
-				// 	uni.navigateTo({
-				// 		url: '/pages/store/examine'
-				// 	})
-				// }
-				
+				if (!item.path) return;
+				uni.navigateTo({
+					url: item.path
+				})
 			}
 		}
 	}

+ 158 - 0
components/list-scroll-view/index.vue

@@ -0,0 +1,158 @@
+<template>
+	<view class="lsv-container">
+		<mescroll-uni 
+			ref="mescrollRef"
+			:fixed="false"
+			:up="upOption" 
+			:down="downOption" 
+			@up="upCallback"
+			@down="downCallback"
+			@init="mescrollInit"
+			@scroll="onScroll">
+			<view class="lsv-list">
+				<slot name="list" :data="dataList" :is-scrolling="isScrolling"></slot>
+			</view>
+		</mescroll-uni>
+	</view>
+</template>
+
+<script>
+export default {
+	name: '',
+	props: {
+		// 数据接口
+		api: {
+			type: Function,
+			default: () => {}
+		},
+		// 初始参数
+		init: {
+			type: Object,
+			default: () => ({})
+		},
+		emptyText: {
+			type: String,
+			default: ''
+		},
+		emptyBtnText: {
+			type: String,
+			default: ''
+		},
+		// 自定义list数据的字段
+		keyName: {
+			type: String,
+			default: 'records'
+		},
+		// page相关
+		noPage: {
+			type: Boolean,
+			default: false
+		},
+		pageSize: {
+			type: [Number, String],
+			default: 10
+		},
+	},
+	data() {
+		return {
+			params: {},
+			dataList: [],
+			// 下拉刷新的配置
+			downOption: {
+				
+			},
+			// 是否滚动
+			isScrolling: false,
+      		scrollTimer: null
+		};
+	},
+	computed: {
+		// 上拉加载的配置
+		upOption() {
+			let obj = {
+				// noMoreSize: 5, // 如果列表已无数据,可设置列表的总数量要大于5条才显示无更多数据;
+				onScroll: true,
+				textNoMore: '-- 暂无更多数据 --', 
+				page: {
+					size: this.pageSize // 每页数据的数量,默认10
+				},
+				empty: {
+					use: true,
+					tip: this.emptyText || '暂无数据',
+					btnText: this.emptyBtnText,
+					icon: '/static/common/empty.png',
+				}
+			};
+			return obj;
+		}
+	},
+	methods: {
+		// scroll
+		mescrollInit(e) {
+			this.mescroll = e;
+		},
+		onScroll(e) {
+			this.isScrolling = true;
+      
+			// 使用防抖判断滚动结束
+			clearTimeout(this.scrollTimer);
+			this.scrollTimer = setTimeout(() => {
+				this.isScrolling = false;
+			}, 200);
+		},
+		// 下拉刷新
+		downCallback() {
+			this.mescroll.resetUpScroll();
+		},
+		// 上拉加载
+		upCallback(e) {
+			if (!this.api) {
+				this.mescroll.endErr();
+				return;
+			}
+			let params = {
+				pageNo: e.num,
+				pageSize: e.size,
+				...this.init,
+				...this.params
+			};
+			// 置空
+			if(e.num == 1) this.dataList = []; 
+			// 请求
+			this.api(params).then(res => {
+				// 无分页处理,用于那些需要下拉和空列表的地方
+				if (this.noPage) {
+					res = {
+						...res,
+						result: {
+							records: res.result,
+							total: res.result.length
+						}
+					};
+				}
+				let result = res.result || {}, records = result[this.keyName].records || result[this.keyName] || [];
+				this.$emit('afterFetch', result);
+				// 数据
+				this.dataList = this.dataList.concat(records);
+				this.mescroll.endBySize(records.length, result.total || result[this.keyName].total);
+			}).catch(e => {
+				this.mescroll.endErr();
+			});
+		},
+		reloadList(p) {
+			this.params = p;
+			this.mescroll.resetUpScroll();
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+.lsv-container {
+	height: 100%;
+	position: relative;
+	.lsv-list {
+		min-height: 100%;
+	}
+}
+</style>

+ 75 - 0
components/list-scroll-view/list-expand.vue

@@ -0,0 +1,75 @@
+<template>
+	<view class="expandable-list-container">
+		<!-- 使用作用域插槽,将item数据传回给父组件 -->
+		<slot :record="data" :items="visibleItems"></slot>
+
+		<!-- 当项目总数大于限制时,显示展开/收起按钮 -->
+		<view v-if="items.length > limit" class="expand-trigger" @click.stop="toggleExpand">
+			<text>{{ isExpanded ? '收起' : '展开查看' }}</text>
+			<!-- <u-icon :name="isExpanded ? 'arrow-up' : 'arrow-down'" color="#909399" size="12"></u-icon> -->
+			<image :src="`/static/order/${isExpanded ? 'hidden' : 'show'}.png`"></image>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'ExpandableList',
+	props: {
+		// 兼容小程序,slot内如果使用到父级变量(此变量正好是遍历出来的),会取不到值
+		data: {
+			type: Object,
+			default: () => ({})
+		},
+		// 接收完整的列表数据
+		items: {
+			type: Array,
+			default: () => []
+		},
+		// 默认显示的条目数量
+		limit: {
+			type: Number,
+			default: 2
+		}
+	},
+	data() {
+		return {
+			isExpanded: false // 内部维护的展开状态
+		};
+	},
+	computed: {
+		// 根据展开状态,计算出实际应该显示的列表
+		visibleItems() {
+			if (this.isExpanded) {
+				return this.items; // 展开时,返回所有项目
+			}
+			return this.items.slice(0, this.limit); // 折叠时,返回限制数量的项目
+		}
+	},
+	methods: {
+		// 切换展开/收起状态
+		toggleExpand() {
+			this.isExpanded = !this.isExpanded;
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.expand-trigger {
+	font-size: 24rpx;
+	color: #2D88F4;
+	padding: 16rpx 0;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	text {
+		margin-right: 8rpx;
+	}
+
+	image {
+		width: 20rpx;
+		height: 20rpx;
+	}
+}
+</style>

+ 176 - 0
components/modal/index.vue

@@ -0,0 +1,176 @@
+<template>
+	<u-popup v-model="show" mode="center"
+		bgColor="transparent"
+		:customStyle="{ width: '100%' }"
+		:mask-close-able="closeOnClickOverlay"
+		:closeOnClickOverlay="closeOnClickOverlay"
+		@close="onCancel">
+		<view class="modal-box" :class="[type]">
+			<view class="modal-header" v-if="!!title">
+				<text>{{ title }}</text>
+			</view>
+			<view class="modal-content">
+				<slot v-if="$slots.content" name="content"></slot>
+				<text v-else>{{ content }}</text>
+			</view>
+			<view class="modal-footer">
+				<template v-if="$slots.buttons">
+					<slot name="buttons"></slot>
+				</template>
+				<template v-else>
+					<button class="btn cancel"
+						v-if="showCancelButton"
+						@click="onCancel()"
+					>{{ cancelText }}</button>
+					<button class="btn submit"
+						v-if="showConfirmButton"
+						@click="onSubmit()"
+					>{{ confirmText }}</button>
+				</template>
+			</view>
+		</view>
+	</u-popup>
+</template>
+
+<script>
+export default {
+	name: "",
+	props: {
+		title: {
+			default: '',
+			type: String
+		},
+		// success, warning
+		type: {
+			default: '',
+			type: String
+		},
+		content: {
+			default: '',
+			type: String
+		},
+		cancelText: {
+			default: '取消',
+			type: String
+		},
+		confirmText: {
+			default: '确认',
+			type: String
+		},
+		showCancelButton: {
+			default: true,
+			type: Boolean
+		},
+		showConfirmButton: {
+			default: true,
+			type: Boolean
+		},
+        // 点击遮罩是否关闭弹窗
+        closeOnClickOverlay: {
+            type: Boolean,
+            default: false
+        },
+	},
+	data() {
+		return {
+			show: false,
+			timer: null
+		};
+	},
+	mounted() {
+		
+	},
+	methods: {
+		onOpen(duration = 0, callback) {
+			this.show = true;
+
+			if (duration > 0) {
+				// 清除之前的定时器(防止多次调用)
+				if (this.timer) clearTimeout(this.timer);
+				this.timer = setTimeout(() => {
+					this.show = false;
+					callback && callback();
+				}, duration);
+			}
+		},
+		onCancel() {
+			this.$emit('cancel');
+			this.show = false;
+		},
+		onSubmit() {
+			this.$emit('confirm');
+			this.show = false;
+		},
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep .u-popup {
+	flex: initial;
+}
+::v-deep .u-mode-center-box {
+	background: transparent;
+}
+.modal-box {
+	width: calc(100vw - 150rpx);
+	// margin: 0 75rpx;
+	border-radius: 16rpx;
+	background: #fff;
+	.modal-header {
+		margin: 0 24rpx;
+		padding: 18rpx 0;
+		text-align: center;
+		border-bottom: 1rpx solid #EEEEEE;
+		text {
+			font-weight: 500;
+			font-size: 34rpx;
+			color: #333333;
+		}
+	}
+	.modal-content {
+		// min-height: 164rpx;
+		padding: 42rpx 40rpx;
+		text-align: center;
+		text {
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #232832;
+		}
+	}
+	.modal-footer {
+		padding: 16rpx 24rpx;
+		border-top: 1rpx solid #EEEEEE;
+		gap: 20rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		.btn {
+			width: 100%;
+			font-weight: 400;
+			font-size: 28rpx;
+			line-height: 68rpx;
+			border-radius: 54rpx;
+			&::after {
+				border: none;
+			}
+		}
+		.cancel {
+			color: #999999;
+			border: 1rpx solid #CCCCCC;
+			background: #FFFFFF;
+		}
+		.submit {
+			color: #FFFFFF;
+			border: 1rpx solid #449AFF;
+			background: #449AFF;
+		}
+	}
+	&.success {
+		background: linear-gradient(180deg, #E0F8E3 0%, #FFFFFF 25%);
+	}
+	&.warning {
+		background: linear-gradient( 180deg, #FFEFE2 0%, #FFFFFF 35%);
+	}
+}
+</style>

+ 0 - 546
components/uni-calendar/calendar.js

@@ -1,546 +0,0 @@
-/**
-* @1900-2100区间内的公历、农历互转
-* @charset UTF-8
-* @github  https://github.com/jjonline/calendar.js
-* @Author  Jea杨(JJonline@JJonline.Cn)
-* @Time    2014-7-21
-* @Time    2016-8-13 Fixed 2033hex、Attribution Annals
-* @Time    2016-9-25 Fixed lunar LeapMonth Param Bug
-* @Time    2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
-* @Version 1.0.3
-* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
-* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
-*/
-/* eslint-disable */
-var calendar = {
-
-  /**
-      * 农历1900-2100的润大小信息表
-      * @Array Of Property
-      * @return Hex
-      */
-  lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
-    0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
-    0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
-    0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
-    0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
-    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
-    0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
-    0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
-    0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
-    0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
-    0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
-    0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
-    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
-    0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
-    0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
-    /** Add By JJonline@JJonline.Cn**/
-    0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
-    0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
-    0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
-    0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
-    0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
-    0x0d520], // 2100
-
-  /**
-      * 公历每个月份的天数普通表
-      * @Array Of Property
-      * @return Number
-      */
-  solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
-
-  /**
-      * 天干地支之天干速查表
-      * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
-      * @return Cn string
-      */
-  Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
-
-  /**
-      * 天干地支之地支速查表
-      * @Array Of Property
-      * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
-      * @return Cn string
-      */
-  Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
-
-  /**
-      * 天干地支之地支速查表<=>生肖
-      * @Array Of Property
-      * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
-      * @return Cn string
-      */
-  Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
-
-  /**
-      * 24节气速查表
-      * @Array Of Property
-      * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
-      * @return Cn string
-      */
-  solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
-
-  /**
-      * 1900-2100各年的24节气日期速查表
-      * @Array Of Property
-      * @return 0x string For splice
-      */
-  sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
-    '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
-    '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
-    '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
-    'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
-    '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
-    '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
-    '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
-    '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
-    '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
-    '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
-    '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
-    '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
-    '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
-    '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
-    '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
-    '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
-    '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
-    '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
-    '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
-    '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
-    '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
-    '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
-    '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
-    '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
-    '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
-    '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
-    '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
-    '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
-    '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
-    '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
-    '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
-    '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
-    '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
-    '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
-    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
-    '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
-    '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
-    '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
-    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
-    '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
-    '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
-    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
-    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
-    '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
-    '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
-    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
-    '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
-    '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
-    '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
-    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
-    '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
-    '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
-    '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
-    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
-    '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
-    '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
-    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
-    '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
-    '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
-    '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
-    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
-    '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
-    '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
-    '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
-    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
-    '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
-
-  /**
-      * 数字转中文速查表
-      * @Array Of Property
-      * @trans ['日','一','二','三','四','五','六','七','八','九','十']
-      * @return Cn string
-      */
-  nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
-
-  /**
-      * 日期转农历称呼速查表
-      * @Array Of Property
-      * @trans ['初','十','廿','卅']
-      * @return Cn string
-      */
-  nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
-
-  /**
-      * 月份转农历称呼速查表
-      * @Array Of Property
-      * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
-      * @return Cn string
-      */
-  nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
-
-  /**
-      * 返回农历y年一整年的总天数
-      * @param lunar Year
-      * @return Number
-      * @eg:var count = calendar.lYearDays(1987) ;//count=387
-      */
-  lYearDays: function (y) {
-    var i; var sum = 348
-    for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
-    return (sum + this.leapDays(y))
-  },
-
-  /**
-      * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
-      * @param lunar Year
-      * @return Number (0-12)
-      * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
-      */
-  leapMonth: function (y) { // 闰字编码 \u95f0
-    return (this.lunarInfo[y - 1900] & 0xf)
-  },
-
-  /**
-      * 返回农历y年闰月的天数 若该年没有闰月则返回0
-      * @param lunar Year
-      * @return Number (0、29、30)
-      * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
-      */
-  leapDays: function (y) {
-    if (this.leapMonth(y)) {
-      return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
-    }
-    return (0)
-  },
-
-  /**
-      * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
-      * @param lunar Year
-      * @return Number (-1、29、30)
-      * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
-      */
-  monthDays: function (y, m) {
-    if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
-    return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
-  },
-
-  /**
-      * 返回公历(!)y年m月的天数
-      * @param solar Year
-      * @return Number (-1、28、29、30、31)
-      * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
-      */
-  solarDays: function (y, m) {
-    if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
-    var ms = m - 1
-    if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
-      return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
-    } else {
-      return (this.solarMonth[ms])
-    }
-  },
-
-  /**
-     * 农历年份转换为干支纪年
-     * @param  lYear 农历年的年份数
-     * @return Cn string
-     */
-  toGanZhiYear: function (lYear) {
-    var ganKey = (lYear - 3) % 10
-    var zhiKey = (lYear - 3) % 12
-    if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
-    if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
-    return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
-  },
-
-  /**
-     * 公历月、日判断所属星座
-     * @param  cMonth [description]
-     * @param  cDay [description]
-     * @return Cn string
-     */
-  toAstro: function (cMonth, cDay) {
-    var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
-    var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
-    return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
-  },
-
-  /**
-      * 传入offset偏移量返回干支
-      * @param offset 相对甲子的偏移量
-      * @return Cn string
-      */
-  toGanZhi: function (offset) {
-    return this.Gan[offset % 10] + this.Zhi[offset % 12]
-  },
-
-  /**
-      * 传入公历(!)y年获得该年第n个节气的公历日期
-      * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
-      * @return day Number
-      * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
-      */
-  getTerm: function (y, n) {
-    if (y < 1900 || y > 2100) { return -1 }
-    if (n < 1 || n > 24) { return -1 }
-    var _table = this.sTermInfo[y - 1900]
-    var _info = [
-      parseInt('0x' + _table.substr(0, 5)).toString(),
-      parseInt('0x' + _table.substr(5, 5)).toString(),
-      parseInt('0x' + _table.substr(10, 5)).toString(),
-      parseInt('0x' + _table.substr(15, 5)).toString(),
-      parseInt('0x' + _table.substr(20, 5)).toString(),
-      parseInt('0x' + _table.substr(25, 5)).toString()
-    ]
-    var _calday = [
-      _info[0].substr(0, 1),
-      _info[0].substr(1, 2),
-      _info[0].substr(3, 1),
-      _info[0].substr(4, 2),
-
-      _info[1].substr(0, 1),
-      _info[1].substr(1, 2),
-      _info[1].substr(3, 1),
-      _info[1].substr(4, 2),
-
-      _info[2].substr(0, 1),
-      _info[2].substr(1, 2),
-      _info[2].substr(3, 1),
-      _info[2].substr(4, 2),
-
-      _info[3].substr(0, 1),
-      _info[3].substr(1, 2),
-      _info[3].substr(3, 1),
-      _info[3].substr(4, 2),
-
-      _info[4].substr(0, 1),
-      _info[4].substr(1, 2),
-      _info[4].substr(3, 1),
-      _info[4].substr(4, 2),
-
-      _info[5].substr(0, 1),
-      _info[5].substr(1, 2),
-      _info[5].substr(3, 1),
-      _info[5].substr(4, 2)
-    ]
-    return parseInt(_calday[n - 1])
-  },
-
-  /**
-      * 传入农历数字月份返回汉语通俗表示法
-      * @param lunar month
-      * @return Cn string
-      * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
-      */
-  toChinaMonth: function (m) { // 月 => \u6708
-    if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
-    var s = this.nStr3[m - 1]
-    s += '\u6708'// 加上月字
-    return s
-  },
-
-  /**
-      * 传入农历日期数字返回汉字表示法
-      * @param lunar day
-      * @return Cn string
-      * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
-      */
-  toChinaDay: function (d) { // 日 => \u65e5
-    var s
-    switch (d) {
-      case 10:
-        s = '\u521d\u5341'; break
-      case 20:
-        s = '\u4e8c\u5341'; break
-        break
-      case 30:
-        s = '\u4e09\u5341'; break
-        break
-      default :
-        s = this.nStr2[Math.floor(d / 10)]
-        s += this.nStr1[d % 10]
-    }
-    return (s)
-  },
-
-  /**
-      * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
-      * @param y year
-      * @return Cn string
-      * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
-      */
-  getAnimal: function (y) {
-    return this.Animals[(y - 4) % 12]
-  },
-
-  /**
-      * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
-      * @param y  solar year
-      * @param m  solar month
-      * @param d  solar day
-      * @return JSON object
-      * @eg:console.log(calendar.solar2lunar(1987,11,01));
-      */
-  solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
-    // 年份限定、上限
-    if (y < 1900 || y > 2100) {
-      return -1// undefined转换为数字变为NaN
-    }
-    // 公历传参最下限
-    if (y == 1900 && m == 1 && d < 31) {
-      return -1
-    }
-    // 未传参  获得当天
-    if (!y) {
-      var objDate = new Date()
-    } else {
-      var objDate = new Date(y, parseInt(m) - 1, d)
-    }
-    var i; var leap = 0; var temp = 0
-    // 修正ymd参数
-    var y = objDate.getFullYear()
-    var m = objDate.getMonth() + 1
-    var d = objDate.getDate()
-    var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
-    for (i = 1900; i < 2101 && offset > 0; i++) {
-      temp = this.lYearDays(i)
-      offset -= temp
-    }
-    if (offset < 0) {
-      offset += temp; i--
-    }
-
-    // 是否今天
-    var isTodayObj = new Date()
-    var isToday = false
-    if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
-      isToday = true
-    }
-    // 星期几
-    var nWeek = objDate.getDay()
-    var cWeek = this.nStr1[nWeek]
-    // 数字表示周几顺应天朝周一开始的惯例
-    if (nWeek == 0) {
-      nWeek = 7
-    }
-    // 农历年
-    var year = i
-    var leap = this.leapMonth(i) // 闰哪个月
-    var isLeap = false
-
-    // 效验闰月
-    for (i = 1; i < 13 && offset > 0; i++) {
-      // 闰月
-      if (leap > 0 && i == (leap + 1) && isLeap == false) {
-        --i
-        isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
-      } else {
-        temp = this.monthDays(year, i)// 计算农历普通月天数
-      }
-      // 解除闰月
-      if (isLeap == true && i == (leap + 1)) { isLeap = false }
-      offset -= temp
-    }
-    // 闰月导致数组下标重叠取反
-    if (offset == 0 && leap > 0 && i == leap + 1) {
-      if (isLeap) {
-        isLeap = false
-      } else {
-        isLeap = true; --i
-      }
-    }
-    if (offset < 0) {
-      offset += temp; --i
-    }
-    // 农历月
-    var month = i
-    // 农历日
-    var day = offset + 1
-    // 天干地支处理
-    var sm = m - 1
-    var gzY = this.toGanZhiYear(year)
-
-    // 当月的两个节气
-    // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
-    var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
-    var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
-
-    // 依据12节气修正干支月
-    var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
-    if (d >= firstNode) {
-      gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
-    }
-
-    // 传入的日期的节气与否
-    var isTerm = false
-    var Term = null
-    if (firstNode == d) {
-      isTerm = true
-      Term = this.solarTerm[m * 2 - 2]
-    }
-    if (secondNode == d) {
-      isTerm = true
-      Term = this.solarTerm[m * 2 - 1]
-    }
-    // 日柱 当月一日与 1900/1/1 相差天数
-    var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
-    var gzD = this.toGanZhi(dayCyclical + d - 1)
-    // 该日期所属的星座
-    var astro = this.toAstro(m, d)
-
-    return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro }
-  },
-
-  /**
-      * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
-      * @param y  lunar year
-      * @param m  lunar month
-      * @param d  lunar day
-      * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
-      * @return JSON object
-      * @eg:console.log(calendar.lunar2solar(1987,9,10));
-      */
-  lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
-    var isLeapMonth = !!isLeapMonth
-    var leapOffset = 0
-    var leapMonth = this.leapMonth(y)
-    var leapDay = this.leapDays(y)
-    if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
-    if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
-    var day = this.monthDays(y, m)
-    var _day = day
-    // bugFix 2016-9-25
-    // if month is leap, _day use leapDays method
-    if (isLeapMonth) {
-      _day = this.leapDays(y, m)
-    }
-    if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
-
-    // 计算农历的时间差
-    var offset = 0
-    for (var i = 1900; i < y; i++) {
-      offset += this.lYearDays(i)
-    }
-    var leap = 0; var isAdd = false
-    for (var i = 1; i < m; i++) {
-      leap = this.leapMonth(y)
-      if (!isAdd) { // 处理闰月
-        if (leap <= i && leap > 0) {
-          offset += this.leapDays(y); isAdd = true
-        }
-      }
-      offset += this.monthDays(y, i)
-    }
-    // 转换闰月农历 需补充该年闰月的前一个月的时差
-    if (isLeapMonth) { offset += day }
-    // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
-    var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
-    var calObj = new Date((offset + d - 31) * 86400000 + stmap)
-    var cY = calObj.getUTCFullYear()
-    var cM = calObj.getUTCMonth() + 1
-    var cD = calObj.getUTCDate()
-
-    return this.solar2lunar(cY, cM, cD)
-  }
-}
-
-export default calendar

+ 0 - 179
components/uni-calendar/uni-calendar-item.vue

@@ -1,179 +0,0 @@
-<template>
-	<view class="uni-calendar-item__weeks-box" :class="{
-		'uni-calendar-item--disable':weeks.disable,
-		'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
-		'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
-		'uni-calendar-item--before-checked':weeks.beforeMultiple,
-		'uni-calendar-item--multiple': weeks.multiple,
-		'uni-calendar-item--after-checked':weeks.afterMultiple,
-		}"
-	 @click="choiceDate(weeks)">
-		<view class="uni-calendar-item__weeks-box-item">
-			<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
-			<text class="uni-calendar-item__weeks-box-text" :class="{
-				'uni-calendar-item--isDay-text': weeks.isDay,
-				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
-				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
-				'uni-calendar-item--before-checked':weeks.beforeMultiple,
-				'uni-calendar-item--multiple': weeks.multiple,
-				'uni-calendar-item--after-checked':weeks.afterMultiple,
-				'uni-calendar-item--disable':weeks.disable,
-				}">{{weeks.date}}</text>
-			<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
-				'uni-calendar-item--isDay-text':weeks.isDay,
-				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
-				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
-				'uni-calendar-item--before-checked':weeks.beforeMultiple,
-				'uni-calendar-item--multiple': weeks.multiple,
-				'uni-calendar-item--after-checked':weeks.afterMultiple,
-				}">今天</text>
-			<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
-				'uni-calendar-item--isDay-text':weeks.isDay,
-				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
-				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
-				'uni-calendar-item--before-checked':weeks.beforeMultiple,
-				'uni-calendar-item--multiple': weeks.multiple,
-				'uni-calendar-item--after-checked':weeks.afterMultiple,
-				'uni-calendar-item--disable':weeks.disable,
-				}">{{weeks.isDay?'今天': (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
-			<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
-				'uni-calendar-item--extra':weeks.extraInfo.info,
-				'uni-calendar-item--isDay-text':weeks.isDay,
-				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
-				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
-				'uni-calendar-item--before-checked':weeks.beforeMultiple,
-				'uni-calendar-item--multiple': weeks.multiple,
-				'uni-calendar-item--after-checked':weeks.afterMultiple,
-				'uni-calendar-item--disable':weeks.disable,
-				}">{{weeks.extraInfo.info}}</text>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		props: {
-			weeks: {
-				type: Object,
-				default () {
-					return {}
-				}
-			},
-			calendar: {
-				type: Object,
-				default: () => {
-					return {}
-				}
-			},
-			selected: {
-				type: Array,
-				default: () => {
-					return []
-				}
-			},
-			lunar: {
-				type: Boolean,
-				default: false
-			}
-		},
-		methods: {
-			choiceDate(weeks) {
-				this.$emit('change', weeks)
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.uni-calendar-item__weeks-box {
-		flex: 1;
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: column;
-		justify-content: center;
-		align-items: center;
-	}
-
-	.uni-calendar-item__weeks-box-text {
-		font-size: $uni-font-size-base;
-		color: $uni-text-color;
-	}
-
-	.uni-calendar-item__weeks-lunar-text {
-		font-size: $uni-font-size-sm;
-		color: $uni-text-color;
-	}
-
-	.uni-calendar-item__weeks-box-item {
-		position: relative;
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: column;
-		justify-content: center;
-		align-items: center;
-		width: 100rpx;
-		height: 100rpx;
-	}
-
-	/* .uni-calendar-item__weeks-box-circle {
-		position: absolute;
-		top: 5px;
-		right: 5px;
-		width: 8px;
-		height: 8px;
-		border-radius: 8px;
-		background-color: $uni-color-error;
-	} */
-	.uni-calendar-item__weeks-box-circle{
-	    position: absolute;
-	    top: 37px;
-	    right: 23px;
-	    width: 3px;
-	    height: 3px;
-	    border-radius: 3px;
-	    //background-color: $uni-color-primary;
-	    background-color: $uni-color-error;
-	}
-
-	.uni-calendar-item--disable {
-		background-color: rgba(249, 249, 249, $uni-opacity-disabled);
-		color: $uni-text-color-disable;
-	}
-
-	.uni-calendar-item--isDay-text {
-		color: $uni-color-primary;
-	}
-
-	.uni-calendar-item--isDay {
-		background-color: $uni-color-primary;
-		opacity: 0.8;
-		color: #fff;
-	}
-
-	.uni-calendar-item--extra {
-		color: $uni-color-error;
-		opacity: 0.8;
-	}
-
-	.uni-calendar-item--checked {
-		background-color: $uni-color-primary;
-		color: #fff;
-		opacity: 0.8;
-	}
-
-	.uni-calendar-item--multiple {
-		background-color: $uni-color-primary;
-		color: #fff;
-		opacity: 0.8;
-	}
-	.uni-calendar-item--before-checked {
-		background-color: #ff5a5f;
-		color: #fff;
-	}
-	.uni-calendar-item--after-checked {
-		background-color: #ff5a5f;
-		color: #fff;
-	}
-</style>

+ 0 - 512
components/uni-calendar/uni-calendar.vue

@@ -1,512 +0,0 @@
-<template>
-	<view class="uni-calendar">
-		<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
-		<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
-			<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
-				<view class="uni-calendar__header-btn-box" @click="close">
-					<text class="uni-calendar__header-text uni-calendar--fixed-width">取消</text>
-				</view>
-				<view class="uni-calendar__header-btn-box" @click="confirm">
-					<text class="uni-calendar__header-text uni-calendar--fixed-width">确定</text>
-				</view>
-			</view>
-			<view class="uni-calendar__header">
-				<view class="uni-calendar__header-btn-box" @click.stop="pre">
-					<view class="uni-calendar__header-btn uni-calendar--left"></view>
-				</view>
-				<picker mode="date" :value="date" fields="month" @change="bindDateChange">
-					<text class="uni-calendar__header-text">{{ (nowDate.year||'') +'年'+( nowDate.month||'') +'月'}}</text>
-				</picker>
-				<view class="uni-calendar__header-btn-box" @click.stop="next">
-					<view class="uni-calendar__header-btn uni-calendar--right"></view>
-				</view>
-				<text class="uni-calendar__backtoday" @click="backtoday">回到今天</text>
-
-			</view>
-			<view class="uni-calendar__box">
-				<view v-if="showMonth" class="uni-calendar__box-bg">
-					<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
-				</view>
-				<view class="uni-calendar__weeks">
-					<view class="uni-calendar__weeks-day">
-						<text class="uni-calendar__weeks-day-text">日</text>
-					</view>
-					<view class="uni-calendar__weeks-day">
-						<text class="uni-calendar__weeks-day-text">一</text>
-					</view>
-					<view class="uni-calendar__weeks-day">
-						<text class="uni-calendar__weeks-day-text">二</text>
-					</view>
-					<view class="uni-calendar__weeks-day">
-						<text class="uni-calendar__weeks-day-text">三</text>
-					</view>
-					<view class="uni-calendar__weeks-day">
-						<text class="uni-calendar__weeks-day-text">四</text>
-					</view>
-					<view class="uni-calendar__weeks-day">
-						<text class="uni-calendar__weeks-day-text">五</text>
-					</view>
-					<view class="uni-calendar__weeks-day">
-						<text class="uni-calendar__weeks-day-text">六</text>
-					</view>
-				</view>
-				<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
-					<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
-						<calendar-item :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></calendar-item>
-					</view>
-				</view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import Calendar from './util.js';
-	import calendarItem from './uni-calendar-item.vue'
-	/**
-	 * Calendar 日历
-	 * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
-	 * @tutorial https://ext.dcloud.net.cn/plugin?id=56
-	 * @property {String} date 自定义当前时间,默认为今天
-	 * @property {Boolean} lunar 显示农历
-	 * @property {String} startDate 日期选择范围-开始日期
-	 * @property {String} endDate 日期选择范围-结束日期
-	 * @property {Boolean} range 范围选择
-	 * @property {Boolean} insert = [true|false] 插入模式,默认为false
-	 * 	@value true 弹窗模式
-	 * 	@value false 插入模式
-	 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
-	 * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
-	 * @property {Boolean} showMonth 是否选择月份为背景
-	 * @event {Function} change 日期改变,`insert :ture` 时生效
-	 * @event {Function} confirm 确认选择`insert :false` 时生效
-	 * @event {Function} monthSwitch 切换月份时触发
-	 * @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
-	 */
-	export default {
-		components: {
-			calendarItem
-		},
-		props: {
-			date: {
-				type: String,
-				default: ''
-			},
-			selected: {
-				type: Array,
-				default () {
-					return []
-				}
-			},
-			lunar: {
-				type: Boolean,
-				default: false
-			},
-			startDate: {
-				type: String,
-				default: ''
-			},
-			endDate: {
-				type: String,
-				default: ''
-			},
-			range: {
-				type: Boolean,
-				default: false
-			},
-			insert: {
-				type: Boolean,
-				default: true
-			},
-			showMonth: {
-				type: Boolean,
-				default: true
-			},
-			clearDate: {
-				type: Boolean,
-				default: true
-			}
-		},
-		data() {
-			return {
-				show: false,
-				weeks: [],
-				calendar: {},
-				nowDate: '',
-				aniMaskShow: false
-			}
-		},
-		watch: {
-			date(newVal) {
-				this.cale.setDate(newVal)
-				this.init(this.cale.selectDate.fullDate)
-			},
-			startDate(val){
-				this.cale.resetSatrtDate(val)
-			},
-			endDate(val){
-				this.cale.resetEndDate(val)
-			},
-			selected(newVal) {
-				this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
-				this.weeks = this.cale.weeks
-			}
-		},
-		created() {
-			// 获取日历方法实例
-			this.cale = new Calendar({
-				// date: new Date(),
-				selected: this.selected,
-				startDate: this.startDate,
-				endDate: this.endDate,
-				range: this.range,
-			})
-			// 选中某一天
-			this.cale.setDate(this.date)
-			this.init(this.cale.selectDate.fullDate)
-			// this.setDay
-		},
-		methods: {
-			// 取消穿透
-			clean() {},
-			bindDateChange(e) {
-				const value = e.detail.value + '-1'
-				console.log(this.cale.getDate(value));
-				this.cale.setDate(value)
-				this.init(value)
-			},
-			/**
-			 * 初始化日期显示
-			 * @param {Object} date
-			 */
-			init(date) {
-				this.weeks = this.cale.weeks
-				this.nowDate = this.calendar = this.cale.getInfo(date)
-			    console.log("this.weeks",this.weeks)
-			},
-			/**
-			 * 打开日历弹窗
-			 */
-			open() {
-				// 弹窗模式并且清理数据
-				if (this.clearDate && !this.insert) {
-					this.cale.cleanMultipleStatus()
-					this.cale.setDate(this.date)
-					this.init(this.cale.selectDate.fullDate)
-				}
-				this.show = true
-				this.$nextTick(() => {
-					setTimeout(() => {
-						this.aniMaskShow = true
-					}, 50)
-				})
-			},
-			/**
-			 * 关闭日历弹窗
-			 */
-			close() {
-				this.aniMaskShow = false
-				this.$nextTick(() => {
-					setTimeout(() => {
-						this.show = false
-						this.$emit('close')
-					}, 300)
-				})
-			},
-			/**
-			 * 确认按钮
-			 */
-			confirm() {
-				this.setEmit('confirm')
-				this.close()
-			},
-			/**
-			 * 变化触发
-			 */
-			change() {
-				if (!this.insert) return
-				this.setEmit('change')
-			},
-			/**
-			 * 选择月份触发
-			 */
-			monthSwitch() {
-				let {
-					year,
-					month
-				} = this.nowDate
-				this.$emit('monthSwitch', {
-					year,
-					month: Number(month)
-				})
-			},
-			/**
-			 * 派发事件
-			 * @param {Object} name
-			 */
-			setEmit(name) {
-				let {
-					year,
-					month,
-					date,
-					fullDate,
-					lunar,
-					extraInfo
-				} = this.calendar
-				this.$emit(name, {
-					range: this.cale.multipleStatus,
-					year,
-					month,
-					date,
-					fulldate: fullDate,
-					lunar,
-					extraInfo: extraInfo || {}
-				})
-			},
-			/**
-			 * 选择天触发
-			 * @param {Object} weeks
-			 */
-			choiceDate(weeks) {
-				console.log(weeks)
-				if (weeks.disable){
-					//this.next()
-					return
-				} 
-				this.calendar = weeks
-				// 设置多选
-				this.cale.setMultiple(this.calendar.fullDate)
-				this.weeks = this.cale.weeks
-				this.change()
-			},
-			/**
-			 * 回到今天
-			 */
-			backtoday() {
-				console.log(this.cale.getDate(new Date()).fullDate);
-				let date = this.cale.getDate(new Date()).fullDate
-				this.cale.setDate(date)
-				this.init(date)
-				this.change()
-			},
-			/**
-			 * 上个月
-			 */
-			pre() {
-				const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
-				this.setDate(preDate)
-				this.monthSwitch()
-				this.$emit("monthChange",preDate)
-            },
-			/**
-			 * 下个月
-			 */
-			next() {
-				const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
-				this.setDate(nextDate)
-				this.monthSwitch()
-				this.$emit("monthChange",nextDate)
-			},
-			/**
-			 * 设置日期
-			 * @param {Object} date
-			 */
-			setDate(date) {
-				this.cale.setDate(date)
-				this.weeks = this.cale.weeks
-				this.nowDate = this.cale.getInfo(date)
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.uni-calendar {
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: column;
-	}
-
-	.uni-calendar__mask {
-		position: fixed;
-		bottom: 0;
-		top: 0;
-		left: 0;
-		right: 0;
-		background-color: $uni-bg-color-mask;
-		transition-property: opacity;
-		transition-duration: 0.3s;
-		opacity: 0;
-		/* #ifndef APP-NVUE */
-		z-index: 99;
-		/* #endif */
-	}
-
-	.uni-calendar--mask-show {
-		opacity: 1
-	}
-
-	.uni-calendar--fixed {
-		position: fixed;
-		bottom: 0;
-		left: 0;
-		right: 0;
-		transition-property: transform;
-		transition-duration: 0.3s;
-		transform: translateY(460px);
-		/* #ifndef APP-NVUE */
-		z-index: 99;
-		/* #endif */
-	}
-
-	.uni-calendar--ani-show {
-		transform: translateY(0);
-	}
-
-	.uni-calendar__content {
-		background-color: #fff;
-	}
-
-	.uni-calendar__header {
-		position: relative;
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: row;
-		justify-content: center;
-		align-items: center;
-		height: 50px;
-		border-bottom-color: $uni-border-color-gray;
-		border-bottom-style: solid;
-		border-bottom-width: 1px;
-	}
-
-	.uni-calendar--fixed-top {
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: row;
-		justify-content: space-between;
-		border-top-color: $uni-border-color;
-		border-top-style: solid;
-		border-top-width: 1px;
-	}
-
-	.uni-calendar--fixed-width {
-		width: 50px;
-		// padding: 0 15px;
-	}
-
-	.uni-calendar__backtoday {
-		position: absolute;
-		right: 0;
-		top: 25rpx;
-		padding: 0 5px;
-		padding-left: 10px;
-		height: 25px;
-		line-height: 25px;
-		font-size: 12px;
-		border-top-left-radius: 25px;
-		border-bottom-left-radius: 25px;
-		color: $uni-text-color;
-		background-color: $uni-bg-color-hover;
-	}
-
-	.uni-calendar__header-text {
-		text-align: center;
-		width: 100px;
-		font-size: $uni-font-size-xl;
-		color: $uni-text-color;
-	}
-
-	.uni-calendar__header-btn-box {
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: row;
-		align-items: center;
-		justify-content: center;
-		width: 50px;
-		height: 50px;
-	}
-
-	.uni-calendar__header-btn {
-		width: 10px;
-		height: 10px;
-		border-left-color: $uni-text-color-placeholder;
-		border-left-style: solid;
-		border-left-width: 2px;
-		border-top-color: $uni-color-subtitle;
-		border-top-style: solid;
-		border-top-width: 2px;
-	}
-
-	.uni-calendar--left {
-		transform: rotate(-45deg);
-	}
-
-	.uni-calendar--right {
-		transform: rotate(135deg);
-	}
-
-
-	.uni-calendar__weeks {
-		position: relative;
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: row;
-	}
-
-	.uni-calendar__weeks-item {
-		flex: 1;
-	}
-
-	.uni-calendar__weeks-day {
-		flex: 1;
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		flex-direction: column;
-		justify-content: center;
-		align-items: center;
-		height: 45px;
-		border-bottom-color: #F5F5F5;
-		border-bottom-style: solid;
-		border-bottom-width: 1px;
-	}
-
-	.uni-calendar__weeks-day-text {
-		font-size: 14px;
-	}
-
-	.uni-calendar__box {
-		position: relative;
-	}
-
-	.uni-calendar__box-bg {
-		/* #ifndef APP-NVUE */
-		display: flex;
-		/* #endif */
-		justify-content: center;
-		align-items: center;
-		position: absolute;
-		top: 0;
-		left: 0;
-		right: 0;
-		bottom: 0;
-	}
-
-	.uni-calendar__box-bg-text {
-		font-size: 200px;
-		font-weight: bold;
-		color: $uni-text-color-grey;
-		opacity: 0.1;
-		text-align: center;
-		/* #ifndef APP-NVUE */
-		line-height: 1;
-		/* #endif */
-	}
-	
-</style>

+ 0 - 352
components/uni-calendar/util.js

@@ -1,352 +0,0 @@
-import CALENDAR from './calendar.js'
-
-class Calendar {
-	constructor({
-		date,
-		selected,
-		startDate,
-		endDate,
-		range
-	} = {}) {
-		// 当前日期
-		this.date = this.getDate(new Date()) // 当前初入日期
-		// 打点信息
-		this.selected = selected || [];
-		// 范围开始
-		this.startDate = startDate
-		// 范围结束
-		this.endDate = endDate
-		this.range = range
-		// 多选状态
-		this.cleanMultipleStatus()
-		// 每周日期
-		this.weeks = {}
-		// this._getWeek(this.date.fullDate)
-	}
-	/**
-	 * 设置日期
-	 * @param {Object} date
-	 */
-	setDate(date) {
-		this.selectDate = this.getDate(date)
-		this._getWeek(this.selectDate.fullDate)
-	}
-
-	/**
-	 * 清理多选状态
-	 */
-	cleanMultipleStatus() {
-		this.multipleStatus = {
-			before: '',
-			after: '',
-			data: []
-		}
-	}
-
-	/**
-	 * 重置开始日期
-	 */
-	resetSatrtDate(startDate) {
-		// 范围开始
-		this.startDate = startDate
-
-	}
-
-	/**
-	 * 重置结束日期
-	 */
-	resetEndDate(endDate) {
-		// 范围结束
-		this.endDate = endDate
-	}
-
-	/**
-	 * 获取任意时间
-	 */
-	getDate(date, AddDayCount = 0, str = 'day') {
-		if (!date) {
-			date = new Date()
-		}
-		if (typeof date !== 'object') {
-			date = date.replace(/-/g, '/')
-		}
-		const dd = new Date(date)
-		switch (str) {
-			case 'day':
-				dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
-				break
-			case 'month':
-				if (dd.getDate() === 31) {
-					dd.setDate(dd.getDate() + AddDayCount)
-				} else {
-					dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
-				}
-				break
-			case 'year':
-				dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
-				break
-		}
-		const y = dd.getFullYear()
-		const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
-		const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
-		return {
-			fullDate: y + '-' + m + '-' + d,
-			year: y,
-			month: m,
-			date: d,
-			day: dd.getDay()
-		}
-	}
-
-
-	/**
-	 * 获取上月剩余天数
-	 */
-	_getLastMonthDays(firstDay, full) {
-		let dateArr = []
-		for (let i = firstDay; i > 0; i--) {
-			const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
-			dateArr.push({
-				date: beforeDate,
-				month: full.month - 1,
-				lunar: this.getlunar(full.year, full.month - 1, beforeDate),
-				disable: true
-			})
-		}
-		return dateArr
-	}
-	/**
-	 * 获取本月天数
-	 */
-	_currentMonthDys(dateData, full) {
-		let dateArr = []
-		let fullDate = this.date.fullDate
-		for (let i = 1; i <= dateData; i++) {
-			let isinfo = false
-			let nowDate = full.year + '-' + (full.month < 10 ?
-				full.month : full.month) + '-' + (i < 10 ?
-				'0' + i : i)
-			// 是否今天
-			let isDay = fullDate === nowDate
-			// 获取打点信息
-			let info = this.selected && this.selected.find((item) => {
-				if (this.dateEqual(nowDate, item.date)) {
-					return item
-				}
-			})
-
-			// 日期禁用
-			let disableBefore = true
-			let disableAfter = true
-			if (this.startDate) {
-				let dateCompBefore = this.dateCompare(this.startDate, fullDate)
-				disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
-			}
-
-			if (this.endDate) {
-				let dateCompAfter = this.dateCompare(fullDate, this.endDate)
-				disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
-			}
-			let multiples = this.multipleStatus.data
-			let checked = false
-			let multiplesStatus = -1
-			if (this.range) {
-				if (multiples) {
-					multiplesStatus = multiples.findIndex((item) => {
-						return this.dateEqual(item, nowDate)
-					})
-				}
-				if (multiplesStatus !== -1) {
-					checked = true
-				}
-			}
-			let data = {
-				fullDate: nowDate,
-				year: full.year,
-				date: i,
-				multiple: this.range ? checked : false,
-				beforeMultiple: this.dateEqual(this.multipleStatus.before, nowDate),
-				afterMultiple: this.dateEqual(this.multipleStatus.after, nowDate),
-				month: full.month,
-				lunar: this.getlunar(full.year, full.month, i),
-				disable: !disableBefore || !disableAfter,
-				isDay
-			}
-			if (info) {
-				data.extraInfo = info
-			}
-
-			dateArr.push(data)
-		}
-		return dateArr
-	}
-	/**
-	 * 获取下月天数
-	 */
-	_getNextMonthDays(surplus, full) {
-		let dateArr = []
-		for (let i = 1; i < surplus + 1; i++) {
-			dateArr.push({
-				date: i,
-				month: Number(full.month) + 1,
-				lunar: this.getlunar(full.year, Number(full.month) + 1, i),
-				disable: true
-			})
-		}
-		return dateArr
-	}
-
-	/**
-	 * 获取当前日期详情
-	 * @param {Object} date
-	 */
-	getInfo(date) {
-		if (!date) {
-			date = new Date()
-		}
-		const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
-		return dateInfo
-	}
-
-	/**
-	 * 比较时间大小
-	 */
-	dateCompare(startDate, endDate) {
-		// 计算截止时间
-		startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
-		// 计算详细项的截止时间
-		endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
-		if (startDate <= endDate) {
-			return true
-		} else {
-			return false
-		}
-	}
-
-	/**
-	 * 比较时间是否相等
-	 */
-	dateEqual(before, after) {
-		// 计算截止时间
-		before = new Date(before.replace('-', '/').replace('-', '/'))
-		// 计算详细项的截止时间
-		after = new Date(after.replace('-', '/').replace('-', '/'))
-		if (before.getTime() - after.getTime() === 0) {
-			return true
-		} else {
-			return false
-		}
-	}
-
-
-	/**
-	 * 获取日期范围内所有日期
-	 * @param {Object} begin
-	 * @param {Object} end
-	 */
-	geDateAll(begin, end) {
-		var arr = []
-		var ab = begin.split('-')
-		var ae = end.split('-')
-		var db = new Date()
-		db.setFullYear(ab[0], ab[1] - 1, ab[2])
-		var de = new Date()
-		de.setFullYear(ae[0], ae[1] - 1, ae[2])
-		var unixDb = db.getTime() - 24 * 60 * 60 * 1000
-		var unixDe = de.getTime() - 24 * 60 * 60 * 1000
-		for (var k = unixDb; k <= unixDe;) {
-			k = k + 24 * 60 * 60 * 1000
-			arr.push(this.getDate(new Date(parseInt(k))).fullDate)
-		}
-		return arr
-	}
-	/**
-	 * 计算阴历日期显示
-	 */
-	getlunar(year, month, date) {
-		return CALENDAR.solar2lunar(year, month, date)
-	}
-	/**
-	 * 设置打点
-	 */
-	setSelectInfo(data, value) {
-		this.selected = value
-		this._getWeek(data)
-	}
-
-	/**
-	 *  获取多选状态
-	 */
-	setMultiple(fullDate) {
-		let {
-			before,
-			after
-		} = this.multipleStatus
-
-		if (!this.range) return
-		if (before && after) {
-			this.multipleStatus.before = ''
-			this.multipleStatus.after = ''
-			this.multipleStatus.data = []
-		} else {
-			if (!before) {
-				this.multipleStatus.before = fullDate
-			} else {
-				this.multipleStatus.after = fullDate
-				if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
-					this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
-				} else {
-					this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
-				}
-			}
-		}
-		this._getWeek(fullDate)
-	}
-
-	/**
-	 * 获取每周数据
-	 * @param {Object} dateData
-	 */
-	_getWeek(dateData) {
-		const {
-			fullDate,
-			year,
-			month,
-			date,
-			day
-		} = this.getDate(dateData)
-		let firstDay = new Date(year, month - 1, 1).getDay()
-		let currentDay = new Date(year, month, 0).getDate()
-		let dates = {
-			lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
-			currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
-			nextMonthDays: [], // 下个月开始几天
-			weeks: []
-		}
-		let canlender = []
-		const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
-		dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
-		canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
-		let weeks = {}
-		// 拼接数组  上个月开始几天 + 本月天数+ 下个月开始几天
-		for (let i = 0; i < canlender.length; i++) {
-			if (i % 7 === 0) {
-				weeks[parseInt(i / 7)] = new Array(7)
-			}
-			weeks[parseInt(i / 7)][i % 7] = canlender[i]
-		}
-		this.canlender = canlender
-		this.weeks = weeks
-	}
-
-	//静态方法
-	// static init(date) {
-	// 	if (!this.instance) {
-	// 		this.instance = new Calendar(date);
-	// 	}
-	// 	return this.instance;
-	// }
-}
-
-
-export default Calendar

+ 0 - 100
components/uni-forms/changelog.md

@@ -1,100 +0,0 @@
-## 1.4.13(2024-10-08)
-- 修复 校验规则在抖音开发者工具上不生效的bug,详见:[https://ask.dcloud.net.cn/question/191933](https://ask.dcloud.net.cn/question/191933)
-## 1.4.12 (2024-9-21)
-- 修复 form上次修改的问题
-## 1.4.11 (2024-9-14)
-- 修复 binddata的兼容性问题
-## 1.4.10(2023-11-03)
-- 优化 labelWidth 描述错误
-## 1.4.9(2023-02-10)
-- 修复 required 参数无法动态绑定
-## 1.4.8(2022-08-23)
-- 优化 根据 rules 自动添加 required 的问题
-## 1.4.7(2022-08-22)
-- 修复 item 未设置 require 属性,rules 设置 require 后,星号也显示的 bug,详见:[https://ask.dcloud.net.cn/question/151540](https://ask.dcloud.net.cn/question/151540)
-## 1.4.6(2022-07-13)
-- 修复 model 需要校验的值没有声明对应字段时,导致第一次不触发校验的bug
-## 1.4.5(2022-07-05)
-- 新增 更多表单示例
-- 优化 子表单组件过期提示的问题
-- 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
-## 1.4.4(2022-07-04)
-- 更新 删除组件日志
-## 1.4.3(2022-07-04)
-- 修复 由 1.4.0 引发的 label 插槽不生效的bug
-## 1.4.2(2022-07-04)
-- 修复 子组件找不到 setValue 报错的bug
-## 1.4.1(2022-07-04)
-- 修复 uni-data-picker 在 uni-forms-item 中报错的bug
-- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
-## 1.4.0(2022-06-30)
-- 【重要】组件逻辑重构,部分用法用旧版本不兼容,请注意兼容问题
-- 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
-- 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
-- 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
-- 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法
-- 新增 子表单的 setRules 方法,配合自定义校验函数使用
-- 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
-- 优化 动态表单校验方式,废弃拼接name的方式
-## 1.3.3(2022-06-22)
-- 修复 表单校验顺序无序问题
-## 1.3.2(2021-12-09)
--
-## 1.3.1(2021-11-19)
-- 修复 label 插槽不生效的bug
-## 1.3.0(2021-11-19)
-- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
-- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-forms](https://uniapp.dcloud.io/component/uniui/uni-forms)
-## 1.2.7(2021-08-13)
-- 修复 没有添加校验规则的字段依然报错的Bug
-## 1.2.6(2021-08-11)
-- 修复 重置表单错误信息无法清除的问题
-## 1.2.5(2021-08-11)
-- 优化 组件文档
-## 1.2.4(2021-08-11)
-- 修复 表单验证只生效一次的问题
-## 1.2.3(2021-07-30)
-- 优化 vue3下事件警告的问题
-## 1.2.2(2021-07-26)
-- 修复 vue2 下条件编译导致destroyed生命周期失效的Bug
-- 修复 1.2.1 引起的示例在小程序平台报错的Bug
-## 1.2.1(2021-07-22)
-- 修复 动态校验表单,默认值为空的情况下校验失效的Bug
-- 修复 不指定name属性时,运行报错的Bug
-- 优化 label默认宽度从65调整至70,使required为true且四字时不换行
-- 优化 组件示例,新增动态校验示例代码
-- 优化 组件文档,使用方式更清晰
-## 1.2.0(2021-07-13)
-- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
-## 1.1.2(2021-06-25)
-- 修复 pattern 属性在微信小程序平台无效的问题
-## 1.1.1(2021-06-22)
-- 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug
-## 1.1.0(2021-06-22)
-- 修复 只写setRules方法而导致校验不生效的Bug
-- 修复 由上个办法引发的错误提示文字错位的Bug
-## 1.0.48(2021-06-21)
-- 修复 不设置 label 属性 ,无法设置label插槽的问题
-## 1.0.47(2021-06-21)
-- 修复 不设置label属性,label-width属性不生效的bug
-- 修复 setRules 方法与rules属性冲突的问题
-## 1.0.46(2021-06-04)
-- 修复 动态删减数据导致报错的问题
-## 1.0.45(2021-06-04)
-- 新增 modelValue 属性 ,value 即将废弃
-## 1.0.44(2021-06-02)
-- 新增 uni-forms-item 可以设置单独的 rules
-- 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤
-- 优化 submit 事件重命名为 validate
-## 1.0.43(2021-05-12)
-- 新增 组件示例地址
-## 1.0.42(2021-04-30)
-- 修复 自定义检验器失效的问题
-## 1.0.41(2021-03-05)
-- 更新 校验器
-- 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug
-## 1.0.40(2021-03-04)
-- 修复 动态显示uni-forms-item的情况下,submit 方法获取值错误的Bug
-## 1.0.39(2021-02-05)
-- 调整为uni_modules目录规范
-- 修复 校验器传入 int 等类型 ,返回String类型的Bug

+ 0 - 632
components/uni-forms/components/uni-forms-item/uni-forms-item.vue

@@ -1,632 +0,0 @@
-<template>
-	<view class="uni-forms-item"
-		:class="['is-direction-' + localLabelPos ,border?'uni-forms-item--border':'' ,border && isFirstBorder?'is-first-border':'']">
-		<slot name="label">
-			<view class="uni-forms-item__label" :class="{'no-label':!label && !required}"
-				:style="{width:localLabelWidth,justifyContent: localLabelAlign}">
-				<text v-if="required" class="is-required">*</text>
-				<text>{{label}}</text>
-			</view>
-		</slot>
-		<!-- #ifndef APP-NVUE -->
-		<view class="uni-forms-item__content">
-			<slot></slot>
-			<view class="uni-forms-item__error" :class="{'msg--active':msg}">
-				<text>{{msg}}</text>
-			</view>
-		</view>
-		<!-- #endif -->
-		<!-- #ifdef APP-NVUE -->
-		<view class="uni-forms-item__nuve-content">
-			<view class="uni-forms-item__content">
-				<slot></slot>
-			</view>
-			<view class="uni-forms-item__error" :class="{'msg--active':msg}">
-				<text class="error-text">{{msg}}</text>
-			</view>
-		</view>
-		<!-- #endif -->
-	</view>
-</template>
-
-<script>
-	/**
-	 * uni-fomrs-item 表单子组件
-	 * @description uni-fomrs-item 表单子组件,提供了基础布局已经校验能力
-	 * @tutorial https://ext.dcloud.net.cn/plugin?id=2773
-	 * @property {Boolean} required 是否必填,左边显示红色"*"号
-	 * @property {String } 	label 				输入框左边的文字提示
-	 * @property {Number } 	labelWidth 			label的宽度,单位px(默认70)
-	 * @property {String } 	labelAlign = [left|center|right] label的文字对齐方式(默认left)
-	 * 	@value left		label 左侧显示
-	 * 	@value center	label 居中
-	 * 	@value right	label 右侧对齐
-	 * @property {String } 	errorMessage 		显示的错误提示内容,如果为空字符串或者false,则不显示错误信息
-	 * @property {String } 	name 				表单域的属性名,在使用校验规则时必填
-	 * @property {String } 	leftIcon 			【1.4.0废弃】label左边的图标,限 uni-ui 的图标名称
-	 * @property {String } 	iconColor 		【1.4.0废弃】左边通过icon配置的图标的颜色(默认#606266)
-	 * @property {String} validateTrigger = [bind|submit|blur]	【1.4.0废弃】校验触发器方式 默认 submit
-	 * 	@value bind 	发生变化时触发
-	 * 	@value submit 提交时触发
-	 * 	@value blur 	失去焦点触发
-	 * @property {String } 	labelPosition = [top|left] 【1.4.0废弃】label的文字的位置(默认left)
-	 * 	@value top	顶部显示 label
-	 * 	@value left	左侧显示 label
-	 */
-
-	export default {
-		name: 'uniFormsItem',
-		options: {
-			// #ifdef MP-TOUTIAO
-			virtualHost: false,
-			// #endif
-			// #ifndef MP-TOUTIAO
-			virtualHost: true
-			// #endif
-		},
-		provide() {
-			return {
-				uniFormItem: this
-			}
-		},
-		inject: {
-			form: {
-				from: 'uniForm',
-				default: null
-			},
-		},
-		props: {
-			// 表单校验规则
-			rules: {
-				type: Array,
-				default () {
-					return null;
-				}
-			},
-			// 表单域的属性名,在使用校验规则时必填
-			name: {
-				type: [String, Array],
-				default: ''
-			},
-			required: {
-				type: Boolean,
-				default: false
-			},
-			label: {
-				type: String,
-				default: ''
-			},
-			// label的宽度
-			labelWidth: {
-				type: [String, Number],
-				default: ''
-			},
-			// label 居中方式,默认 left 取值 left/center/right
-			labelAlign: {
-				type: String,
-				default: ''
-			},
-			// 强制显示错误信息
-			errorMessage: {
-				type: [String, Boolean],
-				default: ''
-			},
-			// 1.4.0 弃用,统一使用 form 的校验时机
-			// validateTrigger: {
-			// 	type: String,
-			// 	default: ''
-			// },
-			// 1.4.0 弃用,统一使用 form 的label 位置
-			// labelPosition: {
-			// 	type: String,
-			// 	default: ''
-			// },
-			// 1.4.0 以下属性已经废弃,请使用  #label 插槽代替
-			leftIcon: String,
-			iconColor: {
-				type: String,
-				default: '#606266'
-			},
-		},
-		data() {
-			return {
-				errMsg: '',
-				userRules: null,
-				localLabelAlign: 'left',
-				localLabelWidth: '70px',
-				localLabelPos: 'left',
-				border: false,
-				isFirstBorder: false,
-			};
-		},
-		computed: {
-			// 处理错误信息
-			msg() {
-				return this.errorMessage || this.errMsg;
-			}
-		},
-		watch: {
-			// 规则发生变化通知子组件更新
-			'form.formRules'(val) {
-				// TODO 处理头条vue3 watch不生效的问题
-				// #ifndef MP-TOUTIAO
-				this.init()
-				// #endif
-			},
-			'form.labelWidth'(val) {
-				// 宽度
-				this.localLabelWidth = this._labelWidthUnit(val)
-
-			},
-			'form.labelPosition'(val) {
-				// 标签位置
-				this.localLabelPos = this._labelPosition()
-			},
-			'form.labelAlign'(val) {
-
-			}
-		},
-		created() {
-			this.init(true)
-			if (this.name && this.form) {
-				// TODO 处理头条vue3 watch不生效的问题
-				// #ifdef MP-TOUTIAO
-				this.$watch('form.formRules', () => {
-					this.init()
-				})
-				// #endif
-
-				// 监听变化
-				this.$watch(
-					() => {
-						const val = this.form._getDataValue(this.name, this.form.localData)
-						return val
-					},
-					(value, oldVal) => {
-						const isEqual = this.form._isEqual(value, oldVal)
-						// 简单判断前后值的变化,只有发生变化才会发生校验
-						// TODO  如果 oldVal = undefined ,那么大概率是源数据里没有值导致 ,这个情况不哦校验 ,可能不严谨 ,需要在做观察
-						// fix by mehaotian 暂时取消 && oldVal !== undefined ,如果formData 中不存在,可能会不校验
-						if (!isEqual) {
-							const val = this.itemSetValue(value)
-							this.onFieldChange(val, false)
-						}
-					}, {
-						immediate: false
-					}
-				);
-			}
-
-		},
-		// #ifndef VUE3
-		destroyed() {
-			if (this.__isUnmounted) return
-			this.unInit()
-		},
-		// #endif
-		// #ifdef VUE3
-		unmounted() {
-			this.__isUnmounted = true
-			this.unInit()
-		},
-		// #endif
-		methods: {
-			/**
-			 * 外部调用方法
-			 * 设置规则 ,主要用于小程序自定义检验规则
-			 * @param {Array} rules 规则源数据
-			 */
-			setRules(rules = null) {
-				this.userRules = rules
-				this.init(false)
-			},
-			// 兼容老版本表单组件
-			setValue() {
-				// console.log('setValue 方法已经弃用,请使用最新版本的 uni-forms 表单组件以及其他关联组件。');
-			},
-			/**
-			 * 外部调用方法
-			 * 校验数据
-			 * @param {any} value 需要校验的数据
-			 * @param {boolean} 是否立即校验
-			 * @return {Array|null} 校验内容
-			 */
-			async onFieldChange(value, formtrigger = true) {
-				const {
-					formData,
-					localData,
-					errShowType,
-					validateCheck,
-					validateTrigger,
-					_isRequiredField,
-					_realName
-				} = this.form
-				const name = _realName(this.name)
-				if (!value) {
-					value = this.form.formData[name]
-				}
-				// fixd by mehaotian 不在校验前清空信息,解决闪屏的问题
-				// this.errMsg = '';
-
-				// fix by mehaotian 解决没有检验规则的情况下,抛出错误的问题
-				const ruleLen = this.itemRules.rules && this.itemRules.rules.length
-				if (!this.validator || !ruleLen || ruleLen === 0) return;
-
-				// 检验时机
-				// let trigger = this.isTrigger(this.itemRules.validateTrigger, this.validateTrigger, validateTrigger);
-				const isRequiredField = _isRequiredField(this.itemRules.rules || []);
-				let result = null;
-				// 只有等于 bind 时 ,才能开启时实校验
-				if (validateTrigger === 'bind' || formtrigger) {
-					// 校验当前表单项
-					result = await this.validator.validateUpdate({
-							[name]: value
-						},
-						formData
-					);
-
-					// 判断是否必填,非必填,不填不校验,填写才校验 ,暂时只处理 undefined  和空的情况
-					if (!isRequiredField && (value === undefined || value === '')) {
-						result = null;
-					}
-
-					// 判断错误信息显示类型
-					if (result && result.errorMessage) {
-						if (errShowType === 'undertext') {
-							// 获取错误信息
-							this.errMsg = !result ? '' : result.errorMessage;
-						}
-						if (errShowType === 'toast') {
-							uni.showToast({
-								title: result.errorMessage || '校验错误',
-								icon: 'none'
-							});
-						}
-						if (errShowType === 'modal') {
-							uni.showModal({
-								title: '提示',
-								content: result.errorMessage || '校验错误'
-							});
-						}
-					} else {
-						this.errMsg = ''
-					}
-					// 通知 form 组件更新事件
-					validateCheck(result ? result : null)
-				} else {
-					this.errMsg = ''
-				}
-				return result ? result : null;
-			},
-			/**
-			 * 初始组件数据
-			 */
-			init(type = false) {
-				const {
-					validator,
-					formRules,
-					childrens,
-					formData,
-					localData,
-					_realName,
-					labelWidth,
-					_getDataValue,
-					_setDataValue
-				} = this.form || {}
-				// 对齐方式
-				this.localLabelAlign = this._justifyContent()
-				// 宽度
-				this.localLabelWidth = this._labelWidthUnit(labelWidth)
-				// 标签位置
-				this.localLabelPos = this._labelPosition()
-				// 将需要校验的子组件加入form 队列
-				this.form && type && childrens.push(this)
-
-				if (!validator || !formRules) return
-				// 判断第一个 item
-				if (!this.form.isFirstBorder) {
-					this.form.isFirstBorder = true;
-					this.isFirstBorder = true;
-				}
-
-				// 判断 group 里的第一个 item
-				if (this.group) {
-					if (!this.group.isFirstBorder) {
-						this.group.isFirstBorder = true;
-						this.isFirstBorder = true;
-					}
-				}
-				this.border = this.form.border;
-				// 获取子域的真实名称
-				const name = _realName(this.name)
-				const itemRule = this.userRules || this.rules
-				if (typeof formRules === 'object' && itemRule) {
-					// 子规则替换父规则
-					formRules[name] = {
-						rules: itemRule
-					}
-					validator.updateSchema(formRules);
-				}
-				// 注册校验规则
-				const itemRules = formRules[name] || {}
-				this.itemRules = itemRules
-				// 注册校验函数
-				this.validator = validator
-				// 默认值赋予
-				this.itemSetValue(_getDataValue(this.name, localData))
-			},
-			unInit() {
-				if (this.form) {
-					const {
-						childrens,
-						formData,
-						_realName
-					} = this.form
-					childrens.forEach((item, index) => {
-						if (item === this) {
-							this.form.childrens.splice(index, 1)
-							delete formData[_realName(item.name)]
-						}
-					})
-				}
-			},
-			// 设置item 的值
-			itemSetValue(value) {
-				const name = this.form._realName(this.name)
-				const rules = this.itemRules.rules || []
-				const val = this.form._getValue(name, value, rules)
-				this.form._setDataValue(name, this.form.formData, val)
-				return val
-			},
-
-			/**
-			 * 移除该表单项的校验结果
-			 */
-			clearValidate() {
-				this.errMsg = '';
-			},
-
-			// 是否显示星号
-			_isRequired() {
-				// TODO 不根据规则显示 星号,考虑后续兼容
-				// if (this.form) {
-				// 	if (this.form._isRequiredField(this.itemRules.rules || []) && this.required) {
-				// 		return true
-				// 	}
-				// 	return false
-				// }
-				return this.required
-			},
-
-			// 处理对齐方式
-			_justifyContent() {
-				if (this.form) {
-					const {
-						labelAlign
-					} = this.form
-					let labelAli = this.labelAlign ? this.labelAlign : labelAlign;
-					if (labelAli === 'left') return 'flex-start';
-					if (labelAli === 'center') return 'center';
-					if (labelAli === 'right') return 'flex-end';
-				}
-				return 'flex-start';
-			},
-			// 处理 label宽度单位 ,继承父元素的值
-			_labelWidthUnit(labelWidth) {
-
-				// if (this.form) {
-				// 	const {
-				// 		labelWidth
-				// 	} = this.form
-				return this.num2px(this.labelWidth ? this.labelWidth : (labelWidth || (this.label ? 70 : 'auto')))
-				// }
-				// return '70px'
-			},
-			// 处理 label 位置
-			_labelPosition() {
-				if (this.form) return this.form.labelPosition || 'left'
-				return 'left'
-
-			},
-
-			/**
-			 * 触发时机
-			 * @param {Object} rule 当前规则内时机
-			 * @param {Object} itemRlue 当前组件时机
-			 * @param {Object} parentRule 父组件时机
-			 */
-			isTrigger(rule, itemRlue, parentRule) {
-				//  bind  submit
-				if (rule === 'submit' || !rule) {
-					if (rule === undefined) {
-						if (itemRlue !== 'bind') {
-							if (!itemRlue) {
-								return parentRule === '' ? 'bind' : 'submit';
-							}
-							return 'submit';
-						}
-						return 'bind';
-					}
-					return 'submit';
-				}
-				return 'bind';
-			},
-			num2px(num) {
-				if (typeof num === 'number') {
-					return `${num}px`
-				}
-				return num
-			}
-		}
-	};
-</script>
-
-<style lang="scss">
-	.uni-forms-item {
-		position: relative;
-		display: flex;
-		/* #ifdef APP-NVUE */
-		// 在 nvue 中,使用 margin-bottom error 信息会被隐藏
-		padding-bottom: 22px;
-		/* #endif */
-		/* #ifndef APP-NVUE */
-		margin-bottom: 22px;
-		/* #endif */
-		flex-direction: row;
-
-		&__label {
-			display: flex;
-			flex-direction: row;
-			align-items: center;
-			text-align: left;
-			font-size: 14px;
-			color: #606266;
-			height: 36px;
-			padding: 0 12px 0 0;
-			/* #ifndef APP-NVUE */
-			vertical-align: middle;
-			flex-shrink: 0;
-			/* #endif */
-
-			/* #ifndef APP-NVUE */
-			box-sizing: border-box;
-
-			/* #endif */
-			&.no-label {
-				padding: 0;
-			}
-		}
-
-		&__content {
-			/* #ifndef MP-TOUTIAO */
-			// display: flex;
-			// align-items: center;
-			/* #endif */
-			position: relative;
-			font-size: 14px;
-			flex: 1;
-			/* #ifndef APP-NVUE */
-			box-sizing: border-box;
-			/* #endif */
-			flex-direction: row;
-
-			/* #ifndef APP || H5 || MP-WEIXIN || APP-NVUE */
-			// TODO 因为小程序平台会多一层标签节点 ,所以需要在多余节点继承当前样式
-			&>uni-easyinput,
-			&>uni-data-picker {
-				width: 100%;
-			}
-
-			/* #endif */
-
-		}
-
-		& .uni-forms-item__nuve-content {
-			display: flex;
-			flex-direction: column;
-			flex: 1;
-		}
-
-		&__error {
-			color: #f56c6c;
-			font-size: 12px;
-			line-height: 1;
-			padding-top: 4px;
-			position: absolute;
-			/* #ifndef APP-NVUE */
-			top: 100%;
-			left: 0;
-			transition: transform 0.3s;
-			transform: translateY(-100%);
-			/* #endif */
-			/* #ifdef APP-NVUE */
-			bottom: 5px;
-			/* #endif */
-
-			opacity: 0;
-
-			.error-text {
-				// 只有 nvue 下这个样式才生效
-				color: #f56c6c;
-				font-size: 12px;
-			}
-
-			&.msg--active {
-				opacity: 1;
-				transform: translateY(0%);
-			}
-		}
-
-		// 位置修饰样式
-		&.is-direction-left {
-			flex-direction: row;
-		}
-
-		&.is-direction-top {
-			flex-direction: column;
-
-			.uni-forms-item__label {
-				padding: 0 0 8px;
-				line-height: 1.5715;
-				text-align: left;
-				/* #ifndef APP-NVUE */
-				white-space: initial;
-				/* #endif */
-			}
-		}
-
-		.is-required {
-			// color: $uni-color-error;
-			color: #dd524d;
-			font-weight: bold;
-		}
-	}
-
-
-	.uni-forms-item--border {
-		margin-bottom: 0;
-		padding: 10px 0;
-		// padding-bottom: 0;
-		border-top: 1px #eee solid;
-
-		/* #ifndef APP-NVUE */
-		.uni-forms-item__content {
-			flex-direction: column;
-			justify-content: flex-start;
-			align-items: flex-start;
-
-			.uni-forms-item__error {
-				position: relative;
-				top: 5px;
-				left: 0;
-				padding-top: 0;
-			}
-		}
-
-		/* #endif */
-
-		/* #ifdef APP-NVUE */
-		display: flex;
-		flex-direction: column;
-
-		.uni-forms-item__error {
-			position: relative;
-			top: 0px;
-			left: 0;
-			padding-top: 0;
-			margin-top: 5px;
-		}
-
-		/* #endif */
-
-	}
-
-	.is-first-border {
-		/* #ifndef APP-NVUE */
-		border: none;
-		/* #endif */
-		/* #ifdef APP-NVUE */
-		border-width: 0;
-		/* #endif */
-	}
-</style>

+ 0 - 404
components/uni-forms/components/uni-forms/uni-forms.vue

@@ -1,404 +0,0 @@
-<template>
-	<view class="uni-forms">
-		<form>
-			<slot></slot>
-		</form>
-	</view>
-</template>
-
-<script>
-	import Validator from './validate.js';
-	import {
-		deepCopy,
-		getValue,
-		isRequiredField,
-		setDataValue,
-		getDataValue,
-		realName,
-		isRealName,
-		rawData,
-		isEqual
-	} from './utils.js'
-
-	// #ifndef VUE3
-	// 后续会慢慢废弃这个方法
-	import Vue from 'vue';
-	Vue.prototype.binddata = function(name, value, formName) {
-		if (formName) {
-			this.$refs[formName].setValue(name, value);
-		} else {
-			let formVm;
-			for (let i in this.$refs) {
-				const vm = this.$refs[i];
-				if (vm && vm.$options && vm.$options.name === 'uniForms') {
-					formVm = vm;
-					break;
-				}
-			}
-			if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
-			formVm.setValue(name, value);
-		}
-	};
-	// #endif
-	/**
-	 * Forms 表单
-	 * @description 由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据
-	 * @tutorial https://ext.dcloud.net.cn/plugin?id=2773
-	 * @property {Object} rules	表单校验规则
-	 * @property {String} validateTrigger = [bind|submit|blur]	校验触发器方式 默认 submit
-	 * @value bind		发生变化时触发
-	 * @value submit	提交时触发
-	 * @value blur	  失去焦点时触发
-	 * @property {String} labelPosition = [top|left]	label 位置 默认 left
-	 * @value top		顶部显示 label
-	 * @value left	左侧显示 label
-	 * @property {String} labelWidth	label 宽度,默认 70px
-	 * @property {String} labelAlign = [left|center|right]	label 居中方式  默认 left
-	 * @value left		label 左侧显示
-	 * @value center	label 居中
-	 * @value right		label 右侧对齐
-	 * @property {String} errShowType = [undertext|toast|modal]	校验错误信息提示方式
-	 * @value undertext	错误信息在底部显示
-	 * @value toast			错误信息toast显示
-	 * @value modal			错误信息modal显示
-	 * @event {Function} submit	提交时触发
-	 * @event {Function} validate	校验结果发生变化触发
-	 */
-	export default {
-		name: 'uniForms',
-		emits: ['validate', 'submit'],
-		options: {
-			// #ifdef MP-TOUTIAO
-			virtualHost: false,
-			// #endif
-			// #ifndef MP-TOUTIAO
-			virtualHost: true
-			// #endif
-		},
-		props: {
-			// 即将弃用
-			value: {
-				type: Object,
-				default () {
-					return null;
-				}
-			},
-			// vue3 替换 value 属性
-			modelValue: {
-				type: Object,
-				default () {
-					return null;
-				}
-			},
-			// 1.4.0 开始将不支持 v-model ,且废弃 value 和 modelValue
-			model: {
-				type: Object,
-				default () {
-					return null;
-				}
-			},
-			// 表单校验规则
-			rules: {
-				type: Object,
-				default () {
-					return {};
-				}
-			},
-			//校验错误信息提示方式 默认 undertext 取值 [undertext|toast|modal]
-			errShowType: {
-				type: String,
-				default: 'undertext'
-			},
-			// 校验触发器方式 默认 bind 取值 [bind|submit]
-			validateTrigger: {
-				type: String,
-				default: 'submit'
-			},
-			// label 位置,默认 left 取值  top/left
-			labelPosition: {
-				type: String,
-				default: 'left'
-			},
-			// label 宽度
-			labelWidth: {
-				type: [String, Number],
-				default: ''
-			},
-			// label 居中方式,默认 left 取值 left/center/right
-			labelAlign: {
-				type: String,
-				default: 'left'
-			},
-			border: {
-				type: Boolean,
-				default: false
-			}
-		},
-		provide() {
-			return {
-				uniForm: this
-			}
-		},
-		data() {
-			return {
-				// 表单本地值的记录,不应该与传如的值进行关联
-				formData: {},
-				formRules: {}
-			};
-		},
-		computed: {
-			// 计算数据源变化的
-			localData() {
-				const localVal = this.model || this.modelValue || this.value
-				if (localVal) {
-					return deepCopy(localVal)
-				}
-				return {}
-			}
-		},
-		watch: {
-			// 监听数据变化 ,暂时不使用,需要单独赋值
-			// localData: {},
-			// 监听规则变化
-			rules: {
-				handler: function(val, oldVal) {
-					this.setRules(val)
-				},
-				deep: true,
-				immediate: true
-			}
-		},
-		created() {
-			// #ifdef VUE3
-			let getbinddata = getApp().$vm.$.appContext.config.globalProperties.binddata
-			if (!getbinddata) {
-				getApp().$vm.$.appContext.config.globalProperties.binddata = function(name, value, formName) {
-					if (formName) {
-						this.$refs[formName].setValue(name, value);
-					} else {
-						let formVm;
-						for (let i in this.$refs) {
-							const vm = this.$refs[i];
-							if (vm && vm.$options && vm.$options.name === 'uniForms') {
-								formVm = vm;
-								break;
-							}
-						}
-						if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
-						if(formVm.model)formVm.model[name] = value
-						if(formVm.modelValue)formVm.modelValue[name] = value
-						if(formVm.value)formVm.value[name] = value
-					}
-				}
-			}
-			// #endif
-
-			// 子组件实例数组
-			this.childrens = []
-			// TODO 兼容旧版 uni-data-picker ,新版本中无效,只是避免报错
-			this.inputChildrens = []
-			this.setRules(this.rules)
-		},
-		methods: {
-			/**
-			 * 外部调用方法
-			 * 设置规则 ,主要用于小程序自定义检验规则
-			 * @param {Array} rules 规则源数据
-			 */
-			setRules(rules) {
-				// TODO 有可能子组件合并规则的时机比这个要早,所以需要合并对象 ,而不是直接赋值,可能会被覆盖
-				this.formRules = Object.assign({}, this.formRules, rules)
-				// 初始化校验函数
-				this.validator = new Validator(rules);
-			},
-
-			/**
-			 * 外部调用方法
-			 * 设置数据,用于设置表单数据,公开给用户使用 , 不支持在动态表单中使用
-			 * @param {Object} key
-			 * @param {Object} value
-			 */
-			setValue(key, value) {
-				let example = this.childrens.find(child => child.name === key);
-				if (!example) return null;
-				this.formData[key] = getValue(key, value, (this.formRules[key] && this.formRules[key].rules) || [])
-				return example.onFieldChange(this.formData[key]);
-			},
-
-			/**
-			 * 外部调用方法
-			 * 手动提交校验表单
-			 * 对整个表单进行校验的方法,参数为一个回调函数。
-			 * @param {Array} keepitem 保留不参与校验的字段
-			 * @param {type} callback 方法回调
-			 */
-			validate(keepitem, callback) {
-				return this.checkAll(this.formData, keepitem, callback);
-			},
-
-			/**
-			 * 外部调用方法
-			 * 部分表单校验
-			 * @param {Array|String} props 需要校验的字段
-			 * @param {Function} 回调函数
-			 */
-			validateField(props = [], callback) {
-				props = [].concat(props);
-				let invalidFields = {};
-				this.childrens.forEach(item => {
-					const name = realName(item.name)
-					if (props.indexOf(name) !== -1) {
-						invalidFields = Object.assign({}, invalidFields, {
-							[name]: this.formData[name]
-						});
-					}
-				});
-				return this.checkAll(invalidFields, [], callback);
-			},
-
-			/**
-			 * 外部调用方法
-			 * 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果
-			 * @param {Array|String} props 需要移除校验的字段 ,不填为所有
-			 */
-			clearValidate(props = []) {
-				props = [].concat(props);
-				this.childrens.forEach(item => {
-					if (props.length === 0) {
-						item.errMsg = '';
-					} else {
-						const name = realName(item.name)
-						if (props.indexOf(name) !== -1) {
-							item.errMsg = '';
-						}
-					}
-				});
-			},
-
-			/**
-			 * 外部调用方法 ,即将废弃
-			 * 手动提交校验表单
-			 * 对整个表单进行校验的方法,参数为一个回调函数。
-			 * @param {Array} keepitem 保留不参与校验的字段
-			 * @param {type} callback 方法回调
-			 */
-			submit(keepitem, callback, type) {
-				for (let i in this.dataValue) {
-					const itemData = this.childrens.find(v => v.name === i);
-					if (itemData) {
-						if (this.formData[i] === undefined) {
-							this.formData[i] = this._getValue(i, this.dataValue[i]);
-						}
-					}
-				}
-
-				if (!type) {
-					console.warn('submit 方法即将废弃,请使用validate方法代替!');
-				}
-
-				return this.checkAll(this.formData, keepitem, callback, 'submit');
-			},
-
-			// 校验所有
-			async checkAll(invalidFields, keepitem, callback, type) {
-				// 不存在校验规则 ,则停止校验流程
-				if (!this.validator) return
-				let childrens = []
-				// 处理参与校验的item实例
-				for (let i in invalidFields) {
-					const item = this.childrens.find(v => realName(v.name) === i)
-					if (item) {
-						childrens.push(item)
-					}
-				}
-
-				// 如果validate第一个参数是funciont ,那就走回调
-				if (!callback && typeof keepitem === 'function') {
-					callback = keepitem;
-				}
-
-				let promise;
-				// 如果不存在回调,那么使用 Promise 方式返回
-				if (!callback && typeof callback !== 'function' && Promise) {
-					promise = new Promise((resolve, reject) => {
-						callback = function(valid, invalidFields) {
-							!valid ? resolve(invalidFields) : reject(valid);
-						};
-					});
-				}
-
-				let results = [];
-				// 避免引用错乱 ,建议拷贝对象处理
-				let tempFormData = JSON.parse(JSON.stringify(invalidFields))
-				// 所有子组件参与校验,使用 for 可以使用  awiat
-				for (let i in childrens) {
-					const child = childrens[i]
-					let name = realName(child.name);
-					const result = await child.onFieldChange(tempFormData[name]);
-					if (result) {
-						results.push(result);
-						// toast ,modal 只需要执行第一次就可以
-						if (this.errShowType === 'toast' || this.errShowType === 'modal') break;
-					}
-				}
-
-
-				if (Array.isArray(results)) {
-					if (results.length === 0) results = null;
-				}
-				if (Array.isArray(keepitem)) {
-					keepitem.forEach(v => {
-						let vName = realName(v);
-						let value = getDataValue(v, this.localData)
-						if (value !== undefined) {
-							tempFormData[vName] = value
-						}
-					});
-				}
-
-				// TODO submit 即将废弃
-				if (type === 'submit') {
-					this.$emit('submit', {
-						detail: {
-							value: tempFormData,
-							errors: results
-						}
-					});
-				} else {
-					this.$emit('validate', results);
-				}
-
-				// const resetFormData = rawData(tempFormData, this.localData, this.name)
-				let resetFormData = {}
-				resetFormData = rawData(tempFormData, this.name)
-				callback && typeof callback === 'function' && callback(results, resetFormData);
-
-				if (promise && callback) {
-					return promise;
-				} else {
-					return null;
-				}
-
-			},
-
-			/**
-			 * 返回validate事件
-			 * @param {Object} result
-			 */
-			validateCheck(result) {
-				this.$emit('validate', result);
-			},
-			_getValue: getValue,
-			_isRequiredField: isRequiredField,
-			_setDataValue: setDataValue,
-			_getDataValue: getDataValue,
-			_realName: realName,
-			_isRealName: isRealName,
-			_isEqual: isEqual
-		}
-	};
-</script>
-
-<style lang="scss">
-	.uni-forms {}
-</style>

+ 0 - 293
components/uni-forms/components/uni-forms/utils.js

@@ -1,293 +0,0 @@
-/**
- * 简单处理对象拷贝
- * @param {Obejct} 被拷贝对象
- * @@return {Object} 拷贝对象
- */
-export const deepCopy = (val) => {
-	return JSON.parse(JSON.stringify(val))
-}
-/**
- * 过滤数字类型
- * @param {String} format 数字类型
- * @@return {Boolean} 返回是否为数字类型
- */
-export const typeFilter = (format) => {
-	return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp';
-}
-
-/**
- * 把 value 转换成指定的类型,用于处理初始值,原因是初始值需要入库不能为 undefined
- * @param {String} key 字段名
- * @param {any} value 字段值
- * @param {Object} rules 表单校验规则
- */
-export const getValue = (key, value, rules) => {
-	const isRuleNumType = rules.find(val => val.format && typeFilter(val.format));
-	const isRuleBoolType = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool');
-	// 输入类型为 number
-	if (!!isRuleNumType) {
-		if (!value && value !== 0) {
-			value = null
-		} else {
-			value = isNumber(Number(value)) ? Number(value) : value
-		}
-	}
-
-	// 输入类型为 boolean
-	if (!!isRuleBoolType) {
-		value = isBoolean(value) ? value : false
-	}
-
-	return value;
-}
-
-/**
- * 获取表单数据
- * @param {String|Array} name 真实名称,需要使用 realName 获取
- * @param {Object} data 原始数据
- * @param {any} value  需要设置的值
- */
-export const setDataValue = (field, formdata, value) => {
-	formdata[field] = value
-	return value || ''
-}
-
-/**
- * 获取表单数据
- * @param {String|Array} field 真实名称,需要使用 realName 获取
- * @param {Object} data 原始数据
- */
-export const getDataValue = (field, data) => {
-	return objGet(data, field)
-}
-
-/**
- * 获取表单类型
- * @param {String|Array} field 真实名称,需要使用 realName 获取
- */
-export const getDataValueType = (field, data) => {
-	const value = getDataValue(field, data)
-	return {
-		type: type(value),
-		value
-	}
-}
-
-/**
- * 获取表单可用的真实name
- * @param {String|Array} name 表单name
- * @@return {String} 表单可用的真实name
- */
-export const realName = (name, data = {}) => {
-	const base_name = _basePath(name)
-	if (typeof base_name === 'object' && Array.isArray(base_name) && base_name.length > 1) {
-		const realname = base_name.reduce((a, b) => a += `#${b}`, '_formdata_')
-		return realname
-	}
-	return base_name[0] || name
-}
-
-/**
- * 判断是否表单可用的真实name
- * @param {String|Array} name 表单name
- * @@return {String} 表单可用的真实name
- */
-export const isRealName = (name) => {
-	const reg = /^_formdata_#*/
-	return reg.test(name)
-}
-
-/**
- * 获取表单数据的原始格式
- * @@return {Object|Array} object 需要解析的数据
- */
-export const rawData = (object = {}, name) => {
-	let newData = JSON.parse(JSON.stringify(object))
-	let formData = {}
-	for(let i in newData){
-		let path = name2arr(i)
-		objSet(formData,path,newData[i])
-	}
-	return formData
-}
-
-/**
- * 真实name还原为 array
- * @param {*} name 
- */
-export const name2arr = (name) => {
-	let field = name.replace('_formdata_#', '')
-	field = field.split('#').map(v => (isNumber(v) ? Number(v) : v))
-	return field
-}
-
-/**
- * 对象中设置值
- * @param {Object|Array} object 源数据
- * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c']
- * @param {String} value 需要设置的值
- */
-export const objSet = (object, path, value) => {
-	if (typeof object !== 'object') return object;
-	_basePath(path).reduce((o, k, i, _) => {
-		if (i === _.length - 1) { 
-			// 若遍历结束直接赋值
-			o[k] = value
-			return null
-		} else if (k in o) { 
-			// 若存在对应路径,则返回找到的对象,进行下一次遍历
-			return o[k]
-		} else { 
-			// 若不存在对应路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象
-			o[k] = /^[0-9]{1,}$/.test(_[i + 1]) ? [] : {}
-			return o[k]
-		}
-	}, object)
-	// 返回object
-	return object;
-}
-
-// 处理 path, path有三种形式:'a[0].b.c'、'a.0.b.c' 和 ['a','0','b','c'],需要统一处理成数组,便于后续使用
-function _basePath(path) {
-	// 若是数组,则直接返回
-	if (Array.isArray(path)) return path
-	// 若有 '[',']',则替换成将 '[' 替换成 '.',去掉 ']'
-	return path.replace(/\[/g, '.').replace(/\]/g, '').split('.')
-}
-
-/**
- * 从对象中获取值
- * @param {Object|Array} object 源数据
- * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c']
- * @param {String} defaultVal 如果无法从调用链中获取值的默认值
- */
-export const objGet = (object, path, defaultVal = 'undefined') => {
-	// 先将path处理成统一格式
-	let newPath = _basePath(path)
-	// 递归处理,返回最后结果
-	let val = newPath.reduce((o, k) => {
-		return (o || {})[k]
-	}, object);
-	return !val || val !== undefined ? val : defaultVal
-}
-
-
-/**
- * 是否为 number 类型 
- * @param {any} num 需要判断的值
- * @return {Boolean} 是否为 number
- */
-export const isNumber = (num) => {
-	return !isNaN(Number(num))
-}
-
-/**
- * 是否为 boolean 类型 
- * @param {any} bool 需要判断的值
- * @return {Boolean} 是否为 boolean
- */
-export const isBoolean = (bool) => {
-	return (typeof bool === 'boolean')
-}
-/**
- * 是否有必填字段
- * @param {Object} rules 规则
- * @return {Boolean} 是否有必填字段
- */
-export const isRequiredField = (rules) => {
-	let isNoField = false;
-	for (let i = 0; i < rules.length; i++) {
-		const ruleData = rules[i];
-		if (ruleData.required) {
-			isNoField = true;
-			break;
-		}
-	}
-	return isNoField;
-}
-
-
-/**
- * 获取数据类型
- * @param {Any} obj 需要获取数据类型的值
- */
-export const type = (obj) => {
-	var class2type = {};
-
-	// 生成class2type映射
-	"Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) {
-		class2type["[object " + item + "]"] = item.toLowerCase();
-	})
-	if (obj == null) {
-		return obj + "";
-	}
-	return typeof obj === "object" || typeof obj === "function" ?
-		class2type[Object.prototype.toString.call(obj)] || "object" :
-		typeof obj;
-}
-
-/**
- * 判断两个值是否相等
- * @param {any} a 值  
- * @param {any} b 值  
- * @return {Boolean} 是否相等
- */
-export const isEqual = (a, b) => {
-	//如果a和b本来就全等
-	if (a === b) {
-		//判断是否为0和-0
-		return a !== 0 || 1 / a === 1 / b;
-	}
-	//判断是否为null和undefined
-	if (a == null || b == null) {
-		return a === b;
-	}
-	//接下来判断a和b的数据类型
-	var classNameA = toString.call(a),
-		classNameB = toString.call(b);
-	//如果数据类型不相等,则返回false
-	if (classNameA !== classNameB) {
-		return false;
-	}
-	//如果数据类型相等,再根据不同数据类型分别判断
-	switch (classNameA) {
-		case '[object RegExp]':
-		case '[object String]':
-			//进行字符串转换比较
-			return '' + a === '' + b;
-		case '[object Number]':
-			//进行数字转换比较,判断是否为NaN
-			if (+a !== +a) {
-				return +b !== +b;
-			}
-			//判断是否为0或-0
-			return +a === 0 ? 1 / +a === 1 / b : +a === +b;
-		case '[object Date]':
-		case '[object Boolean]':
-			return +a === +b;
-	}
-	//如果是对象类型
-	if (classNameA == '[object Object]') {
-		//获取a和b的属性长度
-		var propsA = Object.getOwnPropertyNames(a),
-			propsB = Object.getOwnPropertyNames(b);
-		if (propsA.length != propsB.length) {
-			return false;
-		}
-		for (var i = 0; i < propsA.length; i++) {
-			var propName = propsA[i];
-			//如果对应属性对应值不相等,则返回false
-			if (a[propName] !== b[propName]) {
-				return false;
-			}
-		}
-		return true;
-	}
-	//如果是数组类型
-	if (classNameA == '[object Array]') {
-		if (a.toString() == b.toString()) {
-			return true;
-		}
-		return false;
-	}
-}

+ 0 - 486
components/uni-forms/components/uni-forms/validate.js

@@ -1,486 +0,0 @@
-var pattern = {
-	email: /^\S+?@\S+?\.\S+?$/,
-	idcard: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
-	url: new RegExp(
-		"^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$",
-		'i')
-};
-
-const FORMAT_MAPPING = {
-	"int": 'integer',
-	"bool": 'boolean',
-	"double": 'number',
-	"long": 'number',
-	"password": 'string'
-	// "fileurls": 'array'
-}
-
-function formatMessage(args, resources = '') {
-	var defaultMessage = ['label']
-	defaultMessage.forEach((item) => {
-		if (args[item] === undefined) {
-			args[item] = ''
-		}
-	})
-
-	let str = resources
-	for (let key in args) {
-		let reg = new RegExp('{' + key + '}')
-		str = str.replace(reg, args[key])
-	}
-	return str
-}
-
-function isEmptyValue(value, type) {
-	if (value === undefined || value === null) {
-		return true;
-	}
-
-	if (typeof value === 'string' && !value) {
-		return true;
-	}
-
-	if (Array.isArray(value) && !value.length) {
-		return true;
-	}
-
-	if (type === 'object' && !Object.keys(value).length) {
-		return true;
-	}
-
-	return false;
-}
-
-const types = {
-	integer(value) {
-		return types.number(value) && parseInt(value, 10) === value;
-	},
-	string(value) {
-		return typeof value === 'string';
-	},
-	number(value) {
-		if (isNaN(value)) {
-			return false;
-		}
-		return typeof value === 'number';
-	},
-	"boolean": function(value) {
-		return typeof value === 'boolean';
-	},
-	"float": function(value) {
-		return types.number(value) && !types.integer(value);
-	},
-	array(value) {
-		return Array.isArray(value);
-	},
-	object(value) {
-		return typeof value === 'object' && !types.array(value);
-	},
-	date(value) {
-		return value instanceof Date;
-	},
-	timestamp(value) {
-		if (!this.integer(value) || Math.abs(value).toString().length > 16) {
-			return false
-		}
-		return true;
-	},
-	file(value) {
-		return typeof value.url === 'string';
-	},
-	email(value) {
-		return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255;
-	},
-	url(value) {
-		return typeof value === 'string' && !!value.match(pattern.url);
-	},
-	pattern(reg, value) {
-		try {
-			return new RegExp(reg).test(value);
-		} catch (e) {
-			return false;
-		}
-	},
-	method(value) {
-		return typeof value === 'function';
-	},
-	idcard(value) {
-		return typeof value === 'string' && !!value.match(pattern.idcard);
-	},
-	'url-https'(value) {
-		return this.url(value) && value.startsWith('https://');
-	},
-	'url-scheme'(value) {
-		return value.startsWith('://');
-	},
-	'url-web'(value) {
-		return false;
-	}
-}
-
-class RuleValidator {
-
-	constructor(message) {
-		this._message = message
-	}
-
-	async validateRule(fieldKey, fieldValue, value, data, allData) {
-		var result = null
-
-		let rules = fieldValue.rules
-
-		let hasRequired = rules.findIndex((item) => {
-			return item.required
-		})
-		if (hasRequired < 0) {
-			if (value === null || value === undefined) {
-				return result
-			}
-			if (typeof value === 'string' && !value.length) {
-				return result
-			}
-		}
-
-		var message = this._message
-
-		if (rules === undefined) {
-			return message['default']
-		}
-
-		for (var i = 0; i < rules.length; i++) {
-			let rule = rules[i]
-			let vt = this._getValidateType(rule)
-
-			Object.assign(rule, {
-				label: fieldValue.label || `["${fieldKey}"]`
-			})
-
-			if (RuleValidatorHelper[vt]) {
-				result = RuleValidatorHelper[vt](rule, value, message)
-				if (result != null) {
-					break
-				}
-			}
-
-			if (rule.validateExpr) {
-				let now = Date.now()
-				let resultExpr = rule.validateExpr(value, allData, now)
-				if (resultExpr === false) {
-					result = this._getMessage(rule, rule.errorMessage || this._message['default'])
-					break
-				}
-			}
-
-			if (rule.validateFunction) {
-				result = await this.validateFunction(rule, value, data, allData, vt)
-				if (result !== null) {
-					break
-				}
-			}
-		}
-
-		if (result !== null) {
-			result = message.TAG + result
-		}
-
-		return result
-	}
-
-	async validateFunction(rule, value, data, allData, vt) {
-		let result = null
-		try {
-			let callbackMessage = null
-			const res = await rule.validateFunction(rule, value, allData || data, (message) => {
-				callbackMessage = message
-			})
-			if (callbackMessage || (typeof res === 'string' && res) || res === false) {
-				result = this._getMessage(rule, callbackMessage || res, vt)
-			}
-		} catch (e) {
-			result = this._getMessage(rule, e.message, vt)
-		}
-		return result
-	}
-
-	_getMessage(rule, message, vt) {
-		return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default'])
-	}
-
-	_getValidateType(rule) {
-		var result = ''
-		if (rule.required) {
-			result = 'required'
-		} else if (rule.format) {
-			result = 'format'
-		} else if (rule.arrayType) {
-			result = 'arrayTypeFormat'
-		} else if (rule.range) {
-			result = 'range'
-		} else if (rule.maximum !== undefined || rule.minimum !== undefined) {
-			result = 'rangeNumber'
-		} else if (rule.maxLength !== undefined || rule.minLength !== undefined) {
-			result = 'rangeLength'
-		} else if (rule.pattern) {
-			result = 'pattern'
-		} else if (rule.validateFunction) {
-			result = 'validateFunction'
-		}
-		return result
-	}
-}
-
-const RuleValidatorHelper = {
-	required(rule, value, message) {
-		if (rule.required && isEmptyValue(value, rule.format || typeof value)) {
-			return formatMessage(rule, rule.errorMessage || message.required);
-		}
-
-		return null
-	},
-
-	range(rule, value, message) {
-		const {
-			range,
-			errorMessage
-		} = rule;
-
-		let list = new Array(range.length);
-		for (let i = 0; i < range.length; i++) {
-			const item = range[i];
-			if (types.object(item) && item.value !== undefined) {
-				list[i] = item.value;
-			} else {
-				list[i] = item;
-			}
-		}
-
-		let result = false
-		if (Array.isArray(value)) {
-			result = (new Set(value.concat(list)).size === list.length);
-		} else {
-			if (list.indexOf(value) > -1) {
-				result = true;
-			}
-		}
-
-		if (!result) {
-			return formatMessage(rule, errorMessage || message['enum']);
-		}
-
-		return null
-	},
-
-	rangeNumber(rule, value, message) {
-		if (!types.number(value)) {
-			return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
-		}
-
-		let {
-			minimum,
-			maximum,
-			exclusiveMinimum,
-			exclusiveMaximum
-		} = rule;
-		let min = exclusiveMinimum ? value <= minimum : value < minimum;
-		let max = exclusiveMaximum ? value >= maximum : value > maximum;
-
-		if (minimum !== undefined && min) {
-			return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMinimum ?
-				'exclusiveMinimum' : 'minimum'
-			])
-		} else if (maximum !== undefined && max) {
-			return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMaximum ?
-				'exclusiveMaximum' : 'maximum'
-			])
-		} else if (minimum !== undefined && maximum !== undefined && (min || max)) {
-			return formatMessage(rule, rule.errorMessage || message['number'].range)
-		}
-
-		return null
-	},
-
-	rangeLength(rule, value, message) {
-		if (!types.string(value) && !types.array(value)) {
-			return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
-		}
-
-		let min = rule.minLength;
-		let max = rule.maxLength;
-		let val = value.length;
-
-		if (min !== undefined && val < min) {
-			return formatMessage(rule, rule.errorMessage || message['length'].minLength)
-		} else if (max !== undefined && val > max) {
-			return formatMessage(rule, rule.errorMessage || message['length'].maxLength)
-		} else if (min !== undefined && max !== undefined && (val < min || val > max)) {
-			return formatMessage(rule, rule.errorMessage || message['length'].range)
-		}
-
-		return null
-	},
-
-	pattern(rule, value, message) {
-		if (!types['pattern'](rule.pattern, value)) {
-			return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
-		}
-
-		return null
-	},
-
-	format(rule, value, message) {
-		var customTypes = Object.keys(types);
-		var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : (rule.format || rule.arrayType);
-
-		if (customTypes.indexOf(format) > -1) {
-			if (!types[format](value)) {
-				return formatMessage(rule, rule.errorMessage || message.typeError);
-			}
-		}
-
-		return null
-	},
-
-	arrayTypeFormat(rule, value, message) {
-		if (!Array.isArray(value)) {
-			return formatMessage(rule, rule.errorMessage || message.typeError);
-		}
-
-		for (let i = 0; i < value.length; i++) {
-			const element = value[i];
-			let formatResult = this.format(rule, element, message)
-			if (formatResult !== null) {
-				return formatResult
-			}
-		}
-
-		return null
-	}
-}
-
-class SchemaValidator extends RuleValidator {
-
-	constructor(schema, options) {
-		super(SchemaValidator.message);
-
-		this._schema = schema
-		this._options = options || null
-	}
-
-	updateSchema(schema) {
-		this._schema = schema
-	}
-
-	async validate(data, allData) {
-		let result = this._checkFieldInSchema(data)
-		if (!result) {
-			result = await this.invokeValidate(data, false, allData)
-		}
-		return result.length ? result[0] : null
-	}
-
-	async validateAll(data, allData) {
-		let result = this._checkFieldInSchema(data)
-		if (!result) {
-			result = await this.invokeValidate(data, true, allData)
-		}
-		return result
-	}
-
-	async validateUpdate(data, allData) {
-		let result = this._checkFieldInSchema(data)
-		if (!result) {
-			result = await this.invokeValidateUpdate(data, false, allData)
-		}
-		return result.length ? result[0] : null
-	}
-
-	async invokeValidate(data, all, allData) {
-		let result = []
-		let schema = this._schema
-		for (let key in schema) {
-			let value = schema[key]
-			let errorMessage = await this.validateRule(key, value, data[key], data, allData)
-			if (errorMessage != null) {
-				result.push({
-					key,
-					errorMessage
-				})
-				if (!all) break
-			}
-		}
-		return result
-	}
-
-	async invokeValidateUpdate(data, all, allData) {
-		let result = []
-		for (let key in data) {
-			let errorMessage = await this.validateRule(key, this._schema[key], data[key], data, allData)
-			if (errorMessage != null) {
-				result.push({
-					key,
-					errorMessage
-				})
-				if (!all) break
-			}
-		}
-		return result
-	}
-
-	_checkFieldInSchema(data) {
-		var keys = Object.keys(data)
-		var keys2 = Object.keys(this._schema)
-		if (new Set(keys.concat(keys2)).size === keys2.length) {
-			return ''
-		}
-
-		var noExistFields = keys.filter((key) => {
-			return keys2.indexOf(key) < 0;
-		})
-		var errorMessage = formatMessage({
-			field: JSON.stringify(noExistFields)
-		}, SchemaValidator.message.TAG + SchemaValidator.message['defaultInvalid'])
-		return [{
-			key: 'invalid',
-			errorMessage
-		}]
-	}
-}
-
-function Message() {
-	return {
-		TAG: "",
-		default: '验证错误',
-		defaultInvalid: '提交的字段{field}在数据库中并不存在',
-		validateFunction: '验证无效',
-		required: '{label}必填',
-		'enum': '{label}超出范围',
-		timestamp: '{label}格式无效',
-		whitespace: '{label}不能为空',
-		typeError: '{label}类型无效',
-		date: {
-			format: '{label}日期{value}格式无效',
-			parse: '{label}日期无法解析,{value}无效',
-			invalid: '{label}日期{value}无效'
-		},
-		length: {
-			minLength: '{label}长度不能少于{minLength}',
-			maxLength: '{label}长度不能超过{maxLength}',
-			range: '{label}必须介于{minLength}和{maxLength}之间'
-		},
-		number: {
-			minimum: '{label}不能小于{minimum}',
-			maximum: '{label}不能大于{maximum}',
-			exclusiveMinimum: '{label}不能小于等于{minimum}',
-			exclusiveMaximum: '{label}不能大于等于{maximum}',
-			range: '{label}必须介于{minimum}and{maximum}之间'
-		},
-		pattern: {
-			mismatch: '{label}格式不匹配'
-		}
-	};
-}
-
-
-SchemaValidator.message = new Message();
-
-export default SchemaValidator

+ 0 - 89
components/uni-forms/package.json

@@ -1,89 +0,0 @@
-{
-  "id": "uni-forms",
-  "displayName": "uni-forms 表单",
-  "version": "1.4.13",
-  "description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据",
-  "keywords": [
-    "uni-ui",
-    "表单",
-    "校验",
-    "表单校验",
-    "表单验证"
-],
-  "repository": "https://github.com/dcloudio/uni-ui",
-  "engines": {
-    "HBuilderX": ""
-  },
-  "directories": {
-    "example": "../../temps/example_temps"
-  },
-"dcloudext": {
-    "sale": {
-      "regular": {
-        "price": "0.00"
-      },
-      "sourcecode": {
-        "price": "0.00"
-      }
-    },
-    "contact": {
-      "qq": ""
-    },
-    "declaration": {
-      "ads": "无",
-      "data": "无",
-      "permissions": "无"
-    },
-    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
-    "type": "component-vue"
-  },
-  "uni_modules": {
-    "dependencies": [
-			"uni-scss",
-      "uni-icons"
-    ],
-    "encrypt": [],
-    "platforms": {
-      "cloud": {
-        "tcb": "y",
-        "aliyun": "y",
-        "alipay": "n"
-      },
-      "client": {
-        "App": {
-          "app-vue": "y",
-          "app-nvue": "y"
-        },
-        "H5-mobile": {
-          "Safari": "y",
-          "Android Browser": "y",
-          "微信浏览器(Android)": "y",
-          "QQ浏览器(Android)": "y"
-        },
-        "H5-pc": {
-          "Chrome": "y",
-          "IE": "y",
-          "Edge": "y",
-          "Firefox": "y",
-          "Safari": "y"
-        },
-        "小程序": {
-          "微信": "y",
-          "阿里": "y",
-          "百度": "y",
-          "字节跳动": "y",
-        "QQ": "y",
-        "京东": "u"
-        },
-        "快应用": {
-          "华为": "u",
-          "联盟": "u"
-        },
-        "Vue": {
-            "vue2": "y",
-            "vue3": "y"
-        }
-      }
-    }
-  }
-}

+ 0 - 23
components/uni-forms/readme.md

@@ -1,23 +0,0 @@
-
-
-## Forms 表单
-
-> **组件名:uni-forms**
-> 代码块: `uForms`、`uni-forms-item`
-> 关联组件:`uni-forms-item`、`uni-easyinput`、`uni-data-checkbox`、`uni-group`。
-
-
-uni-app的内置组件已经有了 `<form>`组件,用于提交表单内容。
-
-然而几乎每个表单都需要做表单验证,为了方便做表单验证,减少重复开发,`uni ui` 又基于 `<form>`组件封装了 `<uni-forms>`组件,内置了表单验证功能。
-
-`<uni-forms>` 提供了 `rules`属性来描述校验规则、`<uni-forms-item>`子组件来包裹具体的表单项,以及给原生或三方组件提供了 `binddata()` 来设置表单值。
-
-每个要校验的表单项,不管input还是checkbox,都必须放在`<uni-forms-item>`组件中,且一个`<uni-forms-item>`组件只能放置一个表单项。
-
-`<uni-forms-item>`组件内部预留了显示error message的区域,默认是在表单项的底部。
-
-另外,`<uni-forms>`组件下面的各个表单项,可以通过`<uni-group>`包裹为不同的分组。同一`<uni-group>`下的不同表单项目将聚拢在一起,同其他group保持垂直间距。`<uni-group>`仅影响视觉效果。
-
-### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-forms)
-#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 30 - 43
main.js

@@ -1,95 +1,82 @@
 import Vue from 'vue'
 import uView from "@/uni_modules/uview-ui";
-Vue.use(uView);
 import App from './App'
 import store from './store'
-import MinCache from'./common/util/MinCache.js'
-import tip from'./common/util/tip.js'
-import configService from'./common/service/config.service.js'
-
+import MinCache from './common/util/MinCache.js'
+import tip from './common/util/tip.js'
+import configService from './common/service/config.service.js'
+// router实际被RouterMount文件使用
 import router from './common/router'
-import {RouterMount} from './plugin/uni-simple-router/index.js'
-
-import { throttle } from'./common/util/throttle.js'
-//节流组件
+import { RouterMount } from './plugin/uni-simple-router/index.js'
+// 节流组件
+import { throttle } from './common/util/throttle.js'
 Vue.directive('throttle', throttle);
-//引入mescroll插件
+// 引入mescroll插件
 import MescrollBody from "@/components/mescroll-uni/mescroll-body.vue"
 import MescrollUni from "@/components/mescroll-uni/mescroll-uni.vue"
 Vue.component('mescroll-body', MescrollBody);
 Vue.component('mescroll-uni', MescrollUni);
 
-// 注册缓存器
-Vue.use(MinCache,{timeout: 6})
+// 注册
+Vue.use(uView);
+Vue.use(MinCache, { timeout: 6 });
 
 // store
-Vue.prototype.$store=store;
+Vue.prototype.$store = store;
 // tip
-Vue.prototype.$tip=tip;
+Vue.prototype.$tip = tip;
 // config
-Vue.prototype.$config=configService;
+Vue.prototype.$config = configService;
 
 // request请求
-import { http } from '@/common/service/service.js' 
+import { http } from '@/common/service/service.js'
 Vue.prototype.$http = http
 
 import home from './pages/home/home.vue'
-Vue.component('home',home)
-
+Vue.component('home', home)
 
 import people from './pages/user/people.vue'
-Vue.component('people',people)
+Vue.component('people', people)
 
 // 自定义组件
 import mySelect from './components/my-componets/my-select.vue'
-Vue.component('mySelect',mySelect)
+Vue.component('mySelect', mySelect)
 
 import myImageUpload from './components/my-componets/my-image-upload.vue'
-Vue.component('myImageUpload',myImageUpload)
+Vue.component('myImageUpload', myImageUpload)
 
 
 import myPage from './components/my-componets/my-page.vue'
-Vue.component('myPage',myPage)
-
-
+Vue.component('myPage', myPage)
 
 import basics from './pages/basics/home.vue'
-Vue.component('basics',basics)
+Vue.component('basics', basics)
 
 import components from './pages/component/home.vue'
-Vue.component('components',components)
+Vue.component('components', components)
 
 import plugin from './pages/plugin/home.vue'
-Vue.component('plugin',plugin)
+Vue.component('plugin', plugin)
 
 import cuCustom from './plugin/colorui/components/cu-custom.vue'
-Vue.component('cu-custom',cuCustom)
+Vue.component('cu-custom', cuCustom)
 
 // import VConsole from './js_sdk/vconsole.min'
-
-//   var vConsole = new VConsole();
+// var vConsole = new VConsole();
 
 Vue.config.productionTip = false
-
 App.mpType = 'app'
 
 const app = new Vue({
 	store,
 	MinCache,
-    ...App
+	...App
 })
-//v1.3.5起 H5端 你应该去除原有的app.$mount();使用路由自带的渲染方式
+// v1.3.5起 H5端 你应该去除原有的app.$mount();使用路由自带的渲染方式
 // #ifdef H5
-	RouterMount(app,'#app');
+RouterMount(app, '#app');
 // #endif
 
 // #ifndef H5
-	app.$mount(); //为了兼容小程序及app端必须这样写才有效果
-// #endif
-
-
-
- 
-
-
-
+app.$mount(); //为了兼容小程序及app端必须这样写才有效果
+// #endif

+ 8 - 0
pages.json

@@ -422,6 +422,10 @@
 			"path": "pages/groupMeal/orders/order-details",
 			"style": {}
 		},
+		{
+			"path": "pages/groupMeal/orders/refund",
+			"style": {}
+		},
 		{
 			"path": "pages/groupMeal/users/index",
 			"style": {}
@@ -441,6 +445,10 @@
 		{
 			"path": "pages/groupMeal/users/bankCard-edit",
 			"style": {}
+		},
+		{
+			"path": "pages/groupMeal/users/team-member",
+			"style": {}
 		}
 	],
 	"globalStyle": {

+ 7 - 4
pages/financial/balanceBill.vue

@@ -432,13 +432,16 @@ export default {
 .radio-item {
     width: 31%;
     height: 86rpx;
-    line-height: 86rpx;
+    font-size: 28rpx;
+    color: #333;
+    line-height: 1.2;
     text-align: center;
     // padding: 16rpx 30rpx;
-    background-color: #f5f7fa;
     border-radius: 10rpx;
-    font-size: 28rpx;
-    color: #333;
+    background-color: #f5f7fa;
+    display: flex;
+    align-items: center;
+    justify-content: center;
 
     &.active {
         color: #2983EC;

+ 10 - 2
pages/financial/management.vue

@@ -49,7 +49,10 @@
                         <text class="asset-value balance1">{{ userInfo.cashTotal }}</text>元
                     </view>
                 </view>
-                <view class="action-btn recharge" @click="getRecharge ()">充值</view>
+                <view class="action-group">
+                    <view class="action-btn recharge" @click="onClick(`/pages/groupMeal/users/withdrawal`)">提现</view>
+                    <view class="action-btn recharge" @click="getRecharge">充值</view>
+                </view>
             </view>
 
             <!-- 积分卡片 -->
@@ -129,7 +132,12 @@ export default {
                 url: `/pages/financial/buyBean?index=`+type
             })
         },
-     
+        onClick(e) {
+			if (!e) return;
+			uni.navigateTo({
+				url: e
+			});
+		},
     }
 }
 </script>

+ 8 - 0
pages/groupMeal/goods/form-step1.vue

@@ -22,6 +22,8 @@
 						<view class="upload-tip">支持jpg、png格式,建议尺寸为300px*300px,上传1-4张</view>
 						<u-upload
 							name="cover"
+							width="140"
+							height="140"
 							multiple
 							:maxCount="4"
 							:fileList="fileList.cover"
@@ -37,6 +39,8 @@
 						<view class="upload-tip">支持jpg、png格式,建议尺寸为300px*300px,最多20张</view>
 						<u-upload
 							name="detail"
+							width="140"
+							height="140"
 							multiple
 							:maxCount="20"
 							:fileList="fileList.detail"
@@ -197,6 +201,10 @@ $uni-color-primary: #2979ff;
 			color: #999999;
 			margin-bottom: 20rpx;
 		}
+
+		::v-deep .u-add-tips {
+			margin-top: 10rpx;
+		}
 	}
 }
 

+ 28 - 0
pages/groupMeal/goods/list.vue

@@ -105,11 +105,24 @@
 				</template>
 			</view>
 		</view>
+
+		<Tabbar />
+		<Modal ref="myModal"
+			:title="modalText.title" 
+			:content="modalText.content" 
+			:showCancelButton="false"
+		/>
 	</view>
 </template>
 
 <script>
+import Modal from '@/components/modal/index.vue';
+import Tabbar from '@/pages/groupMeal/tabbar/index.vue';
 export default {
+	components: {
+		Modal,
+		Tabbar
+	},
 	data() {
 		return {
 			isManaging: false, // 是否处于批量管理模式
@@ -134,6 +147,16 @@ export default {
 			scrollIntoViewId: '', // 滚动到指定视图的 ID
 			categoryOffsetTops: [], // 每个分类区域到 scroll-view 顶部的距离
 			isScrolling: false, // 标记是否正在进行点击滚动
+			// 弹窗
+			modalText: {
+				title: '注册成功',
+				btntext: '去下载',
+				// 很抱歉,您没有通过平台审核,如有疑问请联系平台客服。
+				// 是否将所选商品上架?
+				// 所选商品有未通过审核商品无法批量操作上架
+				// 是否将所选商品删除?删除后需重新添加品牌标配
+				content: '报名成功,请等待平台审核'
+			},
 		};
 	},
 	computed: {
@@ -160,6 +183,9 @@ export default {
 			return grouped;
 		}
 	},
+	mounted() {
+		// this.$refs.myModal.onOpen();
+	},
 	methods: {
 		addGoods() {
 			uni.navigateTo({
@@ -434,6 +460,8 @@ export default {
 	}
 }
 .footer-bar {
+	bottom: 50px;
+	padding-bottom: 20px;
 	.action-buttons {
 		display: flex;
 		gap: 20rpx;

+ 21 - 0
pages/groupMeal/localDict.js

@@ -0,0 +1,21 @@
+export const dictData = {
+    BANK_COLORDATA: [
+        {'工商银行': '#C7000A'},
+        {'交通银行': '#00377A'},
+        {'招商银行': '#A30030'},
+        {'民生银行': '#0072BC'},
+        {'中信银行': '#D70010'},
+        {'浦发银行': '#000073'},
+        {'兴业银行': '#003F97'},
+        {'光大银行': '#6A1685'},
+        {'广发银行': '#E60021'},
+        {'平安银行': '#F15A25'},
+        {'北京银行': '#CB030D'},
+        {'华夏银行': '#DB0D17'},
+        {'农业银行': '#319C8B'},
+        {'建设银行': '#0066B3'},
+        {'邮政银行': '#02724A'},
+        {'中国银行': '#A71E32'},
+        {'宁波银行': '#EF8F38'},
+    ],
+}

+ 9 - 8
pages/groupMeal/orders/order-alist.vue

@@ -67,13 +67,16 @@
 			</view>
 		</view>
 
-		<!-- 操作成功提示 -->
-		<u-toast ref="uToast"></u-toast>
+		<Tabbar />
 	</view>
 </template>
 
 <script>
+import Tabbar from '@/pages/groupMeal/tabbar/index.vue';
 export default {
+	components: {
+		Tabbar
+	},
 	data() {
 		return {
 			isManaging: false,
@@ -123,15 +126,11 @@ export default {
 		},
 		handleBatchAction() {
 			if (this.selectedOrders.length === 0) {
-				this.$refs.uToast.show({ type: 'warning', message: '请先选择订单' });
+				this.$tip.toast("请先选择订单")
 				return;
 			}
 			console.log('批量出餐的订单ID:', this.selectedOrders);
-			this.$refs.uToast.show({
-				type: 'success',
-				message: '操作成功',
-				iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
-			});
+			this.$tip.success("操作成功")
 		}
 	}
 };
@@ -218,6 +217,8 @@ export default {
 }
 
 .footer-bar {
+	bottom: 50px;
+	padding-bottom: 20px;
 	.action-buttons {
 		display: flex;
 		gap: 20rpx;

+ 417 - 395
pages/groupMeal/orders/order-details.vue

@@ -1,21 +1,14 @@
 <template>
-	<view class="check">
-		<view class="top">
-		</view>
-		<view class="head">
-			<span class="cuIcon-back" @click="back"></span>
-			<view class="case">
-				订单详情
-			</view>
-		</view>
+	<view class="page-container">
+		<u-navbar title="订单详情" bgColor="transparent" :autoBack="true" :placeholder="true"
+			:border-bottom="true"></u-navbar>
 		<view class="content">
 			<view class="status">
 				<view class="status_title">
-					{{product.state}} <span v-if="product.differenceMinutes>0">,剩余</span> 
-					<u-count-down :timestamp="product.differenceMinutes*60" :show-days="false" font-size="36rpx" @end="getDetail"
-						v-if="product.differenceMinutes>0 && product.state == '待支付'"></u-count-down>
-
-					<!-- <span>¥{{product.costPrice}}</span> -->
+					{{ product.state }} <text v-if="product.differenceMinutes > 0">, 剩余</text>
+					<u-count-down :show-days="false" font-size="36rpx" :timestamp="product.differenceMinutes * 60"
+						v-if="product.differenceMinutes > 0 && product.state == '待支付'" @end="getDetail"></u-count-down>
+					<!-- <text>¥{{product.costPrice}}</text> -->
 				</view>
 				<view class="span" v-if="product.state == '待支付'">
 					订单已取消
@@ -30,10 +23,10 @@
 					该订单已失效
 				</view>
 			</view>
-			<view class="refund" @click="cutPopup" v-if="product.refundType == 1">
+			<view class="refund" @click="onPopupOpen" v-if="product.refundType == 1">
 				退款去向详情
 			</view>
-			<view class="product" v-if="product.categoryId != 1945013773786701826">
+			<view class="product" v-if="product.categoryId != categoryId">
 				<view class="title">
 					商品信息
 				</view>
@@ -41,107 +34,136 @@
 					<view class="img">
 						<image :src="product.productImage" mode=""></image>
 					</view>
-					<view class="name">
-						{{product.productName}}
+					<view class="box">
+						<view class="name">{{ product.productName }}</view>
 						<view class="price">
-							¥{{product.costPrice}}/份
-							<span>实付款:¥ {{product.orderPrice}}</span>
+							<text class="p">¥<text class="v">{{ product.costPrice }}</text>/份</text>
+							<text class="r">实付款:<text class="p">¥<text class="v">{{ product.orderPrice
+										}}</text></text></text>
 						</view>
 					</view>
 				</view>
 			</view>
-			<view class="product" v-if="product.categoryId == 1945013773786701826">
-				<view class="title" v-if="product.categoryId != 1945013773786701826">
+			<view class="product" v-if="product.categoryId == categoryId">
+				<view class="title" v-if="product.categoryId != categoryId">
 					商品信息
 				</view>
-				<view class="center"
-					v-for="(specitem, specIndex) in product.productsLinkCategorySpecItems.slice(0,isShow ? product.productsLinkCategorySpecItems.length : 2)"
-					:key="specIndex">
-					<view class="img">
-						<image :src="product.productImage" mode=""></image>
-					</view>
-					<view class="spec_item">
-						<view class="top">
-							{{product.productName}}
-						</view>
-						<view class="spec_content">
-							<view class="left">
-								<view class="cventer">
-									{{specitem.partName}} {{specitem.positionName}}
+
+				<ListExpand :items="product.productsLinkCategorySpecItems">
+					<template v-slot:="{ items }">
+						<view class="repair-list">
+							<view class="repair-item" v-for="(eitem, i) in items" :key="i">
+								<u-image :src="product.productImage" width="112rpx" height="112rpx"
+									border-radius="6rpx"></u-image>
+								<view class="repair-details">
+									<text class="repair-name one-line-text">{{ product.productName }}</text>
+									<text class="repair-type">{{ eitem.partName }} {{ eitem.positionName }}</text>
+									<text class="repair-type">{{ eitem.craftName }}</text>
 								</view>
-								<view class="foot">
-									{{specitem.craftName}}
+								<view class="repair-price">
+									<text class="final-price">¥{{ eitem.soldPrice }}</text>
+									<text class="original-price">¥{{ eitem.partPrice }}</text>
 								</view>
 							</view>
-							<view class="right">
-								<span style="font-size: 22rpx;color: #FD4912;">¥{{specitem.soldPrice}}</span>
-								<span style="text-decoration: line-through;font-size: 18rpx;color: #999999;">¥{{specitem.price}}</span>
-							</view>
 						</view>
-					</view>
-				</view>
-				<view class="is_show" @click.stop="unfold" v-if="product.productsLinkCategorySpecItems.length > 2">
-					{{isShow?'收起查看':'展开查看'}}
-					<image src="/static/order/hidden.png" mode="" v-if="isShow"></image>
-					<image src="/static/order/show.png" mode="" v-else></image>
-				</view>
-				<view class="all_price" v-if="product.categoryId == 1945013773786701826">
-					<span style="font-size: 22rpx;color: #FD4912;margin-right: 10rpx;">¥已优惠{{product.couponPrice}}</span>
-					<span style="font-size: 26rpx;color: #FD4912;"><text
-							style="font-size: 22rpx;">¥</text>{{product.orderPrice}}</span>
+					</template>
+				</ListExpand>
+
+				<view class="finnal-price" v-if="product.categoryId == categoryId">
+					<span style="font-size: 22rpx;color: #FD4912;margin-right: 10rpx;">已优惠{{ product.couponPrice
+						}}</span>
+					<span style="font-size: 26rpx;color: #FD4912;">
+						<text style="font-size: 22rpx;">¥</text>{{ product.orderPrice }}
+					</span>
 				</view>
 			</view>
 			<view class="product">
 				<view class="title negotiate" v-if="!product.auditType">
-					协商历史
-					<view class="look" @click="goRecord">
+					<text>协商历史</text>
+					<view class="btn" @click="goRecord">
 						查看详情
 					</view>
 				</view>
-				<view class="title">
-					订单信息
-				</view>
+
+				<view class="title">订单信息</view>
 				<view class="data">
-					<span>订单号:</span>
-					{{product.orderId?product.orderId:'--'}}
+					<text>订单号:</text>
+					{{ product.orderId ? product.orderId : '--' }}
 				</view>
 				<view class="data">
-					<span>支付流水号:</span>
-					{{product.tradeId?product.tradeId:'--'}}
+					<text>支付流水号:</text>
+					{{ product.tradeId ? product.tradeId : '--' }}
 				</view>
 				<view class="data">
-					<span>提交人:</span>
-					{{product.linkName?product.linkName:'--'}}
+					<text>提交人:</text>
+					{{ product.linkName ? product.linkName : '--' }}
 				</view>
 				<view class="data">
-					<span>联系电话:</span>
-					{{product.phone?product.phone:'--'}}
+					<text>联系电话:</text>
+					{{ product.phone ? product.phone : '--' }}
 				</view>
 				<view class="data">
-					<span>下单时间:</span>
-					{{product.buyTime?product.buyTime:'--'}}
+					<text>下单时间:</text>
+					{{ product.buyTime ? product.buyTime : '--' }}
 				</view>
 				<view class="data">
-					<span>付款时间:</span>
-					{{product.payTime?product.payTime:'--'}}
+					<text>付款时间:</text>
+					{{ product.payTime ? product.payTime : '--' }}
 				</view>
 				<view class="data">
-					<span>使用时间:</span>
-					{{product.useTime?product.useTime:'--'}}
+					<text>使用时间:</text>
+					{{ product.useTime ? product.useTime : '--' }}
 				</view>
 			</view>
 		</view>
-		<view class="popup" v-if="isDetail">
+
+		<u-popup mode="bottom" :border-radius="20"
+			:safe-area-inset-bottom="true"
+			v-model="isShow" @close="onPopupClose"
+		>
+			<view class="popup-container">
+				<view class="popup-header">
+					<text>退款去向详情</text>
+					<image src="/static/store/detele.png" @click="isShow = false" />
+				</view>
+				<view class="popup-content">
+					<view class="one-box">
+						<view class="amount">
+							<view>实退金额</view>
+							<view class="val">
+								<text class="unit">¥</text>228.3
+							</view>
+						</view>
+						<view class="text">
+							退款已成功到账
+						</view>
+					</view>
+					<view class="two-box">
+						<view class="refund">
+							<text>退回到银行卡</text>
+							<text class="val">¥228.3</text>
+						</view>
+						<view class="desc">
+							退回(建设银行借记卡8009),退款单号为12523726342632478326483247382
+						</view>
+						<view class="time">
+							2025/12/30 12:20:47
+						</view>
+					</view>
+				</view>
+			</view>
+		</u-popup>
+		<!-- <view class="popup" v-if="isShow">
 			<view class="content">
 				<view class="title">
-					<span>退款去向详情</span>
-					<image src="/static/index/cut.png" alt="" @click="cutPopup" />
+					<text>退款去向详情</text>
+					<image src="/static/index/cut.png" alt="" @click="onPopupOpen" />
 				</view>
 				<view class="detail">
 					<view class="amount">
 						实退金额
 						<view class="money">
-							<span>¥</span>228.3
+							<text>¥</text>228.3
 						</view>
 					</view>
 					<view class="text">
@@ -149,7 +171,7 @@
 					</view>
 					<view class="fund">
 						实退金额
-						<span>¥228.3</span>
+						<text>¥228.3</text>
 					</view>
 					<view class="card">
 						退回(建设银行借记卡8009),退款单号为12523726342632478326483247382
@@ -159,393 +181,393 @@
 					</view>
 				</view>
 			</view>
-		</view>
+		</view> -->
 	</view>
 </template>
 
 <script>
-	export default {
-		data() {
-			return {
-				orderId: '',
-				product: {},
-				isDetail: false,
-				timestamp: 10000,
-				isShow: false
-			}
-		},
-		methods: {
-			//返回
-			back() {
-				uni.navigateBack({
-					delta: 1
-				});
-			},
-			getDetail() {
-				this.$http.get("/app/order/locaOrder/queryById?orderId=" + this.orderId, ).then(res => {
-					if (res.data.code == 200) {
-						console.log(res)
-						this.product = res.data.result
-					}
-				})
-			},
-			//展开/收起查看钣金喷漆子选项
-			unfold(index) {
-				this.isShow = !this.isShow
-				this.$forceUpdate();
-			},
-			goRecord() {
-				uni.navigateTo({
-					url: '/pages/order/record?orderId=' + this.product.orderId
-				})
-			},
-			cutPopup() {
-				this.isDetail = !this.isDetail
+import ListExpand from '@/components/list-scroll-view/list-expand.vue';
+export default {
+	components: {
+		ListExpand
+	},
+	data() {
+		return {
+			orderId: '',
+			product: {
+				state: '待支付',
+				differenceMinutes: 1000,
+				refundType: 1,
+				productName: '一次普通洗车兑换服务代金券(限7座以下的轿车使用)',
+				costPrice: 101,
+				orderPrice: 100.55,
+				categoryId: 1945013773786701826,
+				productsLinkCategorySpecItems: [{}, {}, {}, {}, {}]
 			},
-			refundDetail() {
-				this.isDetail = true
-			},
-			//获取退款去向
-			getRefund() {
-				this.$http.get("/app/order/locaOrder/refundDestination?reOrderId=" + this.orderNo).then(res => {
-					if (res.data.code == 200) {
-						console.log(res)
-						// this.list = res.data.result
-					}
-				})
-			}
+			categoryId: 1945013773786701826,
+			isShow: false,
+			isExpanded: false
+		}
+	},
+	onLoad(query) {
+		this.orderId = query.orderId
+	},
+	mounted() {
+		this.getDetail()
+	},
+	methods: {
+		getDetail() {
+			this.$http.get("/app/order/locaOrder/queryById?orderId=" + this.orderId).then(res => {
+				if (res.data.code == 200) {
+					this.product = res.data.result
+				}
+			})
+		},
+		// 获取退款去向
+		getRefund() {
+			this.$http.get("/app/order/locaOrder/refundDestination?reOrderId=" + this.orderNo).then(res => {
+				if (res.data.code == 200) {
+					console.log(res)
+					// this.list = res.data.result
+				}
+			})
 		},
-		onLoad(option) {
-			this.orderId = option.orderId
+		// 协商历史
+		goRecord() {
+			uni.navigateTo({
+				url: '/pages/order/record?orderId=' + this.product.orderId
+			})
+		},
+		// popup
+		onPopupOpen() {
+			this.isShow = true;
+		},
+		onPopupClose() {
+			this.isShow = false;
 		},
-		mounted() {
-			this.getDetail()
-		}
 	}
+}
 </script>
 
 <style lang="scss" scoped>
-	.check {
-		width: 100vw;
-		height: 100vh;
-		background: #F7F8FC;
-		display: flex;
-		flex-direction: column;
-		overflow: hidden;
+.page-container {
+	height: 100vh;
+	background:
+		linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #F7F8FC 10%),
+		linear-gradient(90deg, #E6FFFF 0%, #CEF7FF 40%, #A3CEFE 73%, #BCD6FF 100%);
+	display: flex;
+	flex-direction: column;
+
+	.content {
+		flex: 1;
+		padding: 24rpx;
+		overflow-y: auto;
+
+		.status {
+			font-size: 44rpx;
+			color: #333333;
+			padding: 0 20rpx;
+
+			.status_title {
+				font-size: 36rpx;
+				font-weight: 600;
+				display: flex;
+				align-items: end;
+				// justify-content: space-between;
+				margin-bottom: 15rpx;
+			}
 
-		/*#ifdef APP-PLUS*/
-		.top {
-			width: 100%;
-			height: var(--status-bar-height);
-			background: linear-gradient(87deg, #E2F4F8 0%, #A3CDFF 100%), linear-gradient(360deg, #FFFFFF 0%, rgba(255, 255, 255, 0) 100%);
+			.span {
+				font-size: 28rpx;
+				color: #666666;
+			}
 		}
 
-		/*#endif*/
-		.head {
-			width: 100%;
-			height: 112rpx;
-			padding: 20rpx;
+		.refund {
+			height: 76rpx;
+			font-weight: 500;
+			font-size: 32rpx;
+			color: #333333;
+			margin: 24rpx 20rpx;
+			border-radius: 12rpx;
+			border: 1rpx solid #000000;
 			display: flex;
 			align-items: center;
-			background: linear-gradient(87deg, #E2F4F8 0%, #A3CDFF 100%), linear-gradient(360deg, #FFFFFF 0%, rgba(255, 255, 255, 0) 100%);
-			position: relative;
-
-			.cuIcon-back {
-				font-size: 40rpx;
-				margin-right: 40rpx;
-			}
-
-			.case {
-				position: absolute;
-				left: 50%;
-				transform: translateX(-50%);
-				font-size: 36rpx;
-				font-weight: 600;
-			}
+			justify-content: center;
 		}
 
-		.content {
-			padding: 24rpx;
-			flex: 1;
-			overflow-y: auto;
+		.product {
+			width: 100%;
+			margin-top: 24rpx;
+			background: #FFFFFF;
+			box-shadow: 0 2rpx 8rpx 0 rgba(214, 225, 237, 0.1);
+			border-radius: 16rpx;
+			padding: 20rpx;
 
-			.status {
-				font-size: 44rpx;
-				padding: 0px 20rpx;
+			.title {
+				font-weight: 500;
+				font-size: 32rpx;
 				color: #333333;
+				margin-bottom: 16rpx;
+			}
 
-				.status_title {
-					display: flex;
-					align-items: end;
-					// justify-content: space-between;
-					margin-bottom: 15rpx;
-					font-size: 36rpx;
-					font-weight: 600;
-				}
+			.negotiate {
+				margin-bottom: 24rpx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
 
-				.span {
-					font-size: 28rpx;
-					color: #999999;
-					line-height: 33rpx;
-					font-size: 24rpx;
-					color: #333333;
+				.btn {
+					width: 152rpx;
+					height: 50rpx;
 					font-weight: 500;
-
+					font-size: 26rpx;
+					color: #449AFF;
+					background: rgba(68, 154, 255, 0.05);
+					border-radius: 8rpx;
+					border: 1rpx solid #449AFF;
+					display: flex;
+					align-items: center;
+					justify-content: center;
 				}
 			}
 
-			.refund {
-				width: 632rpx;
-				height: 76rpx;
-				border-radius: 12rpx;
-				border: 1px solid #000000;
+			.center {
+				width: 100%;
 				display: flex;
-				align-items: center;
-				justify-content: center;
-				margin: 24rpx auto;
-			}
 
-			.product {
-				width: 100%;
-				margin-top: 24rpx;
-				background: #FFFFFF;
-				box-shadow: 0px 2px 8px 0px rgba(214, 225, 237, 0.1);
-				border-radius: 16px;
-				padding: 20rpx;
-
-				.title {
-					font-size: 32rpx;
-					color: #333333;
+				.img {
+					width: 132rpx;
+					height: 132rpx;
+					margin-right: 16rpx;
+					border-radius: 12rpx;
+					overflow: hidden;
+
+					image {
+						width: 100%;
+						height: 100%;
+						background: #eee;
+					}
 				}
 
-				.negotiate {
+				.box {
+					flex: 1;
 					display: flex;
+					flex-direction: column;
 					justify-content: space-between;
-					align-items: center;
-					margin-bottom: 24rpx;
-
-					.look {
-						width: 152rpx;
-						height: 50rpx;
-						background: rgba(68, 154, 255, 0.05);
-						border-radius: 8rpx;
-						border: 1px solid #449AFF;
-						display: flex;
-						justify-content: center;
-						align-items: center;
-						font-size: 26rpx;
-						color: #449AFF;
-					}
 				}
 
-				.center {
-					width: 100%;
+				.name {
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #333333;
+					display: -webkit-box;
+					-webkit-line-clamp: 2;
+					-webkit-box-orient: vertical;
+					overflow: hidden;
+				}
+
+				.price {
 					display: flex;
-					border-radius: 16rpx;
-					margin-bottom: 20rpx;
-
-					.img {
-						width: 132rpx;
-						height: 132rpx;
-						border-radius: 12rpx;
-						overflow: hidden;
-						margin-right: 16rpx;
-
-						image {
-							width: 132rpx;
-							height: 132rpx;
-						}
-					}
+					align-items: center;
+					justify-content: space-between;
 
-					.name {
-						flex: 1;
-						display: flex;
-						flex-direction: column;
-						justify-content: space-between;
-						font-size: 30rpx;
-						color: #000000;
-						line-height: 35rpx;
-						font-weight: 600;
-
-						.price {
-							font-size: 24rpx;
-							display: flex;
-							align-items: center;
-							justify-content: space-between;
-							color: #FF6A42;
-
-							span {
-								color: #666666;
-							}
-						}
-					}
+					.p {
+						font-weight: 400;
+						font-size: 22rpx;
+						color: #FD4912;
 
-					.spec_item {
-						flex: 1;
-						margin-left: 20rpx;
-						display: flex;
-						flex-direction: column;
-						justify-content: space-between;
-
-						.top {
-							font-size: 26rpx;
-							height: 38rpx;
-							color: #000000;
-							margin-bottom: 6rpx;
+						.v {
+							font-size: 32rpx;
 						}
 					}
 
-					.spec_content {
-						width: 100%;
-						flex: 1;
-						display: flex;
-						justify-content: space-between;
-						padding-top: 15rpx;
-
-						.left {
-							display: flex;
-							flex-direction: column;
-							justify-content: space-between;
-							font-size: 22rpx;
-							color: #333333;
-						}
+					.r {
+						font-weight: 400;
+						font-size: 28rpx;
+						color: #666666;
 
-						.right {
-							text-align: right;
-							display: flex;
-							flex-direction: column;
-							justify-content: space-between;
+						.p {
+							color: #414141;
 						}
 					}
 				}
+			}
 
-				.data {
-					width: 100%;
-					height: 38rpx;
-					display: flex;
-					align-items: center;
-					// justify-content: space-between;
-					margin-top: 20rpx;
-					margin-bottom: 12rpx;
-					font-size: 26rpx;
-					color: #333333;
+			.data {
+				width: 100%;
+				font-weight: 400;
+				font-size: 28rpx;
+				color: #333333;
+				padding: 10rpx 0;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
 
-					span {
-						display: block;
-						width: 156rpx;
-						height: 38rpx;
-						font-size: 26rpx;
-						color: #666666;
-						margin-right: 16rpx;
-					}
+				text {
+					font-weight: 400;
+					font-size: 26rpx;
+					color: #8A91A8;
+					display: block;
+					margin-right: 16rpx;
 				}
 			}
 		}
+	}
 
-		.is_show {
-			display: flex;
-			align-items: center;
-			justify-content: center;
-			font-size: 24rpx;
-			color: #2D88F4;
+	.finnal-price {
+		display: flex;
+		align-items: center;
+		justify-content: end;
+		padding-top: 20rpx;
+		border-top: 1rpx solid #EEEEEE;
+	}
+
+	.popup-container {
+		.popup-header {
+			font-weight: 500;
+			font-size: 32rpx;
+			color: #333333;
+			padding: 20rpx 24rpx;
+			text-align: center;
+			position: relative;
+			border-bottom: 1rpx solid #EEEEEE;
 
 			image {
-				width: 20rpx;
-				height: 20rpx;
-				margin-left: 10rpx;
+				width: 40rpx;
+				height: 40rpx;
+				position: absolute;
+				right: 24rpx;
 			}
 		}
 
-		.all_price {
-			display: flex;
-			align-items: center;
-			justify-content: end;
-			padding-top: 20rpx;
-			border-top: 1px solid #EEEEEE;
-			margin-top: 20rpx;
-		}
-
-		.popup {
-			width: 100vw;
-			height: 100vh;
-			position: fixed;
-			top: 0;
-			left: 0;
-			background: rgba(0, 0, 0, 0.4);
+		.popup-content {
+			margin: 24rpx;
+			padding: 20rpx;
+			border-radius: 12rpx;
+			background-color: #F7F8FC;
 
-			.content {
-				width: 100%;
-				background: #FFFFFF;
-				border-radius: 20rpx 20rpx 0rpx 0px;
-				padding: 20rpx 24rpx;
+			.one-box {
 				padding-bottom: 16rpx;
-				position: absolute;
-				bottom: 0;
-				left: 0;
-
-				.title {
+				border-bottom: 1rpx solid #EEEEEE;
+				.amount {
+					font-weight: 500;
+					font-size: 30rpx;
+					color: #333333;
 					display: flex;
 					align-items: center;
-					justify-content: center;
-					position: relative;
-					border-bottom: 1px solid #EEEEEE;
-					padding-bottom: 20rpx;
-					font-weight: 600;
+					justify-content: space-between;
 
-					image {
-						width: 37rpx;
-						height: 37rpx;
-						position: absolute;
-						right: 0;
-					}
-				}
+					.val {
+						font-weight: 500;
+						font-size: 32rpx;
+						color: #FD4912;
 
-				.detail {
-					padding: 20rpx;
-					border-radius: 12rpx;
-					background-color: #F7F8FC;
-					margin-top: 24rpx;
-
-					.amount {
-						display: flex;
-						align-items: center;
-						justify-content: space-between;
-						font-weight: 600;
-
-						.money {
-							font-size: 28rpx;
-							color: #FD4912;
-
-							span {
-								font-size: 16rpx
-							}
+						.unit {
+							font-weight: 400;
+							font-size: 22rpx;
+							margin-right: 4rpx;
 						}
 					}
+				}
 
-					.text {
-						font-size: 26rpx;
-						color: #666666;
-						margin-top: 12rpx;
-						border-bottom: 1px solid #EEEEEE;
-						padding-bottom: 16rpx;
-					}
+				.text {
+					font-weight: 400;
+					font-size: 26rpx;
+					color: #666666;
+					margin-top: 12rpx;
+				}
+			}
 
-					.fund {
-						font-size: 28rpx;
-						color: #333333;
-						display: flex;
-						align-items: center;
-						justify-content: space-between;
-						margin-top: 16rpx;
-					}
+			.two-box {
+				.refund {
+					font-weight: 400;
+					font-size: 28rpx;
+					color: #333333;
+					margin-top: 16rpx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
 
-					.card {
-						font-size: 26rpx;
-						color: #666666;
-						margin-top: 12rpx;
+					.val {
+						font-size: 32rpx;
 					}
 				}
+
+				.desc {
+					font-weight: 400;
+					font-size: 26rpx;
+					color: #666666;
+					margin-top: 12rpx;
+				}
+
+				.time {
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #999999;
+					margin-top: 12rpx;
+				}
+			}
+		}
+	}
+}
+
+.repair-list {
+	padding: 20rpx 0;
+
+	.repair-item {
+		display: flex;
+		align-items: center;
+		margin-bottom: 20rpx;
+
+		&:last-child {
+			margin-bottom: 0;
+		}
+
+		.repair-details {
+			flex: 1;
+			margin: 0 20rpx 0 40rpx;
+
+			.repair-name,
+			.repair-type {
+				display: block;
+			}
+
+			.repair-name {
+				font-weight: 400;
+				font-size: 26rpx;
+				color: #000000;
+			}
+
+			.repair-type {
+				font-weight: 400;
+				font-size: 22rpx;
+				color: #666666;
+				margin-top: 6rpx;
+			}
+		}
+
+		.repair-price {
+			text-align: right;
+
+			.final-price,
+			.original-price {
+				display: block;
+			}
+
+			.final-price {
+				font-weight: 500;
+				font-size: 28rpx;
+				color: #fd2b54;
+			}
+
+			.original-price {
+				font-weight: 400;
+				font-size: 18rpx;
+				color: #999999;
+				text-decoration: line-through;
 			}
 		}
 	}
+}
 </style>

+ 119 - 149
pages/groupMeal/orders/refund.vue

@@ -1,13 +1,6 @@
 <template>
 	<view class="record">
-		<view class="top">
-		</view>
-		<view class="head">
-			<span class="cuIcon-back" @click="back"></span>
-			<view class="case">
-				协商记录
-			</view>
-		</view>
+		<u-navbar title="协商记录" :autoBack="true" :placeholder="true" :border-bottom="true"></u-navbar>
 		<view class="product">
 			<view class="img">
 				<image :src="list.productImage" mode=""></image>
@@ -20,7 +13,7 @@
 			</view>
 		</view>
 		<view class="history">
-			<view class="client"  v-for="(item,index) in list.afterSaleReasonVo" :key="index">
+			<view class="client"  v-for="(item, index) in list.afterSaleReasonVo" :key="index">
 				<view class="title">
 					<view class="img" v-if="item.refundType == 0">
 						<image :src="item.userAvatar" alt="" />
@@ -54,18 +47,18 @@
 				</view>
 				<!-- 商家拒绝 -->
 				<view class="" v-if="item.refundType == 1">
-				<view class="information" >
-					拒绝原因:{{item.refuseReason}}
-				</view>
-				<view class="information">
-					补充说明:{{item.refuseReasonExplain}}
-				</view>
+					<view class="information" >
+						拒绝原因:{{item.refuseReason}}
+					</view>
+					<view class="information">
+						补充说明:{{item.refuseReasonExplain}}
 					</view>
+				</view>
 				<!-- 商家同意 -->
 				<!-- <view class="information" v-if="item.refundType == 0">
 					您已同意退货退款,平台会将退款原路退回。
 				</view> -->
-				<view class="request" v-if="item.auditType ==0">
+				<view class="request" v-if="item.auditType == 0">
 					<view class="btn" @click="reject(item)">拒绝</view>
 					<view class="btn" @click="agree(item)">同意</view>
 				</view>
@@ -107,125 +100,133 @@
 </template>
 
 <script>
-	export default {
-		data() {
-			return {
-				list: [],
-				orderNo: '',
-				reasonList: [{
-						name: '商品已使用',
-						check: false,
-					},
-					{
-						name: '服务已核销',
-						check: false,
-					}
-				],
-				isRefuse: false,
-				rejectData: {
-					id: '',
-					reOrderId: '',
-					refuseReason: '',
-					refuseReasonExplain: ''
+export default {
+	data() {
+		return {
+			list: {
+				productImage: '/static/banner/banner1.png',
+				productName: 'productName',
+				orderPrice: 'orderPrice',
+				afterSaleReasonVo: [
+					{refundType: 0, auditType: 0, nickName: 'nickName', createTime: 'createTime', corporateName: 'corporateName', rejectionTime: 'rejectionTime'},
+					{refundType: 0, nickName: 'nickName', createTime: 'createTime', corporateName: 'corporateName', rejectionTime: 'rejectionTime'},
+					{refundType: 1, nickName: 'nickName', createTime: 'createTime', corporateName: 'corporateName', rejectionTime: 'rejectionTime'},
+				]
+			},
+			orderNo: '',
+			reasonList: [{
+					name: '商品已使用',
+					check: false,
+				},
+				{
+					name: '服务已核销',
+					check: false,
 				}
+			],
+			isRefuse: false,
+			rejectData: {
+				id: '',
+				reOrderId: '',
+				refuseReason: '',
+				refuseReasonExplain: ''
 			}
+		}
+	},
+	mounted() {
+		// this.getRecord()
+		// this.getCodeList()
+	},
+	onLoad(query) {
+		this.orderNo = query.orderId;
+	},
+	methods: {
+		//返回
+		back() {
+			uni.navigateBack({
+				delta: 1
+			});
 		},
-		methods: {
-			//返回
-			back() {
-				uni.navigateBack({
-					delta: 1
-				});
-			},
-			getRecord() {
-				let data = {
-					orderNo: this.orderNo
+		getRecord() {
+			let data = {
+				orderNo: this.orderNo
+			}
+			this.$http.get("/app/order/locaOrder/afterSaleDetails?orderNo=" + this.orderNo).then(res => {
+				if (res.data.code == 200) {
+					this.list = res.data.result
 				}
-				this.$http.get("/app/order/locaOrder/afterSaleDetails?orderNo=" + this.orderNo).then(res => {
+			})
+		},
+		selectReason(item, index) {
+			console.log(item)
+			this.reasonList.forEach(reason => {
+				reason.check = false;
+			});
+			this.reasonList[index].check = true
+			this.rejectData.refuseReason = item.value
+		},
+		cutPopup() {
+			this.isRefuse = false
+		},
+		reject(item) {
+			console.log(item)
+			
+			this.isRefuse = true
+			this.rejectData.id = item.id
+			this.rejectData.reOrderId = item.reOrderId
+		},
+		//提交拒绝
+		refusalRefund() {
+			if(this.rejectData.refuseReason==''){
+				uni.showToast({
+					icon: 'none',
+					title: '选择拒绝原因'
+				})
+				return
+			}else{
+				this.$http.post("/app/order/locaOrder/refusalRefund", this.rejectData).then(res => {
 					if (res.data.code == 200) {
 						console.log(res)
-						this.list = res.data.result
-					}
-				})
-			},
-			selectReason(item, index) {
-				console.log(item)
-				this.reasonList.forEach(reason => {
-					reason.check = false;
-				});
-				this.reasonList[index].check = true
-				this.rejectData.refuseReason = item.value
-			},
-			cutPopup() {
-				this.isRefuse = false
-			},
-			reject(item) {
-				console.log(item)
-				
-				this.isRefuse = true
-				this.rejectData.id = item.id
-				this.rejectData.reOrderId = item.reOrderId
-			},
-			//提交拒绝
-			refusalRefund() {
-				if(this.rejectData.refuseReason==''){
-					uni.showToast({
-						icon: 'none',
-						title: '选择拒绝原因'
-					})
-					return
-				}else{
-					this.$http.post("/app/order/locaOrder/refusalRefund", this.rejectData).then(res => {
-						if (res.data.code == 200) {
-							console.log(res)
-							uni.showToast({
-								icon: 'none',
-								title: '拒绝成功'
-							})
-							this.isRefuse = false
-							this.getRecord()
-							// this.list = res.data.result
-						}
-					})
-				}
-
-			},
-			getCodeList() {
-				this.$http.get("/sys/api/getManyDictItems?dictCodeList=" + 'reason_refusal').then(res => {
-					if (res.statusCode == 200) {
-						// 
-						res.data.reason_refusal.forEach(item => {
-							item.check = false
-						})
-						this.reasonList = res.data.reason_refusal
-					}
-				})
-			},
-			// 同意退款
-			agree(item){
-				let data = {
-					reOrderId:this.orderNo
-				}
-				this.$http.post("/app/order/locaOrder/agreeRefund",data).then(res => {
-					if (res.statusCode == 200) {
 						uni.showToast({
 							icon: 'none',
-							title: '商家已同意退款'
+							title: '拒绝成功'
 						})
+						this.isRefuse = false
 						this.getRecord()
+						// this.list = res.data.result
 					}
 				})
-				
 			}
+
 		},
-		mounted() {
-			this.getRecord()
-			this.getCodeList()
+		getCodeList() {
+			this.$http.get("/sys/api/getManyDictItems?dictCodeList=" + 'reason_refusal').then(res => {
+				if (res.statusCode == 200) {
+					// 
+					res.data.reason_refusal.forEach(item => {
+						item.check = false
+					})
+					this.reasonList = res.data.reason_refusal
+				}
+			})
 		},
-		onLoad(options) {
-			this.orderNo = options.orderId
+		// 同意退款
+		agree(item){
+			let data = {
+				reOrderId:this.orderNo
+			}
+			this.$http.post("/app/order/locaOrder/agreeRefund",data).then(res => {
+				if (res.statusCode == 200) {
+					uni.showToast({
+						icon: 'none',
+						title: '商家已同意退款'
+					})
+					this.getRecord()
+				}
+			})
+			
 		}
 	}
+}
 </script>
 
 <style lang="scss" scoped>
@@ -235,39 +236,8 @@
 		background: #F7F8FC;
 		display: flex;
 		flex-direction: column;
-		/*#ifdef APP-PLUS*/
-		.top {
-			width: 100%;
-			height: var(--status-bar-height);
-			background: #FFFFFF;
-		}
-
-		/*#endif*/
-		.head {
-			width: 100%;
-			height: 112rpx;
-			padding: 20rpx;
-			display: flex;
-			align-items: center;
-			background: #FFFFFF;
-			position: relative;
-
-			.cuIcon-back {
-				font-size: 40rpx;
-				margin-right: 40rpx;
-			}
-
-			.case {
-				position: absolute;
-				left: 50%;
-				transform: translateX(-50%);
-				font-size: 36rpx;
-				font-weight: 600;
-			}
-		}
 
 		.product {
-			
 			display: flex;
 			border-radius: 16rpx;
 			padding: 20rpx 24rpx;

+ 59 - 0
pages/groupMeal/tabbar/index.vue

@@ -0,0 +1,59 @@
+<template>
+	<u-tabbar :list="list" active-color="#449AFF" v-model="current" @change="onChange"></u-tabbar>
+</template>
+
+<script>
+export default {
+	name: "",
+	props: {
+		title: {
+			default: '',
+			type: String
+		},
+	},
+	data() {
+		return {
+			list: [
+				{
+					iconPath: "/static/groupMeal/tab_un1.png",
+					selectedIconPath: "/static/groupMeal/tab_1.png",
+					text: "商品",
+					customIcon: false,
+                    urlPath: '/pages/groupMeal/goods/list'
+				},
+				{
+					iconPath: "/static/groupMeal/tab_un2.png",
+					selectedIconPath: "/static/groupMeal/tab_2.png",
+					text: "订单",
+					customIcon: false,
+                    urlPath: '/pages/groupMeal/orders/order-alist'
+				},
+				{
+					iconPath: "/static/groupMeal/tab_un3.png",
+					selectedIconPath: "/static/groupMeal/tab_3.png",
+					text: "设置",
+					customIcon: false,
+                    urlPath: '/pages/groupMeal/users/index'
+				},
+			],
+			current: 0,
+		};
+	},
+	mounted() {
+        this.current = this.list.findIndex(item => item.urlPath === this.$route.path);
+	},
+	methods: {
+		onChange(e) {
+            uni.redirectTo({
+                url: this.list[e].urlPath
+            });
+		},
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep .u-tabbar__content__item__text {
+	bottom: 4px;
+}
+</style>

+ 29 - 35
pages/groupMeal/users/bankCard-list.vue

@@ -15,13 +15,13 @@
 						<view class="bank-name">{{ card.bankName }}</view>
 						<view class="card-type">{{ card.cardType }}</view>
 					</view>
-					<u-icon name="more-dot-fill" color="#fff" size="24" @click="showCardActions(card)"></u-icon>
+					<image class="more" src="/static/groupMeal/icon_more.png" @click="showCardActions(card)"></image>
 				</view>
 				<view class="card-number">
-					<text>****</text>
-					<text>****</text>
-					<text>****</text>
-					<text>{{ card.last4Digits }}</text>
+					<text>●●●●</text>
+					<text>●●●●</text>
+					<text>●●●●</text>
+					<text class="n">{{ card.last4Digits }}</text>
 				</view>
 			</view>
 		</view>
@@ -49,30 +49,11 @@
 export default {
 	data() {
 		return {
-			colorData: [
-				{'工商银行': '#C7000A'},
-				{'交通银行': '#00377A'},
-				{'招商银行': '#A30030'},
-				{'民生银行': '#0072BC'},
-				{'中信银行': '#D70010'},
-				{'浦发银行': '#000073'},
-				{'兴业银行': '#003F97'},
-				{'光大银行': '#6A1685'},
-				{'广发银行': '#E60021'},
-				{'平安银行': '#F15A25'},
-				{'北京银行': '#CB030D'},
-				{'华夏银行': '#DB0D17'},
-				{'农业银行': '#319C8B'},
-				{'建设银行': '#0066B3'},
-				{'邮政银行': '#02724A'},
-				{'中国银行': '#A71E32'},
-				{'宁波银行': '#EF8F38'},
-			],
 			cardList: [
-				{ id: 1, bankName: '中国建设银行', cardType: '储蓄卡', last4Digits: '0882', logo: '/static/bank_logo/ccb.png', type: 'ccb' },
-				{ id: 2, bankName: '中国光大银行', cardType: '储蓄卡', last4Digits: '0882', logo: '/static/bank_logo/ceb.png', type: 'ceb' },
-				{ id: 3, bankName: '中国工商银行', cardType: '储蓄卡', last4Digits: '0882', logo: '/static/bank_logo/icbc.png', type: 'icbc' },
-				{ id: 4, bankName: '中国邮政储蓄银行', cardType: '储蓄卡', last4Digits: '0882', logo: '/static/bank_logo/psbc.png', type: 'psbc' },
+				{ id: 1, bankName: '中国建设银行', cardType: '储蓄卡', last4Digits: '0882', logo: '/static/groupMeal/iconback/yinhang-jianshe.png', type: 'ccb' },
+				{ id: 2, bankName: '中国光大银行', cardType: '储蓄卡', last4Digits: '0882', logo: '/static/groupMeal/iconback/yinhang-guangda.png', type: 'ceb' },
+				{ id: 3, bankName: '中国工商银行', cardType: '储蓄卡', last4Digits: '0882', logo: '/static/groupMeal/iconback/yinhang-gongshang.png', type: 'icbc' },
+				{ id: 4, bankName: '中国邮政储蓄银行', cardType: '储蓄卡', last4Digits: '0882', logo: '/static/groupMeal/iconback/yinhang-youzhengchuxu.png', type: 'psbc' },
 			],
 			showActions: false,
 			actions: [{ text: '解绑' }],
@@ -104,10 +85,10 @@ export default {
 		},
 		getCardBackground(type) {
 			const gradients = {
-				ccb: this.linearGradient(90, '#0066B3', 0.5, '#0066B3', 1),
-				ceb: this.linearGradient(90, '#6A1685', 0.5, '#6A1685', 1),
-				icbc: this.linearGradient(90, '#C7000A', 0.5, '#C7000A', 1),
-				psbc: this.linearGradient(90, '#02724A', 0.5, '#02724A', 1),
+				ccb: this.linearGradient(90, '#0066B3', 0.5, '#0066B3', 0.8),
+				ceb: this.linearGradient(90, '#6A1685', 0.5, '#6A1685', 0.8),
+				icbc: this.linearGradient(90, '#C7000A', 0.5, '#C7000A', 0.8),
+				psbc: this.linearGradient(90, '#02724A', 0.5, '#02724A', 0.8),
 			};
 			return gradients[type] || 'linear-gradient(90deg, #888, #aaa)';
 		},
@@ -147,15 +128,16 @@ export default {
 	padding: 24rpx;
 }
 .card-item {
-	color: #fff;
+	color: #333333;
 	padding: 28rpx;
 	margin-bottom: 20rpx;
 	border-radius: 12rpx;
 	box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.1);
 	.card-header {
+		margin-bottom: 40rpx;
+		position: relative;
 		display: flex;
 		align-items: center;
-		margin-bottom: 40rpx;
 		.bank-logo {
 			width: 80rpx;
 			height: 80rpx;
@@ -174,12 +156,24 @@ export default {
 				opacity: 0.8;
 			}
 		}
+		.more {
+			width: 56rpx;
+			height: 40rpx;
+			position: absolute;
+			top: 0;
+			right: 0;
+		}
 	}
 	.card-number {
-		font-size: 36rpx;
+		font-size: 28rpx;
 		letter-spacing: 2rpx;
 		display: flex;
+		align-items: center;
 		justify-content: space-between;
+		.n {
+			font-size: 36rpx;
+			font-family: fantasy;
+		}
 	}
 }
 .footer-bar {

+ 7 - 9
pages/groupMeal/users/bankCard-select.vue

@@ -1,5 +1,5 @@
 <template>
-	<u-popup mode="bottom" :border-radius="20" 
+	<u-popup mode="bottom" :border-radius="20"
         :safe-area-inset-bottom="true"
         v-model="show" @close="close"
     >
@@ -24,9 +24,9 @@
 
 				<!-- 添加银行卡 -->
 				<view class="card-item add-card" @click="addCard">
-					<u-icon name="plus-circle" color="#2979ff" size="40"></u-icon>
+					<image class="bank-icon" src="/static/groupMeal/icon_bankadd.png" mode="aspectFit"></image>
 					<text class="card-name">添加银行卡</text>
-					<u-icon name="arrow-right" color="#909399" size="32"></u-icon>
+					<u-icon name="arrow-right" color="#C7C6CA" size="32"></u-icon>
 				</view>
 			</scroll-view>
 		</view>
@@ -86,6 +86,9 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+::v-deep .u-drawer-bottom {
+	background: #F7F8FC;
+}
 .popup-container {
     .popup-header {
         padding: 20rpx 30rpx;
@@ -104,6 +107,7 @@ export default {
     }
     .card-list-scroll {
         max-height: 60vh; // 限制最大高度,超出则滚动
+		background: #fff;
     }
     .card-item {
         display: flex;
@@ -115,18 +119,12 @@ export default {
             width: 40rpx;
             height: 40rpx;
             margin-right: 20rpx;
-            background: #eee;
         }
         .card-name {
             flex: 1;
             font-size: 30rpx;
             color: #303133;
         }
-        &.add-card {
-            .card-name {
-                color: #2979ff;
-            }
-        }
     }
 }
 </style>

+ 13 - 5
pages/groupMeal/users/index.vue

@@ -1,5 +1,7 @@
 <template>
 	<view>
+		<u-navbar title="团餐设置" :autoBack="true" :placeholder="true"></u-navbar>
+
 		<u-cell-group :border="false">
 			<u-cell-item v-for="(item, i) in data" :key="i" value="" @click="onClick(item)">
 				<view class="cell-box" slot="title">
@@ -8,28 +10,34 @@
 				</view>
 			</u-cell-item>
 		</u-cell-group>
+
+		<Tabbar />
 	</view>
 </template>
 
 <script>
+import Tabbar from '@/pages/groupMeal/tabbar/index.vue';
 export default {
+	components: {
+		Tabbar
+	},
 	data() {
 		return {
 			data: [
 				{
 					name: '我的团长',
-					icon: '/static/icon/icon_edit.png',
-					path: ''
+					icon: '/static/groupMeal/icon_user.png',
+					path: '/pages/groupMeal/users/team-member'
 				},
 				{
 					name: '团餐设置',
-					icon: '/static/icon/icon_edit.png',
+					icon: '/static/groupMeal/icon_file.png',
 					path: '/pages/groupMeal/users/settings'
 				},
 				{
 					name: '企业团餐设置',
-					icon: '/static/icon/icon_edit.png',
-					path: ''
+					icon: '/static/groupMeal/icon_build.png',
+					path: '/pages/groupMeal/users/settings'
 				},
 			]
 		}

+ 116 - 0
pages/groupMeal/users/team-member.vue

@@ -0,0 +1,116 @@
+<template>
+	<view class="page-container">
+		<!-- 自定义导航栏 -->
+		<u-navbar
+			title="我的团长"
+			bgColor="transparent"
+			:autoBack="true"
+			:titleStyle="{ color: '#303133', fontWeight: 'bold' }"
+			:placeholder="true"
+		>
+		</u-navbar>
+
+		<view class="main-box">
+            <!-- 用户列表 -->
+            <view class="user-list-card">
+				<ListScrollView 
+					ref="listScroll"
+					:api="api"
+				>
+					<template v-slot:list="{ data }">
+						<view class="user-item" v-for="(item, i) in 10" :key="i" @click="onClick">
+							<u-avatar size="80" src="/static/product/user.png" />
+							<view class="user-info">
+								<view class="name">{{ item.nickName || '' }}</view>
+								<view class="phone">{{ item.phone || '' }}</view>
+							</view>
+						</view>
+					</template>
+				</ListScrollView>
+            </view>
+        </view>
+	</view>
+</template>
+
+<script>
+import ListScrollView from '@/components/list-scroll-view/index.vue';
+export default {
+	components: {
+		ListScrollView
+	},
+    data() {
+        return {
+			api: null,
+        };
+    },
+    onLoad() {
+        
+    },
+    methods: {
+        onClick() {
+			// uni.navigateTo({
+			// 	url: `${e.path}`
+			// });
+        }
+    }
+};
+</script>
+
+<style lang="scss" scoped>
+.page-container {
+	height: 100vh;
+	display: flex;
+	flex-direction: column;
+	background:
+	linear-gradient(180deg, rgba(255,255,255,0) 0%, #F7F8FC 10%),
+	linear-gradient(90deg, #E6FFFF 0%, #CEF7FF 40%, #A3CEFE 73%, #BCD6FF 100%);
+
+    .main-box {
+		flex: 1;
+		overflow: auto;
+    }
+}
+
+.user-list-card {
+	height: 100%;
+	padding: 10rpx 28rpx;
+	background-color: #ffffff;
+
+	&.card0 {
+		border-top-right-radius: 16rpx;
+	}
+	&.card1 {
+		border-radius: 16rpx;
+	}
+	&.card2 {
+		border-top-left-radius: 16rpx;
+	}
+
+	.user-item {
+		display: flex;
+		align-items: center;
+		padding: 20rpx 0;
+		border-bottom: 1rpx solid #eeeeee;
+
+		&:last-child {
+			// border-bottom: none;
+		}
+
+		.user-info {
+			flex: 1;
+			margin-left: 28rpx;
+			.name {
+				font-weight: 500;
+                font-size: 28rpx;
+                color: #333333;
+			}
+			.phone {
+				font-weight: 400;
+                font-size: 26rpx;
+                color: #999999;
+				margin-top: 8rpx;
+			}
+		}
+	}
+}
+</style>

+ 8 - 8
pages/groupMeal/users/withdrawal.vue

@@ -7,7 +7,7 @@
 				<view class="label">提现至</view>
 				<view class="content">
 					<view class="bank-info">
-						<u-image class="bank-icon" src="/static/icon/icon_plus.png" width="48rpx" height="48rpx" mode="aspectFit"></u-image>
+						<u-image class="bank-icon" :src="bankCard.icon" width="48rpx" height="48rpx" mode="aspectFit"></u-image>
 						<text class="bank-name">{{ bankCard.name }} ({{ bankCard.tailNumber }})</text>
 					</view>
 					<u-icon name="arrow-right" color="#c0c4cc" size="32rpx"></u-icon>
@@ -66,19 +66,19 @@ export default {
 			bankCard: {
 				name: '中国工商银行',
 				tailNumber: '0882',
-				icon: 'icbc' // 用于区分图标
+				icon: '/static/groupMeal/iconback/yinhang-gongshang.png' 
 			},
 			availableBalance: '821.33', // 当前可提现余额
 			withdrawalAmount: '', // 提现金额输入框的值
 			// 模拟的银行卡数据
 			bankCards: [
-				{ id: 101, name: '中国工商银行储蓄卡', last4: '0882', icon: '/static/demo/icbc.png' },
-				{ id: 102, name: '中国建设银行储蓄卡', last4: '0882', icon: '/static/demo/ccb.png' },
-				{ id: 103, name: '中国光大银行储蓄卡', last4: '0882', icon: '/static/demo/ceb.png' },
+				{ id: 101, name: '中国工商银行储蓄卡', last4: '0882', icon: '/static/groupMeal/iconback/yinhang-gongshang.png' },
+				{ id: 102, name: '中国建设银行储蓄卡', last4: '0882', icon: '/static/groupMeal/iconback/yinhang-jianshe.png' },
+				{ id: 103, name: '中国光大银行储蓄卡', last4: '0882', icon: '/static/groupMeal/iconback/yinhang-guangda.png' },
 				// 模拟更多数据以测试滚动
-				{ id: 104, name: '中国农业银行储蓄卡', last4: '1234', icon: '/static/demo/abc.png' },
-				{ id: 105, name: '招商银行储蓄卡', last4: '5678', icon: '/static/demo/cmb.png' },
-				{ id: 106, name: '交通银行储蓄卡', last4: '9012', icon: '/static/demo/boc.png' },
+				{ id: 104, name: '中国农业银行储蓄卡', last4: '1234', icon: '/static/groupMeal/iconback/yinhang-nonghang.png' },
+				{ id: 105, name: '招商银行储蓄卡', last4: '5678', icon: '/static/groupMeal/iconback/yinhang-zhaoshang.png' },
+				{ id: 106, name: '交通银行储蓄卡', last4: '9012', icon: '/static/groupMeal/iconback/yinhang-jiaotong.png' },
 			],
 			selectedCardId: 101, // 默认选中的卡ID
 		};

+ 13 - 18
pages/index/full.vue

@@ -49,7 +49,8 @@
 			return {
 				store: [{
 						name: '商品管理',
-						url: '/static/index/product.png'
+						url: '/static/index/product.png',
+						path: '/pages/product/index'
 					},
 					{
 						name: '优惠券',
@@ -61,7 +62,8 @@
 					},
 					{
 						name: '客户评价',
-						url: '/static/index/evaluate.png'
+						url: '/static/index/evaluate.png',
+						path: '/pages/evaluate/evaluate'
 					},
 					{
 						name: '秒杀活动',
@@ -72,12 +74,14 @@
 						url: '/static/index/shop.png'
 					},
 					{
-						name: '平台活动',
-						url: '/static/index/activity.png'
+						name: '团餐活动',
+						url: '/static/index/groupMeal.png',
+						path: '/pages/groupMeal/goods/list'
 					},
 					{
 						name: '财务管理',
-						url: '/static/index/audit.png'
+						url: '/static/index/audit.png',
+						path: '/pages/financial/management'
 					},
 				],
 				order: [
@@ -111,19 +115,10 @@
 		},
 		methods: {
 			storeFunc(item) {
-				if (item.name == '商品管理') {
-					uni.navigateTo({
-						url: '/pages/product/index'
-					})
-				} else if (item.name == '客户评价') {
-					uni.navigateTo({
-						url: '/pages/evaluate/evaluate'
-					})
-				} else if (item.name == '财务管理') {
-					uni.navigateTo({
-						url: '/pages/financial/management'
-					})
-				}
+				if (!item.path) return;
+				uni.navigateTo({
+					url: item.path
+				})
 			},
 			orderFunc(item) {
 				if (item.name == '核销') {

BIN
static/groupMeal/icon_bankadd.png


BIN
static/groupMeal/icon_build.png


BIN
static/groupMeal/icon_file.png


BIN
static/groupMeal/icon_more.png


BIN
static/groupMeal/icon_user.png


BIN
static/groupMeal/iconback/yinhang-dongya.png


BIN
static/groupMeal/iconback/yinhang-gongshang.png


BIN
static/groupMeal/iconback/yinhang-guangda.png


BIN
static/groupMeal/iconback/yinhang-hangzhou.png


BIN
static/groupMeal/iconback/yinhang-hengfeng.png


BIN
static/groupMeal/iconback/yinhang-huaqi.png


BIN
static/groupMeal/iconback/yinhang-huaxia.png


BIN
static/groupMeal/iconback/yinhang-huifeng.png


BIN
static/groupMeal/iconback/yinhang-jianshe.png


BIN
static/groupMeal/iconback/yinhang-jiaotong.png


BIN
static/groupMeal/iconback/yinhang-minsheng.png


BIN
static/groupMeal/iconback/yinhang-nanjing.png


BIN
static/groupMeal/iconback/yinhang-ningbo.png


BIN
static/groupMeal/iconback/yinhang-nonghang.png


BIN
static/groupMeal/iconback/yinhang-pingan.png


BIN
static/groupMeal/iconback/yinhang-pufa.png


BIN
static/groupMeal/iconback/yinhang-shanghai.png


BIN
static/groupMeal/iconback/yinhang-suning.png


BIN
static/groupMeal/iconback/yinhang-xingye.png


BIN
static/groupMeal/iconback/yinhang-youzhengchuxu.png


BIN
static/groupMeal/iconback/yinhang-zhada.png


BIN
static/groupMeal/iconback/yinhang-zhaoshang.png


BIN
static/groupMeal/iconback/yinhang-zheshang.png


BIN
static/groupMeal/iconback/yinhang-zhongguoyinhang.png


BIN
static/groupMeal/iconback/yinhang-zhongxin.png


BIN
static/groupMeal/tab_1.png


BIN
static/groupMeal/tab_2.png


BIN
static/groupMeal/tab_3.png


BIN
static/groupMeal/tab_un1.png


BIN
static/groupMeal/tab_un2.png


BIN
static/groupMeal/tab_un3.png


BIN
static/index/groupMeal.png


+ 8 - 2
uni_modules/uview-ui/components/u-navbar/u-navbar.vue

@@ -130,6 +130,11 @@
 				type: [Boolean, String],
 				default: true
 			},
+			// 背景颜色
+			bgColor: {
+				type: String,
+				default: ''
+			},
 			// 对象形式,因为用户可能定义一个纯色,或者线性渐变的颜色
 			background: {
 				type: Object,
@@ -185,10 +190,11 @@
 			},
 			// 整个导航栏的样式
 			navbarStyle() {
-				let style = {};
+				let style = {}, newStyle = {};
 				style.zIndex = this.zIndex ? this.zIndex : this.$u.zIndex.navbar;
+				if (this.bgColor) newStyle.background = this.bgColor;
 				// 合并用户传递的背景色对象
-				Object.assign(style, this.background);
+				Object.assign(style, this.background, newStyle);
 				return style;
 			},
 			// 导航中间的标题的样式

+ 5 - 5
uni_modules/uview-ui/components/u-upload/u-upload.vue

@@ -614,13 +614,13 @@ export default {
 
 .u-delete-icon {
 	position: absolute;
-	top: 10rpx;
-	right: 10rpx;
+	top: 0;
+	right: 0;
 	z-index: 10;
 	background-color: $u-type-error;
-	border-radius: 100rpx;
-	width: 44rpx;
-	height: 44rpx;
+	border-radius: 0 10rpx;
+	width: 40rpx;
+	height: 40rpx;
 	@include vue-flex;
 	align-items: center;
 	justify-content: center;