初始提交

This commit is contained in:
2026-01-04 11:09:06 +08:00
commit 8fa31df250
1326 changed files with 213907 additions and 0 deletions

View File

@@ -0,0 +1,234 @@
<template>
<view class="jnpf-input">
<template v-if="!detailed">
<view class="input-content" :class="{'input-border':addonBefore||addonAfter}">
<view class="input-left u-line-1" v-if="addonBefore">{{addonBefore}}</view>
<view class="input-center">
<u-input input-align='right' :border="false" v-model="innerValue"
:type="showPassword?'password':'text'" :maxlength="maxlength||maxlength===0?maxlength:9999"
:placeholder="placeholder" :disabled="disabled" :clearable='disabled ? false : clearable'
@input="onInput" @blur="onBlur" :class="{'input-disabled':disabled}" />
</view>
<!-- #ifndef H5 -->
<text class=" icon-ym icon-ym-scanCode1" v-if="useScan" @click="scanCode" />
<!-- #endif -->
<view class="input-right u-line-1" v-if="addonAfter">{{addonAfter}}</view>
<view class="input-count" v-if="showCount&&!addonBefore&&!addonAfter">
<text>{{ innerValue?String(innerValue).length:0 }}</text><text
v-if="maxlength">/{{ maxlength }}</text>
</view>
</view>
</template>
<view class="detail-text" :class="{ ellipsis: showOverflow ,['detail-text-'+align]:true,disabled:disabled }"
v-else>
<text class="detail-text-addon" v-if="addonBefore">{{ addonBefore }}</text>
{{ maskedValue }}
<text class="detail-text-addon" v-if="addonAfter">{{ addonAfter }}</text>
</view>
</view>
</template>
<script>
import {
useTextMask
} from './useTextMask';
export default {
name: 'jnpf-input',
props: {
modelValue: {
type: [String, Number],
default: ''
},
placeholder: {
type: String,
default: '请输入'
},
maxlength: {
type: Number,
default: null
},
showPassword: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: false
},
detailed: {
type: Boolean,
default: false
},
showOverflow: {
type: Boolean,
default: false
},
addonBefore: {
type: String,
default: ''
},
addonAfter: {
type: String,
default: ''
},
align: {
type: String,
default: 'right'
},
useScan: {
type: Boolean,
default: false
},
useMask: {
type: Boolean,
default: false
},
maskConfig: {
type: Object,
default: () => {}
},
showCount: {
type: Boolean,
default: false
},
},
data() {
return {
innerValue: '',
maskedValue: '',
}
},
watch: {
modelValue: {
handler(val) {
this.innerValue = val
if (!this.useMask) return (this.maskedValue = val);
const {
getMaskedText
} = useTextMask(this.maskConfig);
this.maskedValue = getMaskedText(val);
},
immediate: true,
}
},
methods: {
onInput(val) {
this.$nextTick(() => {
this.$emit('update:modelValue', val)
this.$emit('change', val)
})
},
onBlur(val) {
this.$emit('blur', val)
},
isJSON(str) {
try {
var obj = JSON.parse(str);
if (typeof obj == 'object' && obj) {
return true;
} else {
return false;
}
} catch (e) {
return false;
}
},
scanCode() {
uni.scanCode({
success: res => {
if (!res.result || typeof res.result !== 'string') return
this.onInput(res.result)
}
});
}
}
}
</script>
<style lang="scss">
.jnpf-input {
width: 100%;
.input-content {
display: flex;
border-radius: 10rpx;
height: 74rpx;
&.input-border {
border: 1rpx solid rgb(220, 223, 230)
}
.input-center {
flex: 1;
// padding: 0 8rpx;
.input-disabled {
:deep(.uni-input-placeholder) {
color: #9B9B9B !important;
}
:deep(.uni-input-input) {
color: #9B9B9B !important;
}
}
}
.input-left,
.input-right {
flex-shrink: 0;
width: 128rpx;
background-color: #f5f7fa;
color: #909399;
padding: 0 10rpx;
text-align: center;
}
.input-left {
border-right: 1rpx solid #dcdfe6;
border-radius: 10rpx 0 0 10rpx;
}
.input-right {
border-left: 1rpx solid #dcdfe6;
border-radius: 0px 10px 10px 0px;
}
.icon-ym-scanCode1 {
margin-right: 8rpx;
color: #909399;
}
.input-count {
color: #909399;
font-size: 24rpx;
}
}
.detail-text {
word-break: break-all;
text-align: right;
.detail-text-addon {
color: #909399;
}
&.disabled {
background-color: #ebedf0;
}
&.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
&.detail-text-left {
text-align: left;
}
}
}
</style>

View File

@@ -0,0 +1,170 @@
/**
* maskType
* 1 - 全掩盖
* 2 - 姓名-显示前1个字后1个字
* 3 - 手机号-显示前3位后4位
* 4 - 邮箱-显示前3个字@和之后的字
* 5 - 身份证-显示前6位后3位虚拟为4位
* 6 - IP地址-显示第1段IP
* 7 - 车牌号-显示前1个字后2位
* 8 - 银行卡号-显示前6位后4位
* 0 - 自定义规则
*/
export const defaultMaskOptions = {
filler: '*', // 填充符号
maskType: 1, // 掩码规则
prefixType: 1, // 开头显示
prefixLimit: 0, // 开头字数
prefixSpecifyChar: '', // 开头字符
suffixType: 1, // 结尾显示
suffixLimit: 0, // 结尾字数
suffixSpecifyChar: '', // 结尾字符
ignoreChar: '', // 显示字符
useUnrealMask: false, // 虚拟掩码
unrealMaskLength: 1, // 虚拟掩码长度
};
export function useTextMask(options = {}) {
const config = {
...defaultMaskOptions,
...options
};
// 全掩盖
function maskAll(str) {
return config.filler.repeat(str.length);
}
//姓名 显示前1个字后1个字
function maskName(str) {
if (str.length <= 1) return str;
const prefix = str[0];
if (str.length === 2) return prefix + config.filler;
const suffix = str.slice(-1);
const maskedChars = config.filler.repeat(str.length - 2);
return prefix + maskedChars + suffix;
}
// 手机号 - 显示前3位后4位
function maskPhoneNumber(str) {
if (str.length <= 7) return str;
const prefix = str.slice(0, 3);
const suffix = str.slice(-4);
const maskedChars = config.filler.repeat(str.length - 7);
return prefix + maskedChars + suffix;
}
// 邮箱 - 显示前3个字@和之后的字
function maskEmailAddress(str) {
const atIndex = str.indexOf('@');
if (str.length <= 3 || (atIndex > -1 && atIndex < 3)) return str;
let suffixLength = 0;
let maskedCharsLength = str.length - 3;
if (atIndex > 0) {
suffixLength = atIndex;
maskedCharsLength = atIndex - 3;
}
const prefix = str.slice(0, 3);
const suffix = suffixLength ? str.slice(suffixLength) : '';
const maskedChars = config.filler.repeat(maskedCharsLength);
return prefix + maskedChars + suffix;
}
// 身份证 - 显示前6位后3位虚拟为4位
function maskIdNumber(str) {
if (str.length <= 9) return str;
const prefix = str.slice(0, 6);
const suffix = str.slice(-3);
const maskedChars = config.filler.repeat(4);
return prefix + maskedChars + suffix;
}
// IP地址-显示第1段IP
function maskIPAddress(str) {
const segments = str.split('.');
if (segments.length < 1) return str;
const maskedChars = ('.' + config.filler.repeat(3)).repeat(3);
return segments[0] + maskedChars;
}
// 车牌号-显示前1个字后2位
function maskLicensePlate(str) {
if (str.length <= 3) return str;
const prefix = str[0];
const suffix = str.slice(-2);
const maskedChars = config.filler.repeat(str.length - 3);
return prefix + maskedChars + suffix;
}
// 银行卡号-显示前6位后4位
function maskBankCard(str) {
if (str.length <= 10) return str;
const prefix = str.slice(0, 6);
const suffix = str.slice(-4);
const maskedChars = config.filler.repeat(str.length - 10);
return prefix + maskedChars + suffix;
}
// 自定义掩码规则
function maskCustom(str) {
let prefixLength = 0,
suffixLength = 0;
if (config.prefixType === 2) prefixLength = config.prefixLimit || 0;
if ((config.prefixType === 3 || config.prefixType === 4) && config.prefixSpecifyChar) {
let specifyCharIndex = str.indexOf(config.prefixSpecifyChar);
if (specifyCharIndex > -1) prefixLength = config.prefixType === 3 ? specifyCharIndex :
specifyCharIndex + config.prefixSpecifyChar.length;
}
if (config.suffixType === 2) suffixLength = config.suffixLimit || 0;
if ((config.suffixType === 3 || config.suffixType === 4) && config.suffixSpecifyChar) {
let specifyCharIndex = str.indexOf(config.suffixSpecifyChar);
if (specifyCharIndex > -1) suffixLength = config.suffixType === 3 ?
str.length - specifyCharIndex - config.suffixSpecifyChar.length :
str.length - specifyCharIndex;
}
if (prefixLength + suffixLength >= str.length) return str;
const prefix = prefixLength ? str.slice(0, prefixLength) : '';
const suffix = suffixLength ? str.slice(-suffixLength) : '';
let middleChar = '';
if (!config.ignoreChar) {
const maskedLength = config.useUnrealMask ? config.unrealMaskLength || 1 : str.length - prefixLength -
suffixLength;
middleChar = config.filler.repeat(maskedLength);
} else {
const ignoreCharList = config.ignoreChar.split(',');
const middleStr = str.slice(prefixLength, str.length - suffixLength);
const reg = new RegExp('(' + ignoreCharList.map(o => o.replace(/\*/g, '\\*')).join('|') + ')', 'g');
let list = middleStr.split(reg);
list = list.map(o => {
if (o && !ignoreCharList.includes(o)) {
const maskedLength = config.useUnrealMask ? config.unrealMaskLength || 1 : o.length;
o = config.filler.repeat(maskedLength);
}
return o;
});
middleChar = list.join('');
}
return prefix + middleChar + suffix;
}
// 获取掩码后文本
function getMaskedText(str) {
if (!str) return '';
if (config.maskType === 1) return maskAll(str);
if (config.maskType === 2) return maskName(str);
if (config.maskType === 3) return maskPhoneNumber(str);
if (config.maskType === 4) return maskEmailAddress(str);
if (config.maskType === 5) return maskIdNumber(str);
if (config.maskType === 6) return maskIPAddress(str);
if (config.maskType === 7) return maskLicensePlate(str);
if (config.maskType === 8) return maskBankCard(str);
if (config.maskType === 0) return maskCustom(str);
return str;
}
return {
maskAll,
maskName,
maskPhoneNumber,
maskEmailAddress,
maskIdNumber,
maskIPAddress,
maskLicensePlate,
maskBankCard,
maskCustom,
getMaskedText
};
}