更新:登录功能

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,336 @@
@import './../common/abstracts/_mixin.scss';
@import './../common/abstracts/variable.scss';
.wot-theme-dark {
@include b(button) {
@include when(info) {
background: $-dark-background4;
color: $-dark-color3;
}
@include when(plain) {
background: transparent;
@include when(info) {
color: $-dark-color;
&::after {
border-color: $-dark-background5;
}
}
}
@include when(text) {
@include when(disabled) {
color: $-dark-color-gray;
background: transparent;
}
}
@include when(icon) {
color: $-dark-color;
@include when(disabled) {
color: $-dark-color-gray;
background: transparent;
}
}
}
}
@include b(button) {
margin-left: initial;
margin-right: initial;
position: relative;
display: inline-block;
outline: none;
-webkit-appearance: none;
outline: none;
background: transparent;
box-sizing: border-box;
border: none;
border-radius: 0;
color: $-button-normal-color;
transition: opacity 0.2s;
user-select: none;
font-weight: normal;
&::before {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
background: $-color-black;
border: inherit;
border-color: $-color-black;
border-radius: inherit;
transform: translate(-50%, -50%);
opacity: 0;
content: ' ';
}
&::after {
border: none;
border-radius: 0;
}
@include e(content) {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
@include m(active) {
&:active::before {
opacity: 0.15;
}
}
@include when(disabled) {
opacity: $-button-disabled-opacity;
}
@include e(loading) {
margin-right: 5px;
animation: wd-rotate 0.8s linear infinite;
animation-duration: 2s;
}
@include e(loading-svg) {
width: 100%;
height: 100%;
background-size: cover;
background-repeat: no-repeat;
}
@include when(loading) {}
@include when(primary) {
background: $-button-primary-bg-color;
color: $-button-primary-color;
}
@include when(success) {
background: $-button-success-bg-color;
color: $-button-success-color;
}
@include when(info) {
background: $-button-info-bg-color;
color: $-button-info-color;
}
@include when(warning) {
background: $-button-warning-bg-color;
color: $-button-warning-color;
}
@include when(error) {
background: $-button-error-bg-color;
color: $-button-error-color;
}
@include when(small) {
height: $-button-small-height;
padding: $-button-small-padding;
border-radius: $-button-small-radius;
font-size: $-button-small-fs;
font-weight: normal;
.wd-button__loading {
width: $-button-small-loading;
height: $-button-small-loading;
}
}
@include when(medium) {
height: $-button-medium-height;
padding: $-button-medium-padding;
border-radius: $-button-medium-radius;
font-size: $-button-medium-fs;
min-width: 120px;
@include when(round) {
@include when(icon) {
min-width: 0;
border-radius: 50%;
}
@include when(text) {
border-radius: 0;
min-width: 0;
}
}
.wd-button__loading {
width: $-button-medium-loading;
height: $-button-medium-loading;
}
}
@include when(large) {
height: $-button-large-height;
padding: $-button-large-padding;
border-radius: $-button-large-radius;
font-size: $-button-large-fs;
&::after {
border-radius: $-button-large-radius;
}
.wd-button__loading {
width: $-button-large-loading;
height: $-button-large-loading;
}
}
@include when(round) {
border-radius: 999px;
}
@include when(text) {
color: $-button-primary-bg-color;
min-width: 0;
padding: 4px 0;
&::after {
display: none;
}
&.wd-button--active {
opacity: $-button-text-hover-opacity;
&:active::before {
display: none;
}
}
@include when(disabled) {
color: $-button-normal-disabled-color;
background: transparent;
}
}
@include when(plain) {
background: $-button-plain-bg-color;
border: 1px solid currentColor;
@include when(primary) {
color: $-button-primary-bg-color;
}
@include when(success) {
color: $-button-success-bg-color;
}
@include when(info) {
color: $-button-info-plain-normal-color;
border-color: $-button-info-plain-border-color;
}
@include when(warning) {
color: $-button-warning-bg-color;
}
@include when(error) {
color: $-button-error-bg-color;
}
}
@include when(hairline) {
border-width: 0;
&.is-plain {
@include halfPixelBorderSurround();
&::before {
border-radius: inherit;
}
&::after {
border-color: inherit;
}
&.is-round {
&::after {
border-radius: inherit !important;
}
}
&.is-large {
&::after {
border-radius: calc(2 * $-button-large-radius);
}
}
&.is-medium {
&::after {
border-radius: calc(2 * $-button-medium-radius);
}
}
&.is-small {
&::after {
border-radius: calc(2 * $-button-small-radius);
}
}
}
}
@include when(block) {
display: block;
}
@include when(icon) {
width: $-button-icon-size;
height: $-button-icon-size;
padding: 0;
border-radius: 50%;
color: $-button-icon-color;
&::after {
display: none;
}
:deep(.wd-button__icon) {
margin-right: 0;
}
@include when(disabled) {
color: $-button-icon-disabled-color;
background: transparent;
}
}
@include edeep(icon) {
display: block;
margin-right: 6px;
font-size: $-button-icon-fs;
vertical-align: middle;
}
@include e(text) {
user-select: none;
white-space: nowrap;
}
}
@keyframes wd-rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,142 @@
/*
* @Author: weisheng
* @Date: 2024-03-15 11:36:12
* @LastEditTime: 2024-11-04 21:33:52
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-button\types.ts
* 记得注释
*/
import type { ExtractPropTypes, PropType } from 'vue'
import { baseProps, makeBooleanProp, makeStringProp } from '../common/props'
export type ButtonType = 'primary' | 'success' | 'info' | 'warning' | 'error' | 'default' | 'text' | 'icon'
export type ButtonSize = 'small' | 'medium' | 'large'
export type ButtonLang = 'zh_CN' | 'zh_TW' | 'en'
export type ButtonOpenType =
| 'feedback'
| 'share'
| 'getUserInfo'
| 'contact'
| 'getPhoneNumber'
| 'getRealtimePhoneNumber'
| 'launchApp'
| 'openSetting'
| 'chooseAvatar'
| 'getAuthorize'
| 'lifestyle'
| 'contactShare'
| 'openGroupProfile'
| 'openGuildProfile'
| 'openPublicProfile'
| 'shareMessageToFriend'
| 'addFriend'
| 'addColorSign'
| 'addGroupApp'
| 'addToFavorites'
| 'chooseAddress'
| 'chooseInvoiceTitle'
| 'login'
| 'subscribe'
| 'favorite'
| 'watchLater'
| 'openProfile'
| 'agreePrivacyAuthorization'
export type ButtonScope = 'phoneNumber' | 'userInfo'
export const buttonProps = {
...baseProps,
/**
* 幽灵按钮
*/
plain: makeBooleanProp(false),
/**
* 圆角按钮
*/
round: makeBooleanProp(true),
/**
* 禁用按钮
*/
disabled: makeBooleanProp(false),
/**
* 是否细边框
*/
hairline: makeBooleanProp(false),
/**
* 块状按钮
*/
block: makeBooleanProp(false),
/**
* 按钮类型可选值primary / success / info / warning / error / text / icon
*/
type: makeStringProp<ButtonType>('primary'),
/**
* 按钮尺寸可选值small / medium / large
*/
size: makeStringProp<ButtonSize>('medium'),
/**
* 图标类名
*/
icon: String,
/**
* 类名前缀用于使用自定义图标用法参考Icon组件
*/
classPrefix: makeStringProp('wd-icon'),
/**
* 加载中按钮
*/
loading: makeBooleanProp(false),
/**
* 加载图标颜色
*/
loadingColor: String,
/**
* 开放能力
*/
openType: String as PropType<ButtonOpenType>,
/**
* 指定是否阻止本节点的祖先节点出现点击态
*/
hoverStopPropagation: Boolean,
/**
* 指定返回用户信息的语言zh_CN 简体中文zh_TW 繁体中文en 英文
*/
lang: String as PropType<ButtonLang>,
/**
* 会话来源open-type="contact"时有效
*/
sessionFrom: String,
/**
* 会话内消息卡片标题open-type="contact"时有效
*/
sendMessageTitle: String,
/**
* 会话内消息卡片点击跳转小程序路径open-type="contact"时有效
*/
sendMessagePath: String,
/**
* 会话内消息卡片图片open-type="contact"时有效
*/
sendMessageImg: String,
/**
* 打开 APP 时,向 APP 传递的参数open-type=launchApp时有效
*/
appParameter: String,
/**
* 是否显示会话内消息卡片,设置此参数为 true用户进入客服会话会在右下角显示"可能要发送的小程序"提示用户点击后可以快速发送小程序消息open-type="contact"时有效
*/
showMessageCard: Boolean,
/**
* 按钮的唯一标识可用于设置隐私同意授权按钮的id
*/
buttonId: String,
/**
* 支付宝小程序,当 open-type 为 getAuthorize 时有效。
* 可选值:'phoneNumber' | 'userInfo'
*/
scope: String as PropType<ButtonScope>
}
export type ButtonProps = ExtractPropTypes<typeof buttonProps>

View File

@@ -0,0 +1,195 @@
<template>
<button
:id="buttonId"
:hover-class="`${disabled || loading ? '' : 'wd-button--active'}`"
:style="customStyle"
:class="[
'wd-button',
'is-' + type,
'is-' + size,
round ? 'is-round' : '',
hairline ? 'is-hairline' : '',
plain ? 'is-plain' : '',
disabled ? 'is-disabled' : '',
block ? 'is-block' : '',
loading ? 'is-loading' : '',
customClass
]"
:hover-start-time="hoverStartTime"
:hover-stay-time="hoverStayTime"
:open-type="disabled || loading ? undefined : openType"
:send-message-title="sendMessageTitle"
:send-message-path="sendMessagePath"
:send-message-img="sendMessageImg"
:app-parameter="appParameter"
:show-message-card="showMessageCard"
:session-from="sessionFrom"
:lang="lang"
:hover-stop-propagation="hoverStopPropagation"
:scope="scope"
@click="handleClick"
@getAuthorize="handleGetAuthorize"
@getuserinfo="handleGetuserinfo"
@contact="handleConcat"
@getphonenumber="handleGetphonenumber"
@getrealtimephonenumber="handleGetrealtimephonenumber"
@error="handleError"
@launchapp="handleLaunchapp"
@opensetting="handleOpensetting"
@chooseavatar="handleChooseavatar"
@agreeprivacyauthorization="handleAgreePrivacyAuthorization"
>
<view class="wd-button__content">
<view v-if="loading" class="wd-button__loading">
<view class="wd-button__loading-svg" :style="loadingStyle"></view>
</view>
<wd-icon v-else-if="icon" custom-class="wd-button__icon" :name="icon" :classPrefix="classPrefix"></wd-icon>
<view class="wd-button__text"><slot /></view>
</view>
</button>
</template>
<script lang="ts">
export default {
name: 'wd-button',
options: {
addGlobalClass: true,
virtualHost: true,
styleIsolation: 'shared'
}
}
</script>
<script lang="ts" setup>
import wdIcon from '../wd-icon/wd-icon.vue'
import { computed, watch } from 'vue'
import { ref } from 'vue'
import base64 from '../common/base64'
import { buttonProps } from './types'
const loadingIcon = (color = '#4D80F0', reverse = true) => {
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 42 42"><defs><linearGradient x1="100%" y1="0%" x2="0%" y2="0%" id="a"><stop stop-color="${
reverse ? color : '#fff'
}" offset="0%" stop-opacity="0"/><stop stop-color="${
reverse ? color : '#fff'
}" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path d="M21 1c11.046 0 20 8.954 20 20s-8.954 20-20 20S1 32.046 1 21 9.954 1 21 1zm0 7C13.82 8 8 13.82 8 21s5.82 13 13 13 13-5.82 13-13S28.18 8 21 8z" fill="${
reverse ? '#fff' : color
}"/><path d="M4.599 21c0 9.044 7.332 16.376 16.376 16.376 9.045 0 16.376-7.332 16.376-16.376" stroke="url(#a)" stroke-width="3.5" stroke-linecap="round"/></g></svg>`
}
const props = defineProps(buttonProps)
const emit = defineEmits([
'click',
'getuserinfo',
'contact',
'getphonenumber',
'getrealtimephonenumber',
'error',
'launchapp',
'opensetting',
'chooseavatar',
'agreeprivacyauthorization'
])
const hoverStartTime = ref<number>(20)
const hoverStayTime = ref<number>(70)
const loadingIconSvg = ref<string>('')
const loadingStyle = computed(() => {
return `background-image: url(${loadingIconSvg.value});`
})
watch(
() => props.loading,
() => {
buildLoadingSvg()
},
{ deep: true, immediate: true }
)
function handleClick(event: any) {
if (!props.disabled && !props.loading) {
emit('click', event)
}
}
/**
* 支付宝小程序授权
* @param event
*/
function handleGetAuthorize(event: any) {
if (props.scope === 'phoneNumber') {
handleGetphonenumber(event)
} else if (props.scope === 'userInfo') {
handleGetuserinfo(event)
}
}
function handleGetuserinfo(event: any) {
emit('getuserinfo', event.detail)
}
function handleConcat(event: any) {
emit('contact', event.detail)
}
function handleGetphonenumber(event: any) {
emit('getphonenumber', event.detail)
}
function handleGetrealtimephonenumber(event: any) {
emit('getrealtimephonenumber', event.detail)
}
function handleError(event: any) {
emit('error', event.detail)
}
function handleLaunchapp(event: any) {
emit('launchapp', event.detail)
}
function handleOpensetting(event: any) {
emit('opensetting', event.detail)
}
function handleChooseavatar(event: any) {
emit('chooseavatar', event.detail)
}
function handleAgreePrivacyAuthorization(event: any) {
emit('agreeprivacyauthorization', event.detail)
}
function buildLoadingSvg() {
const { loadingColor, type, plain } = props
let color = loadingColor
if (!color) {
switch (type) {
case 'primary':
color = '#4D80F0'
break
case 'success':
color = '#34d19d'
break
case 'info':
color = '#333'
break
case 'warning':
color = '#f0883a'
break
case 'error':
color = '#fa4350'
break
case 'default':
color = '#333'
break
}
}
const svg = loadingIcon(color, !plain)
loadingIconSvg.value = `"data:image/svg+xml;base64,${base64(svg)}"`
}
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>