更新大理市民卡app
diff --git a/uview-ui/components/u-row-notice/u-row-notice.vue b/uview-ui/components/u-row-notice/u-row-notice.vue
new file mode 100644
index 0000000..f4683f1
--- /dev/null
+++ b/uview-ui/components/u-row-notice/u-row-notice.vue
@@ -0,0 +1,269 @@
+<template>
+	<view
+		v-if="show"
+		class="u-notice-bar"
+		:style="{
+			background: computeBgColor,
+			padding: padding
+		}"
+		:class="[
+			type ? `u-type-${type}-light-bg` : ''
+		]"
+	>
+		<view class="u-direction-row">
+			<view class="u-icon-wrap">
+				<u-icon class="u-left-icon" v-if="volumeIcon" name="volume-fill" :size="volumeSize" :color="computeColor"></u-icon>
+			</view>
+			<view class="u-notice-box" id="u-notice-box">
+				<view
+					class="u-notice-content"
+					id="u-notice-content"
+					:style="{
+						animationDuration: animationDuration,
+						animationPlayState: animationPlayState,
+					}"
+				>
+					<text class="u-notice-text" @tap="click" :style="[textStyle]"
+					:class="['u-type-' + type]">{{showText}}</text>
+				</view>
+			</view>
+			<view class="u-icon-wrap">
+				<u-icon @click="getMore" class="u-right-icon" v-if="moreIcon" name="arrow-right" :size="26" :color="computeColor"></u-icon>
+				<u-icon @click="close" class="u-right-icon" v-if="closeIcon" name="close" :size="24" :color="computeColor"></u-icon>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+export default {
+	props: {
+		// 显示的内容,数组
+		list: {
+			type: Array,
+			default() {
+				return [];
+			}
+		},
+		// 显示的主题,success|error|primary|info|warning|none
+		// none主题默认为透明背景,黑色(contentColor)字体
+		type: {
+			type: String,
+			default: 'warning'
+		},
+		// 是否显示左侧的音量图标
+		volumeIcon: {
+			type: Boolean,
+			default: true
+		},
+		// 是否显示右侧的右箭头图标
+		moreIcon: {
+			type: Boolean,
+			default: false
+		},
+		// 是否显示右侧的关闭图标
+		closeIcon: {
+			type: Boolean,
+			default: false
+		},
+		// 是否自动播放
+		autoplay: {
+			type: Boolean,
+			default: true
+		},
+		// 文字颜色,各图标也会使用文字颜色
+		color: {
+			type: String,
+			default: ''
+		},
+		// 背景颜色
+		bgColor: {
+			type: String,
+			default: ''
+		},
+		// 是否显示
+		show: {
+			type: Boolean,
+			default: true
+		},
+		// 字体大小,单位rpx
+		fontSize: {
+			type: [Number, String],
+			default: 26
+		},
+		// 音量喇叭的大小
+		volumeSize: {
+			type: [Number, String],
+			default: 34
+		},
+		// 水平滚动时的滚动速度,即每秒滚动多少rpx,这有利于控制文字无论多少时,都能有一个恒定的速度
+		speed: {
+			type: [Number, String],
+			default: 160
+		},
+		// 播放状态,play-播放,paused-暂停
+		playState: {
+			type: String,
+			default: 'play'
+		},
+		// 通知的边距
+		padding: {
+			type: [Number, String],
+			default: '18rpx 24rpx'
+		}
+	},
+	data() {
+		return {
+			textWidth: 0, // 滚动的文字宽度
+			boxWidth: 0, // 供文字滚动的父盒子的宽度,和前者一起为了计算滚动速度
+			animationDuration: '10s', // 动画执行时间
+			animationPlayState: 'paused', // 动画的开始和结束执行
+			showText: '' // 显示的文本
+		};
+	},
+	watch: {
+		list: {
+			immediate: true,
+			handler(val) {
+				this.showText = val.join(',');
+				this.$nextTick(() => {
+					this.initSize();
+				});
+			}
+		},
+		playState(val) {
+			if(val == 'play') this.animationPlayState = 'running';
+			else this.animationPlayState = 'paused';
+		},
+		speed(val) {
+			this.initSize();
+		}
+	},
+	computed: {
+		// 计算字体颜色,如果没有自定义的,就用uview主题颜色
+		computeColor() {
+			if (this.color) return this.color;
+			// 如果是无主题,就默认使用content-color
+			else if(this.type == 'none') return '#606266';
+			else return this.type;
+		},
+		// 文字内容的样式
+		textStyle() {
+			let style = {};
+			if (this.color) style.color = this.color;
+			else if(this.type == 'none') style.color = '#606266';
+			style.fontSize = this.fontSize + 'rpx';
+			return style;
+		},
+		// 计算背景颜色
+		computeBgColor() {
+			if (this.bgColor) return this.bgColor;
+			else if(this.type == 'none') return 'transparent';
+		}
+	},
+	mounted() {
+		this.$nextTick(() => {
+			this.initSize();
+		});
+	},
+	methods: {
+		initSize() {
+			let query = [],
+				boxWidth = 0,
+				textWidth = 0;
+			let textQuery = new Promise((resolve, reject) => {
+				uni.createSelectorQuery()
+					.in(this)
+					.select(`#u-notice-content`)
+					.boundingClientRect()
+					.exec(ret => {
+						this.textWidth = ret[0].width;
+						resolve();
+					});
+			});
+			query.push(textQuery);
+			Promise.all(query).then(() => {
+				// 根据t=s/v(时间=路程/速度),这里为何不需要加上#u-notice-box的宽度,因为中设置了.u-notice-content样式中设置了padding-left: 100%
+				// 恰巧计算出来的结果中已经包含了#u-notice-box的宽度
+				this.animationDuration = `${this.textWidth / uni.upx2px(this.speed)}s`;
+				// 这里必须这样开始动画,否则在APP上动画速度不会改变(HX版本2.4.6,IOS13)
+				this.animationPlayState = 'paused';
+				setTimeout(() => {
+					if(this.playState == 'play' && this.autoplay) this.animationPlayState = 'running';
+				}, 10);
+			});
+		},
+		// 点击通告栏
+		click(index) {
+			this.$emit('click');
+		},
+		// 点击关闭按钮
+		close() {
+			this.$emit('close');
+		},
+		// 点击更多箭头按钮
+		getMore() {
+			this.$emit('getMore');
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/style.components.scss";
+	
+.u-notice-bar {
+	padding: 18rpx 24rpx;
+	overflow: hidden;
+}
+
+.u-direction-row {
+	@include vue-flex;
+	align-items: center;
+	justify-content: space-between;
+}
+
+.u-left-icon {
+	/* #ifndef APP-NVUE */
+	display: inline-flex;
+	/* #endif */
+	align-items: center;
+}
+
+.u-notice-box {
+	flex: 1;
+	@include vue-flex;
+	overflow: hidden;
+	margin-left: 12rpx;
+}
+
+.u-right-icon {
+	margin-left: 12rpx;
+	display: inline-flex;
+	align-items: center;
+}
+
+.u-notice-content {
+	animation: u-loop-animation 10s linear infinite both;
+	text-align: right;
+	// 这一句很重要,为了能让滚动左右连接起来
+	padding-left: 100%;
+	@include vue-flex;
+	flex-wrap: nowrap;
+}
+
+.u-notice-text {
+	font-size: 26rpx;
+	word-break: keep-all;
+	white-space: nowrap
+}
+
+@keyframes u-loop-animation {
+	0% {
+		transform: translate3d(0, 0, 0);
+	}
+
+	100% {
+		transform: translate3d(-100%, 0, 0);
+	}
+}
+</style>