refactor: refactor code structure and improve demo page (#4389)

* feat: captcha example

* fix: fix lint errors

* chore: event handling and methods

* chore: add accessibility features ARIA labels and roles

* refactor: refactor code structure and improve captcha demo page

* feat: add captcha internationalization

* chore: 适配时间戳国际化展示

---------

Co-authored-by: vince <vince292007@gmail.com>
This commit is contained in:
Squall2017
2024-09-14 09:53:06 +08:00
committed by GitHub
parent 10b90eae5d
commit 5ba3a9dec2
10 changed files with 460 additions and 158 deletions

View File

@@ -81,7 +81,27 @@
"custom": "Custom Component"
},
"captcha": {
"title": "Captcha"
"title": "Captcha",
"captchaCardTitle": "Please complete the security verification",
"pageDescription": "Verify user identity by clicking on specific locations in the image.",
"pageTitle": "Captcha Component Example",
"basic": "Basic Usage",
"titlePlaceholder": "Captcha Title Text",
"captchaImageUrlPlaceholder": "Captcha Image (supports img tag src attribute value)",
"hintImage": "Hint Image",
"hintText": "Hint Text",
"hintImagePlaceholder": "Hint Image (supports img tag src attribute value)",
"hintTextPlaceholder": "Hint Text",
"showConfirm": "Show Confirm",
"hideConfirm": "Hide Confirm",
"widthPlaceholder": "Captcha Image Width Default 300px",
"heightPlaceholder": "Captcha Image Height Default 220px",
"paddingXPlaceholder": "Horizontal Padding Default 12px",
"paddingYPlaceholder": "Vertical Padding Default 16px",
"index": "Index:",
"timestamp": "Timestamp:",
"x": "x:",
"y": "y:"
}
}
}

View File

@@ -81,7 +81,27 @@
"custom": "自定义组件"
},
"captcha": {
"title": "验证码"
"title": "验证码",
"captchaCardTitle": "请完成安全验证",
"pageDescription": "通过点击图片中的特定位置来验证用户身份。",
"pageTitle": "验证码组件示例",
"basic": "基本使用",
"titlePlaceholder": "验证码标题文案",
"captchaImageUrlPlaceholder": "验证码图片支持img标签src属性值",
"hintImage": "提示图片",
"hintText": "提示文本",
"hintImagePlaceholder": "提示图片支持img标签src属性值",
"hintTextPlaceholder": "提示文本",
"showConfirm": "展示确认",
"hideConfirm": "隐藏确认",
"widthPlaceholder": "验证码图片宽度 默认300px",
"heightPlaceholder": "验证码图片高度 默认220px",
"paddingXPlaceholder": "水平内边距 默认12px",
"paddingYPlaceholder": "垂直内边距 默认16px",
"index": "索引:",
"timestamp": "时间戳:",
"x": "x",
"y": "y"
}
}
}

View File

@@ -1,45 +1,177 @@
<script lang="ts" setup>
import type { CaptchaPoint } from '@vben/common-ui';
import { ref } from 'vue';
import { reactive, ref } from 'vue';
import { Page, PointSelectionCaptcha } from '@vben/common-ui';
import { Card } from 'ant-design-vue';
import { Card, Input, InputNumber, message, Switch } from 'ant-design-vue';
import { $t } from '#/locales';
import { captchaImage, hintImage } from './base64';
const selectedPoints = ref<CaptchaPoint[]>([]);
const params = reactive({
captchaImage,
captchaImageUrl: '',
height: undefined,
hintImage,
hintImageUrl: '',
hintText: '唇,燕,碴,找',
paddingX: undefined,
paddingY: undefined,
showConfirm: true,
showHintImage: true,
title: '',
width: undefined,
});
const handleConfirm = (points: CaptchaPoint[], clear: () => void) => {
selectedPoints.value = points;
message.success({
content: `captcha points: ${JSON.stringify(points)}`,
});
clear();
selectedPoints.value = [];
};
const handleRefresh = () => {
selectedPoints.value = [];
};
const handleClick = (point: CaptchaPoint) => {
selectedPoints.value.push(point);
};
</script>
<template>
<Page
description="通过点击图片中的特定位置来验证用户身份。"
title="验证码组件示例"
:description="$t('page.examples.captcha.pageDescription')"
:title="$t('page.examples.captcha.pageTitle')"
>
<Card class="mb-4" title="基本使用">
<PointSelectionCaptcha
:captcha-image="captchaImage"
:hint-image="hintImage"
class="float-left"
@confirm="handleConfirm"
@refresh="handleRefresh"
/>
<div class="float-left p-5">
<div v-for="point in selectedPoints" :key="point.i" class="flex">
<span class="mr-3 w-16">索引{{ point.i }}</span>
<span class="mr-3 w-44">时间戳{{ point.t }}</span>
<span class="mr-3 w-16">x{{ point.x }}</span>
<span class="mr-3 w-16">y{{ point.y }}</span>
<Card :title="$t('page.examples.captcha.basic')" class="mb-4">
<div class="mb-3 flex items-center justify-start">
<Input
v-model:value="params.title"
:placeholder="$t('page.examples.captcha.titlePlaceholder')"
class="w-64"
/>
<Input
v-model:value="params.captchaImageUrl"
:placeholder="$t('page.examples.captcha.captchaImageUrlPlaceholder')"
class="ml-8 w-64"
/>
<div class="ml-8 flex w-96 items-center">
<Switch
v-model:checked="params.showHintImage"
:checked-children="$t('page.examples.captcha.hintImage')"
:un-checked-children="$t('page.examples.captcha.hintText')"
class="mr-4 w-40"
/>
<Input
v-show="params.showHintImage"
v-model:value="params.hintImageUrl"
:placeholder="$t('page.examples.captcha.hintImagePlaceholder')"
/>
<Input
v-show="!params.showHintImage"
v-model:value="params.hintText"
:placeholder="$t('page.examples.captcha.hintTextPlaceholder')"
/>
</div>
<Switch
v-model:checked="params.showConfirm"
:checked-children="$t('page.examples.captcha.showConfirm')"
:un-checked-children="$t('page.examples.captcha.hideConfirm')"
class="ml-8 w-28"
/>
</div>
<div class="mb-3 flex items-center justify-start">
<div>
<InputNumber
v-model:value="params.width"
:min="1"
:placeholder="$t('page.examples.captcha.widthPlaceholder')"
:precision="0"
:step="1"
class="w-64"
>
<template #addonAfter>px</template>
</InputNumber>
</div>
<div class="ml-8">
<InputNumber
v-model:value="params.height"
:min="1"
:placeholder="$t('page.examples.captcha.heightPlaceholder')"
:precision="0"
:step="1"
class="w-64"
>
<template #addonAfter>px</template>
</InputNumber>
</div>
<div class="ml-8">
<InputNumber
v-model:value="params.paddingX"
:min="1"
:placeholder="$t('page.examples.captcha.paddingXPlaceholder')"
:precision="0"
:step="1"
class="w-64"
>
<template #addonAfter>px</template>
</InputNumber>
</div>
<div class="ml-8">
<InputNumber
v-model:value="params.paddingY"
:min="1"
:placeholder="$t('page.examples.captcha.paddingYPlaceholder')"
:precision="0"
:step="1"
class="w-64"
>
<template #addonAfter>px</template>
</InputNumber>
</div>
</div>
<PointSelectionCaptcha
:captcha-image="params.captchaImageUrl || params.captchaImage"
:height="params.height || 220"
:hint-image="
params.showHintImage ? params.hintImageUrl || params.hintImage : ''
"
:hint-text="params.hintText"
:padding-x="params.paddingX"
:padding-y="params.paddingY"
:show-confirm="params.showConfirm"
:width="params.width || 300"
class="float-left"
@click="handleClick"
@confirm="handleConfirm"
@refresh="handleRefresh"
>
<template #title>
{{ params.title || $t('page.examples.captcha.captchaCardTitle') }}
</template>
</PointSelectionCaptcha>
<ol class="float-left p-5">
<li v-for="point in selectedPoints" :key="point.i" class="flex">
<span class="mr-3 w-16">{{
$t('page.examples.captcha.index') + point.i
}}</span>
<span class="mr-3 w-52">{{
$t('page.examples.captcha.timestamp') + point.t
}}</span>
<span class="mr-3 w-16">{{
$t('page.examples.captcha.x') + point.x
}}</span>
<span class="mr-3 w-16">{{
$t('page.examples.captcha.y') + point.y
}}</span>
</li>
</ol>
</Card>
</Page>
</template>