mirror of
https://github.com/iLay1678/i-tools.git
synced 2025-07-03 10:42:15 +08:00
添加挪车码功能
This commit is contained in:
parent
09707324e9
commit
4eba3afed8
9
package-lock.json
generated
9
package-lock.json
generated
@ -13,6 +13,7 @@
|
||||
"clipboard": "^2.0.11",
|
||||
"crypto-es": "^2.1.0",
|
||||
"nuxt": "^3.14.1592",
|
||||
"qrcode.vue": "^3.6.0",
|
||||
"vue": "latest",
|
||||
"vue-router": "latest"
|
||||
},
|
||||
@ -7524,6 +7525,14 @@
|
||||
"resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz",
|
||||
"integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q=="
|
||||
},
|
||||
"node_modules/qrcode.vue": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-3.6.0.tgz",
|
||||
"integrity": "sha512-vQcl2fyHYHMjDO1GguCldJxepq2izQjBkDEEu9NENgfVKP6mv/e2SU62WbqYHGwTgWXLhxZ1NCD1dAZKHQq1fg==",
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
|
@ -17,6 +17,7 @@
|
||||
"clipboard": "^2.0.11",
|
||||
"crypto-es": "^2.1.0",
|
||||
"nuxt": "^3.14.1592",
|
||||
"qrcode.vue": "^3.6.0",
|
||||
"vue": "latest",
|
||||
"vue-router": "latest"
|
||||
},
|
||||
|
@ -39,11 +39,18 @@ const tools = [
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '挪车码牌生成',
|
||||
description: '生成挪车码牌,方便他人联系车主',
|
||||
path: '/move-car-code',
|
||||
available: true
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '敬请期待',
|
||||
description: '更多工具正在开发中...',
|
||||
path: '',
|
||||
available: false
|
||||
}
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
|
85
pages/move-car-code/index.vue
Normal file
85
pages/move-car-code/index.vue
Normal file
@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<head>
|
||||
<title>挪车码牌生成</title>
|
||||
</head>
|
||||
<div class="p-4">
|
||||
<div class="mx-auto w-full max-w-3xl bg-white shadow-lg rounded-lg p-8 mb-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-bold text-gray-800">挪车码牌生成</h1>
|
||||
</div>
|
||||
<a-form :model="form" :rules="rules" ref="formRef">
|
||||
<a-form-item name="plateNumber" label="车牌号">
|
||||
<a-input v-model:value="form.plateNumber" placeholder="请输入车牌号" />
|
||||
</a-form-item>
|
||||
<a-form-item name="phoneNumber" label="手机号">
|
||||
<a-input v-model:value="form.phoneNumber" placeholder="请输入手机号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="是否为新能源车">
|
||||
<a-checkbox v-model:checked="form.newEnergy">是</a-checkbox>
|
||||
</a-form-item>
|
||||
<a-form-item label="微信推送设置">
|
||||
<a-input-group compact>
|
||||
<a-input style="width: 50%" v-model:value="form.token" placeholder="请输入 Token" />
|
||||
<a-input style="width: 50%" v-model:value="form.uid" placeholder="请输入 UID" />
|
||||
</a-input-group>
|
||||
<a-typography-link href="https://wxpusher.zjiecode.com/docs/#/" target="_blank">查看文档</a-typography-link>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" @click="handleSubmit">生成挪车码牌</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
<div v-if="generatedUrl" class="w-full max-w-3xl bg-white shadow-lg rounded-lg p-8 text-center">
|
||||
<div class="prose prose-sm max-w-none">
|
||||
<h2 class="text-xl font-bold mb-4">生成的挪车码牌链接</h2>
|
||||
<a-typography-paragraph copyable>
|
||||
<a :href="generatedUrl" target="_blank">{{ generatedUrl }}</a>
|
||||
</a-typography-paragraph>
|
||||
<div class="flex justify-center">
|
||||
<qrcode-vue :value="generatedUrl" :size="200"></qrcode-vue>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
|
||||
const form = ref({
|
||||
plateNumber: '',
|
||||
phoneNumber: '',
|
||||
token: '',
|
||||
uid: '',
|
||||
newEnergy: false
|
||||
})
|
||||
const generatedUrl = ref('')
|
||||
const formRef = ref(null)
|
||||
|
||||
const rules = {
|
||||
plateNumber: [{ required: true, message: '请输入车牌号' }],
|
||||
phoneNumber: [
|
||||
{ required: true, message: '请输入手机号' },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入有效的手机号' }
|
||||
]
|
||||
}
|
||||
|
||||
const handleSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
const url = new URL(window.location.origin + '/move-car-display')
|
||||
url.searchParams.append('plateNumber', form.value.plateNumber)
|
||||
url.searchParams.append('phoneNumber', form.value.phoneNumber)
|
||||
if (form.value.token) url.searchParams.append('token', form.value.token)
|
||||
if (form.value.uid) url.searchParams.append('uid', form.value.uid)
|
||||
if (form.value.newEnergy) url.searchParams.append('new', 'true')
|
||||
generatedUrl.value = url.toString()
|
||||
}).catch(error => {
|
||||
message.warn('请填写完整信息')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
195
pages/move-car-display/index.vue
Normal file
195
pages/move-car-display/index.vue
Normal file
@ -0,0 +1,195 @@
|
||||
<template>
|
||||
|
||||
<head>
|
||||
<title>快点挪车-信息</title>
|
||||
</head>
|
||||
<div v-if="loading" class="loading-overlay">
|
||||
<div class="loading-container">
|
||||
<div class="loading-wave">
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
<div class="loading-text">加载中...</div>
|
||||
</div>
|
||||
</div>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="car" :class="{ 'new-energy': newEnergy }">
|
||||
<span class="car-province">{{ plateNumber.charAt(0) }}</span><span class="car-letter">{{
|
||||
plateNumber.charAt(1) }}</span><span class="car-dot">•</span><span class="car-number">{{
|
||||
plateNumber.slice(2) }}</span>
|
||||
</div>
|
||||
<div id="cardContainer">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h1 class="card-title">挪车信息</h1>
|
||||
<h2 class="card-text">临时停靠,请多关照</h2>
|
||||
<p class="card-text">车牌号: {{ plateNumber }}</p>
|
||||
<p class="card-text">联系电话: {{ phoneNumber }}</p>
|
||||
<button v-if="uid && token" type="button" class="btn btn-success"
|
||||
@click="notifyOwner">通知车主</button>
|
||||
<button type="button" class="btn btn-primary" @click="callNumber">一键呼叫</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue'
|
||||
definePageMeta({
|
||||
layout: false,
|
||||
})
|
||||
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
||||
const plateNumber = ref('')
|
||||
const phoneNumber = ref('')
|
||||
const token = ref('')
|
||||
const uid = ref('')
|
||||
const newEnergy = ref(false)
|
||||
const loading = ref(true)
|
||||
const checkPageLoaded = () => {
|
||||
if (document.readyState === 'complete') {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
// 检查当前页面状态
|
||||
if (document.readyState === 'complete') {
|
||||
loading.value = false
|
||||
} else {
|
||||
// 添加页面加载完成事件监听
|
||||
window.addEventListener('load', checkPageLoaded)
|
||||
}
|
||||
const urlParams = new URLSearchParams(window.location.search)
|
||||
plateNumber.value = urlParams.get('plateNumber') || ''
|
||||
phoneNumber.value = urlParams.get('phoneNumber') || ''
|
||||
token.value = urlParams.get('token') || ''
|
||||
uid.value = urlParams.get('uid') || ''
|
||||
newEnergy.value = urlParams.get('new') === 'true'
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
// 清理事件监听
|
||||
window.removeEventListener('load', checkPageLoaded)
|
||||
})
|
||||
const notifyOwner = () => {
|
||||
const currentTime = new Date().getTime()
|
||||
const lastNotifyTime = localStorage.getItem('lastNotifyTime')
|
||||
const timeDifference = (currentTime - lastNotifyTime) / 1000
|
||||
|
||||
if (lastNotifyTime && timeDifference < 60) {
|
||||
message.warning('您已发送过通知,请1分钟后再次尝试。')
|
||||
return
|
||||
}
|
||||
|
||||
fetch('https://wxpusher.zjiecode.com/api/send/message', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
appToken: token.value,
|
||||
content: '您好,有人需要您挪车,请及时处理。',
|
||||
contentType: 1,
|
||||
uids: [uid.value],
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.code === 1000) {
|
||||
message.success('通知已发送!')
|
||||
localStorage.setItem('lastNotifyTime', currentTime)
|
||||
} else {
|
||||
message.error('通知发送失败,请稍后重试。')
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error sending notification:', error)
|
||||
message.error('通知发送出错,请检查网络连接。')
|
||||
})
|
||||
}
|
||||
|
||||
const callNumber = () => {
|
||||
window.location.href = 'tel:' + phoneNumber.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 24px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background-color: #38b000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #4b5cc4;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.car {
|
||||
color: #fff;
|
||||
background-color: #4b5cc4;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #fff;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
box-shadow: 0 0 2px 4px #4b5cc4;
|
||||
width: 100%;
|
||||
margin: 15px auto;
|
||||
font-size: 40px;
|
||||
letter-spacing: 5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.car.new-energy {
|
||||
background-color: #38b000;
|
||||
box-shadow: 0 0 2px 4px #38b000;
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user