更新:登录功能

This commit is contained in:
2025-11-04 12:37:04 +08:00
commit a21fb92916
897 changed files with 51500 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
@import '../common/abstracts/variable';
@import '../common/abstracts/mixin';
@include b(text) {
@include when(bold) {
font-weight: bold;
}
@for $i from 1 through 5 {
&.is-lines-#{$i} {
@include multiEllipsis($i);
}
}
@include when(default) {
color: $-text-info-color;
}
@include when(primary) {
color: $-text-primary-color;
}
@include when(error) {
color: $-text-error-color;
}
@include when(warning) {
color: $-text-warning-color;
}
@include when(success) {
color: $-text-success-color;
}
}

View File

@@ -0,0 +1,98 @@
import type { ExtractPropTypes } from 'vue'
import { baseProps, makeBooleanProp, makeNumericProp, makeStringProp } from '../common/props'
export type TextType = 'default' | 'primary' | 'success' | 'warning' | 'error'
export const textProps = {
...baseProps,
/**
* 主题类型
* 类型string
* 可选值:'default' /'primary' / 'error' / 'warning' / 'success'
* 默认值:'default'
*/
type: makeStringProp<TextType>('default'),
/**
* 文字
* 类型string | number
* 默认值:'空字符串'
*/
text: makeNumericProp(''),
/**
* 字体大小
* 类型string
* 默认值:'空字符串'
*/
size: makeStringProp(''),
/**
* 文本处理的匹配模式
* 可选值:'text-普通文本' / 'date - 日期' / 'phone - 手机号' / 'name - 姓名' / 'price - 金额'
* 类型string
* 默认值:'text'
*/
mode: makeStringProp('text'),
/**
* 文字装饰,下划线,中划线等
* 可选值:'underline/line-through/overline'
* 类型string
* 默认值:'none'
*/
decoration: makeStringProp('none'),
/**
* mode=phone时点击文本是否拨打电话
* 类型boolean
* 默认值false
*/
call: makeBooleanProp(false),
/**
* 是否粗体默认normal
* 类型boolean
* 默认值false
*/
bold: makeBooleanProp(false),
/**
* 是否脱敏,当mode为phone和name时生效
* 类型boolean
* 默认值false
*/
format: makeBooleanProp(false),
/**
* 文本颜色
* 类型string
* 默认值:''
*/
color: makeStringProp(''),
/**
* 前置插槽
* 类型string
* 默认值:''
*/
prefix: String,
/**
* 后置插槽
* 类型string
* 默认值:''
*/
suffix: String,
/**
* 文本显示的行数如果设置超出此行数将会显示省略号。最大值为5。
*/
lines: Number,
/**
* 文本行高
* 类型string
* 默认值:''
*/
lineHeight: makeStringProp(''),
/**
* 自定义根节点样式
*/
customStyle: makeStringProp(''),
/**
* 自定义根节点样式类
*/
customClass: makeStringProp('')
}
export type TextProps = ExtractPropTypes<typeof textProps>

View File

@@ -0,0 +1,139 @@
<template>
<text @click="handleClick" :class="rootClass" :style="rootStyle">
<slot v-if="$slots.prefix || prefix" name="prefix">{{ prefix }}</slot>
<text>{{ formattedText }}</text>
<slot v-if="$slots.suffix || suffix" name="suffix">{{ suffix }}</slot>
</text>
</template>
<script lang="ts">
export default {
name: 'wd-text',
options: {
virtualHost: true,
addGlobalClass: true,
styleIsolation: 'shared'
}
}
</script>
<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import { isDef, objToStyle } from '../common/util'
import { textProps } from './types'
import dayjs from '../../dayjs'
// 获取组件的 props 和 emit 函数
const props = defineProps(textProps)
const emit = defineEmits(['click'])
// 存储文本类名的响应式变量
const textClass = ref<string>('')
// 监听 props 变化,合并 watch 逻辑
watch(
() => ({
type: props.type,
text: props.text,
mode: props.mode,
color: props.color,
bold: props.bold,
lines: props.lines,
format: props.format
}),
({ type }) => {
// 验证 type 属性
const types = ['primary', 'error', 'warning', 'success', 'default']
if (type && !types.includes(type)) {
console.error(`type must be one of ${types.toString()}`)
}
computeTextClass()
},
{ deep: true, immediate: true }
)
// 计算根元素的类名
const rootClass = computed(() => {
return `wd-text ${props.customClass} ${textClass.value}`
})
// 计算根元素的样式
const rootStyle = computed(() => {
const rootStyle: Record<string, any> = {}
if (props.color) {
rootStyle['color'] = props.color
}
if (props.size) {
rootStyle['font-size'] = `${props.size}`
}
if (props.lineHeight) {
rootStyle['line-height'] = `${props.lineHeight}`
}
if (props.decoration) {
rootStyle['text-decoration'] = `${props.decoration}`
}
return `${objToStyle(rootStyle)}${props.customStyle}`
})
// 计算文本类名的函数
function computeTextClass() {
const { type, color, bold, lines } = props
const textClassList: string[] = []
if (!color) {
textClassList.push(`is-${type}`)
}
if (isDef(lines)) {
textClassList.push(`is-lines-${lines}`)
}
bold && textClassList.push('is-bold')
textClass.value = textClassList.join(' ')
}
// 格式化文本的函数
function formatText(text: string, format: boolean, mode: string): string {
if (format) {
if (mode === 'phone') {
return text.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2')
} else if (mode === 'name') {
return text.replace(/^(.).*(.)$/, '$1**$2')
} else {
throw new Error('mode must be one of phone or name for encryption')
}
}
return text
}
// 格式化数字的函数
function formatNumber(num: number | string): string {
num = Number(num).toFixed(2)
const x = num.split('.')
let x1 = x[0]
const x2 = x.length > 1 ? '.' + x[1] : ''
const rgx = /(\d+)(\d{3})/
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1,$2')
}
return x1 + x2
}
// 计算格式化后的文本
const formattedText = computed(() => {
const { text, mode, format } = props
if (mode === 'date') {
return dayjs(Number(text)).format('YYYY-MM-DD')
}
if (mode === 'price') {
return formatNumber(text)
}
return formatText(`${text}`, format, mode)
})
// 处理点击事件
function handleClick(event: Event) {
emit('click', event)
}
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>