<template>
	<view class="c-number-pad">
		<view
			class="box"
			v-if="show"
			:style="[finalBoxStyle]"
			:class="{'safeBottomBox' : safeAreaInsetBottom}"
		>
			<view class="left">
				<view
					class="key-box"
					v-for="(item, index) in keys"
					:key="index"
				>
					<button
						class="key"
						hover-class="active"
						:style="{background: `${keyBg}`}"
						@touchend.prevent="tapKey(item)"
						@mouseup.prevent="tapKey(item)"
					>
						{{ item }}
					</button>
				</view>
				<view class="bottom">
					<button
						class="zero"
						hover-class="active"
						:style="{background: `${keyBg}`}"
						@touchend.prevent="tapKey('0')"
						@mouseup.prevent="tapKey('0')"
					>
						0
					</button>
					<button
						class="point"
						hover-class="active"
						v-if="showPoint"
						:style="{background: `${keyBg}`}"
						@touchend.prevent="tapKey('.')"
						@mouseup.prevent="tapKey('.')"
					>
						.
					</button>
				</view>
			</view>
			<view class="right">
				<button
					class="del"
					hover-class="active"
					:style="{background: `${delBg}`}"
					@touchend.prevent="del"
					@mouseup.prevent="del"
				>
					<image
						class="del-icon"
						:style="{width: `${delSize}rpx`, height: `${delSize}rpx`}"
						:src="delIcon"
					></image>
				</button>
				<button
					class="sure"
					hover-class="sure-active"
					:style="[finalConfirmStyle]"
					@touchend.prevent="confirm"
					@mouseup.prevent="confirm"
				>
					{{ confirmText }}
				</button>
			</view>
		</view>
	</view>
</template>

<script>
/**
 * @author cai
 * @time 2025-04-14
 * @description 数字键盘，密码键盘，带删除、小数点、确认键盘
 * @prop {String} 	value 	键盘输入的值，v-model双向绑定
 * @prop {Boolean} 	show	是否显示键盘，默认false
 * @prop {Boolean} 	safeAreaInsetBottom		是否开启底部安全区适配，默认true
 * @prop {Boolean} 	showPoint	是否显示小数点，默认true
 * @prop {Number} 	decimalPlaces	限制小数位数，-1则无限长度，默认2
 * @prop {Number} 	maxlength	输入的长度，0则无限长度，默认0
 * @prop {Number} 	zIndex	键盘层级 
 * @prop {String} 	fontSize	整体的字体大小，单位：rpx，默认32
 * @prop {String} 	boxBgColor	整个键盘的背景色，默认#f4f4f4
 * @prop {Object} 	boxStyle	盒子样式
 * @prop {String} 	confirmText	确认键文字，默认确认
 * @prop {String} 	confirmColor	确认键文字颜色，默认#fff
 * @prop {String} 	confirmBg	确认键背景，默认linear-gradient(to bottom, #ff7979, #ff0000)
 * @prop {Object} 	confirmStyle	确认键样式
 * @prop {String} 	keyBg	按键背景色，0-9和小数点的背景色，默认#fff
 * @prop {String} 	delBg	删除键的背景色，默认#fff
 * @prop {String} 	delColor	删除图标的颜色，默认#000
 * @prop {String|Number} 	delSize		删除图标的大小，单位：rpx，默认60
 * @emits key 	按键点击事件，携带当前点击的值
 * @emits del 	删除按钮事件
 * @emits confirm 右下角确认按钮事件，携带键盘输入的值
 */
import props from "./props";
import delSvg from "./delSvg.js";
export default {
	name: "c-number-pad",
	props,
	data() {
		return {
			tapValue: "",	// 点击的值
			keys: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
		}
	},
	computed: {
		// 盒子样式
		finalBoxStyle() {
			return {
				zIndex: this.zIndex,
				background: this.boxBgColor,
				fontSize: `${this.fontSize}rpx`,
				...this.boxStyle
			}
		},
		// 确认按钮样式
		finalConfirmStyle() {
			return {
				color: this.confirmColor,
				background: this.confirmBg,
				...this.confirmStyle
			}
		},
		// 删除图标
		delIcon() {
			const newSvg = delSvg.replace(/(fill=\"#000000\")/g, `fill="${this.delColor}"`);
			return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(newSvg)}`;
		}
	},
	watch: {
		value(val) {
			this.tapValue = val;
		},
		tapValue(val) {
			this.$emit("input", val);
		}
	},
	methods: {
		// 点击数字键或者小数点键
		tapKey(item) {
			this.$emit("key", item);
			// 限制输入的长度
			if (this.maxlength > 0 && this.maxlength === this.tapValue.length) return;
			// 限制小数显示0位，则不能输入小数点
			if (this.decimalPlaces === 0 && item === ".") return; 
			// 已经有小数点，则不能再输入小数点
			if (item === "." && this.tapValue.includes(".")) return;
			// 限制小数位数
			const decimal = this.tapValue.includes(".") ? this.tapValue.split(".")[1] : "";
			if (this.decimalPlaces > 0 && decimal.length === this.decimalPlaces) return;
			// 如果点击小数点按键，同时输入的值长度为0
			if (item === "." && this.tapValue.length === 0) {
				item = "0.";
			}
			// 正常情况添加
			this.tapValue += item;
		},
		// 点击删除按钮
		del() {
			this.$emit("del");
			if (this.tapValue.length > 0) {
				this.tapValue = this.tapValue.slice(0, this.tapValue.length - 1);
			}
		},
		// 点击确定按钮
		confirm() {
			this.$emit("confirm", this.tapValue);
		}
	}
}
</script>

<style lang="scss" scoped>
	@import "./c-number-pad.scss";
</style>