119 lines
4.5 KiB
Vue
119 lines
4.5 KiB
Vue
<script setup lang="ts">
|
|
import { computed, ref } from "vue";
|
|
import { Button } from "@/components/ui/button";
|
|
import { RefreshCw } from "@lucide/vue";
|
|
import type { GeneratorParams } from "@/lib/dataGrid/dataGenerate";
|
|
import CommonOptions from "./CommonOptions.vue";
|
|
|
|
const props = defineProps<{ params: GeneratorParams }>();
|
|
|
|
const addressTypes = [
|
|
{ value: "line1", label: "第1行地址" },
|
|
{ value: "line2", label: "第2行地址" },
|
|
{ value: "full", label: "完整地址" },
|
|
];
|
|
|
|
const regions = [
|
|
{ value: "us", label: "美国" },
|
|
{ value: "uk", label: "英国" },
|
|
{ value: "cn", label: "中国 (English)" },
|
|
{ value: "jp", label: "日本 (English)" },
|
|
];
|
|
|
|
if (!props.params.addressType) props.params.addressType = "line1";
|
|
if (!props.params.regions) props.params.regions = ["us"];
|
|
|
|
function pick<T>(arr: T[]): T {
|
|
return arr[Math.floor(Math.random() * arr.length)];
|
|
}
|
|
|
|
function randInt(min: number, max: number): number {
|
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
}
|
|
|
|
const usStreets = ["Main St", "Oak Ave", "Elm Rd", "Park Blvd", "Lake Dr", "Hill St", "Washington Blvd", "2nd Ave", "3rd St", "Pine Ln"];
|
|
const ukStreets = ["Oxford Street", "Abbey Road", "Baker Street", "Piccadilly", "Downing Street", "Regent Street", "Bond Street"];
|
|
const cnStreets = ["No. 88, YuShuang Road", "No. 128, Nanjing West Road", "No. 56, RenMin Avenue", "No. 201, ZhongShan Road", "No. 77, ChangJiang Road"];
|
|
const jpStreets = ["1-1-1, Marunouchi", "2-3-1, Shibuya", "3-2-1, Ginza", "1-5-2, Shinjuku", "4-1-3, Umeda"];
|
|
|
|
const usApts = ["Apt #203", "Unit 5", "Suite 300", "#4B", "Floor 7"];
|
|
const ukApts = ["Flat 3", "Apartment 5B", "Studio 2", "Suite 12"];
|
|
const cnApts = ["Building A, Unit 301", "Room 202, Block B", "Unit 1105"];
|
|
const jpApts = ["Building #2, 3F", "Room 402", "Tower A, 15F"];
|
|
|
|
function toggleRegion(val: string) {
|
|
if (!props.params.regions) props.params.regions = [];
|
|
const idx = props.params.regions.indexOf(val);
|
|
if (idx >= 0) props.params.regions.splice(idx, 1);
|
|
else props.params.regions.push(val);
|
|
}
|
|
|
|
function generateAddress(type: string, region: string): string {
|
|
const num = randInt(1, 9999);
|
|
const streets: Record<string, string[]> = {
|
|
us: usStreets,
|
|
uk: ukStreets,
|
|
cn: cnStreets,
|
|
jp: jpStreets,
|
|
};
|
|
const apts: Record<string, string[]> = {
|
|
us: usApts,
|
|
uk: ukApts,
|
|
cn: cnApts,
|
|
jp: jpApts,
|
|
};
|
|
const list = streets[region] ?? usStreets;
|
|
const aptList = apts[region] ?? usApts;
|
|
if (type === "line1") {
|
|
if (region === "cn" || region === "jp") return pick(list);
|
|
return `${num} ${pick(list)}`;
|
|
}
|
|
if (type === "line2") return pick(aptList);
|
|
// full
|
|
if (region === "cn" || region === "jp") return `${randInt(1, 999)} ${pick(list)}, ${pick(aptList)}`;
|
|
return `${num} ${pick(list)}, ${pick(aptList)}`;
|
|
}
|
|
|
|
const previewKey = ref(0);
|
|
const previewVal = computed(() => {
|
|
void previewKey.value;
|
|
const regionsSelected = props.params.regions?.length ? props.params.regions : ["us"];
|
|
const region = pick(regionsSelected);
|
|
return generateAddress(props.params.addressType ?? "line1", region);
|
|
});
|
|
|
|
function refresh() {
|
|
previewKey.value++;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="space-y-3">
|
|
<div class="rounded-md border bg-muted/10 p-3">
|
|
<div class="text-xs text-muted-foreground mb-2">类型</div>
|
|
<div class="flex items-center gap-2 text-xs">
|
|
<button v-for="t in addressTypes" :key="t.value" type="button" class="px-2 py-1 rounded border text-xs" :class="(params.addressType || 'line1') === t.value ? 'bg-primary text-primary-foreground border-primary' : 'bg-background'" @click="params.addressType = t.value">{{ t.label }}</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rounded-md border bg-muted/10 p-3">
|
|
<div class="text-xs text-muted-foreground mb-2">地区</div>
|
|
<div class="flex flex-wrap gap-1.5">
|
|
<button v-for="r in regions" :key="r.value" type="button" class="px-2 py-1 rounded border text-xs" :class="(params.regions ?? []).includes(r.value) ? 'bg-primary text-primary-foreground border-primary' : 'bg-background'" @click="toggleRegion(r.value)">{{ r.label }}</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rounded-md border bg-muted/10 p-3">
|
|
<div class="flex items-center gap-2 text-xs">
|
|
<span class="text-muted-foreground shrink-0">预览</span>
|
|
<span :key="previewKey" class="font-mono text-sm">{{ previewVal }}</span>
|
|
<Button variant="ghost" size="icon" class="h-5 w-5 ml-auto" @click="refresh">
|
|
<RefreshCw class="h-3 w-3" />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<CommonOptions :params="params" />
|
|
</div>
|
|
</template>
|