From d1448cb0ef10f358bb7bddb4e1ec268515e0b787 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 15 七月 2025 11:46:57 +0800
Subject: [PATCH] 项目初始化

---
 uni_modules/uview-ui/components/u-rate/u-rate.vue |  304 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 304 insertions(+), 0 deletions(-)

diff --git a/uni_modules/uview-ui/components/u-rate/u-rate.vue b/uni_modules/uview-ui/components/u-rate/u-rate.vue
new file mode 100644
index 0000000..5992038
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-rate/u-rate.vue
@@ -0,0 +1,304 @@
+<template>
+    <view
+        class="u-rate"
+        :id="elId"
+        ref="u-rate"
+        :style="[$u.addStyle(customStyle)]"
+    >
+        <view
+            class="u-rate__content"
+            @touchmove.stop="touchMove"
+            @touchend.stop="touchEnd"
+        >
+            <view
+                class="u-rate__content__item"
+                v-for="(item, index) in Number(count)"
+                :key="index"
+                :class="[elClass]"
+            >
+                <view
+                    class="u-rate__content__item__icon-wrap"
+                    ref="u-rate__content__item__icon-wrap"
+                    @tap.stop="clickHandler($event, index + 1)"
+                >
+                    <u-icon
+                        :name="
+                            Math.floor(activeIndex) > index
+                                ? activeIcon
+                                : inactiveIcon
+                        "
+                        :color="
+                            disabled
+                                ? '#c8c9cc'
+                                : Math.floor(activeIndex) > index
+                                ? activeColor
+                                : inactiveColor
+                        "
+                        :custom-style="{
+                            padding: `0 ${$u.addUnit(gutter / 2)}`,
+                        }"
+                        :size="size"
+                    ></u-icon>
+                </view>
+                <view
+                    v-if="allowHalf"
+                    @tap.stop="clickHandler($event, index + 1)"
+                    class="u-rate__content__item__icon-wrap u-rate__content__item__icon-wrap--half"
+                    :style="[{
+                        width: $u.addUnit(rateWidth / 2),
+                    }]"
+                    ref="u-rate__content__item__icon-wrap"
+                >
+                    <u-icon
+                        :name="
+                            Math.ceil(activeIndex) > index
+                                ? activeIcon
+                                : inactiveIcon
+                        "
+                        :color="
+                            disabled
+                                ? '#c8c9cc'
+                                : Math.ceil(activeIndex) > index
+                                ? activeColor
+                                : inactiveColor
+                        "
+                        :custom-style="{
+                            padding: `0 ${$u.addUnit(gutter / 2)}`
+                        }"
+                        :size="size"
+                    ></u-icon>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+	import props from './props.js';
+
+	// #ifdef APP-NVUE
+	const dom = weex.requireModule("dom");
+	// #endif
+	/**
+	 * rate 璇勫垎
+	 * @description 璇ョ粍浠朵竴鑸敤浜庢弧鎰忓害璋冩煡锛屾槦鍨嬭瘎鍒嗙殑鍦烘櫙
+	 * @tutorial https://www.uviewui.com/components/rate.html
+	 * @property {String | Number}	value			鐢ㄤ簬v-model鍙屽悜缁戝畾閫変腑鐨勬槦鏄熸暟閲� (榛樿 1 )
+	 * @property {String | Number}	count			鏈�澶氬彲閫夌殑鏄熸槦鏁伴噺 锛堥粯璁� 5 锛�
+	 * @property {Boolean}			disabled		鏄惁绂佹鐢ㄦ埛鎿嶄綔 锛堥粯璁� false 锛�
+	 * @property {Boolean}			readonly		鏄惁鍙 锛堥粯璁� false 锛�
+	 * @property {String | Number}	size			鏄熸槦鐨勫ぇ灏忥紝鍗曚綅px 锛堥粯璁� 18 锛�
+	 * @property {String}			inactiveColor	鏈�変腑鏄熸槦鐨勯鑹� 锛堥粯璁� '#b2b2b2' 锛�
+	 * @property {String}			activeColor		閫変腑鐨勬槦鏄熼鑹� 锛堥粯璁� '#FA3534' 锛�
+	 * @property {String | Number}	gutter			鏄熸槦涔嬮棿鐨勮窛绂� 锛堥粯璁� 4 锛�
+	 * @property {String | Number}	minCount		鏈�灏戦�変腑鏄熸槦鐨勪釜鏁� 锛堥粯璁� 1 锛�
+	 * @property {Boolean}			allowHalf		鏄惁鍏佽鍗婃槦閫夋嫨 锛堥粯璁� false 锛�
+	 * @property {String}			activeIcon		閫変腑鏃剁殑鍥炬爣鍚嶏紝鍙兘涓簎View鐨勫唴缃浘鏍� 锛堥粯璁� 'star-fill' 锛�
+	 * @property {String}			inactiveIcon	鏈�変腑鏃剁殑鍥炬爣鍚嶏紝鍙兘涓簎View鐨勫唴缃浘鏍� 锛堥粯璁� 'star' 锛�
+	 * @property {Boolean}			touchable		鏄惁鍙互閫氳繃婊戝姩鎵嬪娍閫夋嫨璇勫垎 锛堥粯璁� 'true' 锛�
+	 * @property {Object}			customStyle		缁勪欢鐨勬牱寮忥紝瀵硅薄褰㈠紡
+	 * @event {Function} change 閫変腑鐨勬槦鏄熷彂鐢熷彉鍖栨椂瑙﹀彂
+	 * @example <u-rate :count="count" :value="2"></u-rate>
+	 */
+	export default {
+		name: "u-rate",
+		mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+		data() {
+			return {
+				// 鐢熸垚涓�涓敮涓�id锛屽惁鍒欎竴涓〉闈㈠涓瘎鍒嗙粍浠讹紝浼氶�犳垚鍐茬獊
+				elId: uni.$u.guid(),
+				elClass: uni.$u.guid(),
+				rateBoxLeft: 0, // 璇勫垎鐩掑瓙宸﹁竟鍒板睆骞曞乏杈圭殑璺濈锛岀敤浜庢粦鍔ㄩ�夋嫨鏃惰绠楄窛绂�
+				activeIndex: this.value,
+				rateWidth: 0, // 姣忎釜鏄熸槦鐨勫搴�
+				// 鏍囪瘑鏄惁姝e湪婊戝姩锛岀敱浜巌OS浜嬩欢涓妕ouch姣攃lick鍏堣Е鍙戯紝瀵艰嚧蹇�熸粦鍔ㄧ粨鏉熷悗锛屾帴鐫�瑙﹀彂click锛屽鑷翠簨浠舵贩涔辫�屽嚭閿�
+				moving: false,
+			};
+		},
+		watch: {
+			value(val) {
+				this.activeIndex = val;
+			},
+			activeIndex: 'emitEvent'
+		},
+		methods: {
+			init() {
+				uni.$u.sleep().then(() => {
+					this.getRateItemRect();
+					this.getRateIconWrapRect();
+				})
+			},
+			// 鑾峰彇璇勫垎缁勪欢鐩掑瓙鐨勫竷灞�淇℃伅
+			async getRateItemRect() {
+				await uni.$u.sleep();
+				// uView灏佽鐨勮幏鍙栬妭鐐圭殑鏂规硶锛岃瑙佹枃妗�
+				// #ifndef APP-NVUE
+				this.$uGetRect("#" + this.elId).then((res) => {
+					this.rateBoxLeft = res.left;
+				});
+				// #endif
+				// #ifdef APP-NVUE
+				dom.getComponentRect(this.$refs["u-rate"], (res) => {
+					this.rateBoxLeft = res.size.left;
+				});
+				// #endif
+			},
+			// 鑾峰彇鍗曚釜鏄熸槦鐨勫昂瀵�
+			getRateIconWrapRect() {
+				// uView灏佽鐨勮幏鍙栬妭鐐圭殑鏂规硶锛岃瑙佹枃妗�
+				// #ifndef APP-NVUE
+				this.$uGetRect("." + this.elClass).then((res) => {
+					this.rateWidth = res.width;
+				});
+				// #endif
+				// #ifdef APP-NVUE
+				dom.getComponentRect(
+					this.$refs["u-rate__content__item__icon-wrap"][0],
+					(res) => {
+						this.rateWidth = res.size.width;
+					}
+				);
+				// #endif
+			},
+			// 鎵嬫寚婊戝姩
+			touchMove(e) {
+				// 濡傛灉绂佹閫氳繃鎵嬪姩婊戝姩閫夋嫨锛岃繑鍥�
+				if (!this.touchable) {
+					return;
+				}
+				this.preventEvent(e);
+				const x = e.changedTouches[0].pageX;
+				this.getActiveIndex(x);
+			},
+			// 鍋滄婊戝姩
+			touchEnd(e) {
+				// 濡傛灉绂佹閫氳繃鎵嬪姩婊戝姩閫夋嫨锛岃繑鍥�
+				if (!this.touchable) {
+					return;
+				}
+				this.preventEvent(e);
+				const x = e.changedTouches[0].pageX;
+				this.getActiveIndex(x);
+			},
+			// 閫氳繃鐐瑰嚮锛岀洿鎺ラ�変腑
+			clickHandler(e, index) {
+				// ios涓婏紝moving鐘舵�佸彇娑堜簨浠惰Е鍙�
+				if (uni.$u.os() === "ios" && this.moving) {
+					return;
+				}
+				this.preventEvent(e);
+				let x = 0;
+				// 鐐瑰嚮鏃讹紝鍦╪vue涓婏紝鏃犳硶鑾峰緱鐐瑰嚮鐨勫潗鏍囷紝鎵�浠ユ棤娉曞疄鐜扮偣鍑诲崐鏄熼�夋嫨
+				// #ifndef APP-NVUE
+				x = e.changedTouches[0].pageX;
+				// #endif
+				// #ifdef APP-NVUE
+				// nvue涓嬶紝鏃犳硶閫氳繃鐐瑰嚮鑾峰緱鍧愭爣淇℃伅锛岃繖閲岄�氳繃鍏冪礌鐨勪綅缃昂瀵稿�兼ā鎷熷潗鏍�
+				x = index * this.rateWidth + this.rateBoxLeft;
+				// #endif
+				this.getActiveIndex(x,true);
+			},
+			// 鍙戝嚭浜嬩欢
+			emitEvent() {
+				// 鍙戝嚭change浜嬩欢
+				this.$emit("change", this.activeIndex);
+				// 鍚屾椂淇敼鍙屽悜缁戝畾鐨剉alue鐨勫��
+				this.$emit("input", this.activeIndex);
+			},
+			// 鑾峰彇褰撳墠婵�娲荤殑璇勫垎鍥炬爣
+			getActiveIndex(x,isClick = false) {
+				if (this.disabled || this.readonly) {
+					return;
+				}
+				// 鍒ゆ柇褰撳墠鎿嶄綔鐨勭偣鐨剎鍧愭爣鍊硷紝鏄惁鍦ㄥ厑璁哥殑杈圭晫鑼冨洿鍐�
+				const allRateWidth = this.rateWidth * this.count + this.rateBoxLeft;
+				// 濡傛灉灏忎簬绗竴涓浘鏍囩殑宸﹁竟鐣岋紝璁剧疆涓烘渶灏忓�硷紝濡傛灉澶т簬鎵�鏈夊浘鏍囩殑瀹藉害锛屽垯璁剧疆涓烘渶澶у��
+				x = uni.$u.range(this.rateBoxLeft, allRateWidth, x) - this.rateBoxLeft
+				// 婊戝姩鐐圭浉瀵逛簬璇勫垎鐩掑瓙宸﹁竟鐨勮窛绂�
+				const distance = x;
+				// 婊戝姩鐨勮窛绂伙紝鐩稿綋浜庡灏戦鏄熸槦
+				let index;
+				// 鍒ゆ柇鏄惁鍏佽鍗婃槦
+				if (this.allowHalf) {
+					index = Math.floor(distance / this.rateWidth);
+					// 鍙栦綑锛屽垽鏂皬鏁扮殑鍖洪棿鑼冨洿
+					const decimal = distance % this.rateWidth;
+					if (decimal <= this.rateWidth / 2 && decimal > 0) {
+						index += 0.5;
+					} else if (decimal > this.rateWidth / 2) {
+						index++;
+					}
+				} else {
+					index = Math.floor(distance / this.rateWidth);
+					// 鍙栦綑锛屽垽鏂皬鏁扮殑鍖洪棿鑼冨洿
+					const decimal = distance % this.rateWidth;
+					// 闈炲崐鏄熸椂锛屽彧鏈夎秴杩囦簡鍥炬爣鐨勪竴鍗婅窛绂伙紝鎵嶈涓烘槸閫夋嫨浜嗚繖棰楁槦
+					if (isClick){
+						if (decimal > 0) index++;
+					} else {
+						if (decimal > this.rateWidth / 2) index++;
+					}
+
+				}
+				this.activeIndex = Math.min(index, this.count);
+				// 瀵规渶灏戦鏄熸槦鐨勯檺鍒�
+				if (this.activeIndex < this.minCount) {
+					this.activeIndex = this.minCount;
+				}
+
+				// 璁剧疆寤舵椂涓轰簡璁ヽlick浜嬩欢鍦╰ouchmove涔嬪墠瑙﹀彂
+				setTimeout(() => {
+					this.moving = true;
+				}, 10);
+				// 涓�瀹氭椂闂村悗锛屽彇娑堟爣璇嗕负绉诲姩涓姸鎬侊紝鏄负浜嗚click浜嬩欢鏃犳晥
+				setTimeout(() => {
+					this.moving = false;
+				}, 10);
+			},
+		},
+		mounted() {
+			this.init();
+		},
+	};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+$u-rate-margin: 0 !default;
+$u-rate-padding: 0 !default;
+$u-rate-item-icon-wrap-half-top: 0 !default;
+$u-rate-item-icon-wrap-half-left: 0 !default;
+
+.u-rate {
+    @include flex;
+    align-items: center;
+    margin: $u-rate-margin;
+    padding: $u-rate-padding;
+    /* #ifndef APP-NVUE */
+    touch-action: none;
+    /* #endif */
+
+    &__content {
+        @include flex;
+
+		&__item {
+		    position: relative;
+
+		    &__icon-wrap {
+		        &--half {
+		            position: absolute;
+		            overflow: hidden;
+		            top: $u-rate-item-icon-wrap-half-top;
+		            left: $u-rate-item-icon-wrap-half-left;
+		        }
+		    }
+		}
+    }
+}
+
+.u-icon {
+    /* #ifndef APP-NVUE */
+    box-sizing: border-box;
+    /* #endif */
+}
+</style>

--
Gitblit v1.9.3