Mars Developer 51f8d95bf9 first commit
2025-06-26 11:24:11 +08:00

416 lines
15 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="space-y-6">
<!-- 页面头部 -->
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900">创建订单</h1>
<p class="text-gray-600 mt-1">创建新的翻译订单</p>
</div>
<div class="flex space-x-3">
<button
@click="$router.back()"
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50"
>
返回
</button>
</div>
</div>
<!-- 订单表单 -->
<div class="bg-white shadow rounded-lg">
<form @submit.prevent="handleSubmit" class="p-6 space-y-6">
<!-- 客户信息 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">客户信息</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="clientName" class="block text-sm font-medium text-gray-700 mb-2">
客户姓名 *
</label>
<input
id="clientName"
v-model="orderForm.clientName"
type="text"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="请输入客户姓名"
/>
</div>
<div>
<label for="clientPhone" class="block text-sm font-medium text-gray-700 mb-2">
联系电话 *
</label>
<input
id="clientPhone"
v-model="orderForm.clientPhone"
type="tel"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="请输入联系电话"
/>
</div>
<div>
<label for="clientEmail" class="block text-sm font-medium text-gray-700 mb-2">
邮箱地址
</label>
<input
id="clientEmail"
v-model="orderForm.clientEmail"
type="email"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="请输入邮箱地址"
/>
</div>
<div>
<label for="clientCompany" class="block text-sm font-medium text-gray-700 mb-2">
公司名称
</label>
<input
id="clientCompany"
v-model="orderForm.clientCompany"
type="text"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="请输入公司名称"
/>
</div>
</div>
</div>
<!-- 翻译需求 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">翻译需求</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="sourceLanguage" class="block text-sm font-medium text-gray-700 mb-2">
源语言 *
</label>
<select
id="sourceLanguage"
v-model="orderForm.sourceLanguage"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="">请选择源语言</option>
<option value="zh">中文</option>
<option value="en">英文</option>
<option value="ja">日文</option>
<option value="ko">韩文</option>
<option value="fr">法文</option>
<option value="de">德文</option>
<option value="es">西班牙文</option>
<option value="ru">俄文</option>
</select>
</div>
<div>
<label for="targetLanguage" class="block text-sm font-medium text-gray-700 mb-2">
目标语言 *
</label>
<select
id="targetLanguage"
v-model="orderForm.targetLanguage"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="">请选择目标语言</option>
<option value="zh">中文</option>
<option value="en">英文</option>
<option value="ja">日文</option>
<option value="ko">韩文</option>
<option value="fr">法文</option>
<option value="de">德文</option>
<option value="es">西班牙文</option>
<option value="ru">俄文</option>
</select>
</div>
<div>
<label for="serviceType" class="block text-sm font-medium text-gray-700 mb-2">
服务类型 *
</label>
<select
id="serviceType"
v-model="orderForm.serviceType"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="">请选择服务类型</option>
<option value="document">文档翻译</option>
<option value="interpretation">口译服务</option>
<option value="localization">本地化</option>
<option value="proofreading">校对服务</option>
</select>
</div>
<div>
<label for="urgency" class="block text-sm font-medium text-gray-700 mb-2">
紧急程度 *
</label>
<select
id="urgency"
v-model="orderForm.urgency"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="normal">普通</option>
<option value="urgent">紧急</option>
<option value="rush">加急</option>
</select>
</div>
</div>
</div>
<!-- 项目详情 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">项目详情</h3>
<div class="space-y-6">
<div>
<label for="projectTitle" class="block text-sm font-medium text-gray-700 mb-2">
项目标题 *
</label>
<input
id="projectTitle"
v-model="orderForm.projectTitle"
type="text"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="请输入项目标题"
/>
</div>
<div>
<label for="projectDescription" class="block text-sm font-medium text-gray-700 mb-2">
项目描述 *
</label>
<textarea
id="projectDescription"
v-model="orderForm.projectDescription"
rows="4"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="请详细描述翻译需求、专业领域、特殊要求等"
></textarea>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="expectedDelivery" class="block text-sm font-medium text-gray-700 mb-2">
期望交付时间 *
</label>
<input
id="expectedDelivery"
v-model="orderForm.expectedDelivery"
type="datetime-local"
required
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
/>
</div>
<div>
<label for="budget" class="block text-sm font-medium text-gray-700 mb-2">
预算
</label>
<input
id="budget"
v-model.number="orderForm.budget"
type="number"
min="0"
step="0.01"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="请输入预算金额"
/>
</div>
</div>
</div>
</div>
<!-- 附件上传 -->
<div>
<h3 class="text-lg font-medium text-gray-900 mb-4">附件上传</h3>
<div class="border-2 border-dashed border-gray-300 rounded-lg p-6">
<div class="text-center">
<svg class="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" fill="none" viewBox="0 0 48 48">
<path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
<div class="mt-4">
<label for="file-upload" class="cursor-pointer">
<span class="mt-2 block text-sm font-medium text-gray-900">
点击上传文件或拖拽文件到此处
</span>
<input id="file-upload" name="file-upload" type="file" class="sr-only" multiple @change="handleFileUpload" />
</label>
<p class="mt-1 text-xs text-gray-500">
支持 PDF, DOC, DOCX, TXT 等格式单个文件最大 10MB
</p>
</div>
</div>
</div>
<!-- 已上传文件列表 -->
<div v-if="uploadedFiles.length > 0" class="mt-4">
<h4 class="text-sm font-medium text-gray-900 mb-2">已上传文件</h4>
<ul class="space-y-2">
<li v-for="(file, index) in uploadedFiles" :key="index" class="flex items-center justify-between p-2 bg-gray-50 rounded">
<span class="text-sm text-gray-700">{{ file.name }}</span>
<button @click="removeFile(index)" class="text-red-600 hover:text-red-800">
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</li>
</ul>
</div>
</div>
<!-- 备注信息 -->
<div>
<label for="notes" class="block text-sm font-medium text-gray-700 mb-2">
备注信息
</label>
<textarea
id="notes"
v-model="orderForm.notes"
rows="3"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="其他需要说明的信息"
></textarea>
</div>
<!-- 提交按钮 -->
<div class="flex justify-end space-x-3 pt-6 border-t border-gray-200">
<button
type="button"
@click="$router.back()"
class="px-6 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50"
>
取消
</button>
<button
type="submit"
:disabled="isSubmitting"
class="px-6 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
>
{{ isSubmitting ? '创建中...' : '创建订单' }}
</button>
</div>
</form>
</div>
</div>
</template>
<script setup>
// 页面元数据
definePageMeta({
middleware: 'auth'
})
// 页面标题
useHead({
title: '创建订单 - 翻译管理系统'
})
// 路由
const router = useRouter()
// 表单数据
const orderForm = ref({
clientName: '',
clientPhone: '',
clientEmail: '',
clientCompany: '',
sourceLanguage: '',
targetLanguage: '',
serviceType: '',
urgency: 'normal',
projectTitle: '',
projectDescription: '',
expectedDelivery: '',
budget: 0,
notes: ''
})
// 上传文件列表
const uploadedFiles = ref([])
// 提交状态
const isSubmitting = ref(false)
// 处理文件上传
const handleFileUpload = (event) => {
const files = Array.from(event.target.files)
files.forEach(file => {
if (file.size <= 10 * 1024 * 1024) { // 10MB限制
uploadedFiles.value.push(file)
} else {
alert(`文件 ${file.name} 超过10MB限制`)
}
})
}
// 移除文件
const removeFile = (index) => {
uploadedFiles.value.splice(index, 1)
}
// 处理表单提交
const handleSubmit = async () => {
try {
isSubmitting.value = true
// 基本验证
if (!orderForm.value.clientName || !orderForm.value.clientPhone ||
!orderForm.value.sourceLanguage || !orderForm.value.targetLanguage ||
!orderForm.value.serviceType || !orderForm.value.projectTitle ||
!orderForm.value.projectDescription || !orderForm.value.expectedDelivery) {
throw new Error('请填写所有必填字段')
}
// 语言验证
if (orderForm.value.sourceLanguage === orderForm.value.targetLanguage) {
throw new Error('源语言和目标语言不能相同')
}
// 时间验证
const deliveryTime = new Date(orderForm.value.expectedDelivery)
const now = new Date()
if (deliveryTime <= now) {
throw new Error('交付时间必须晚于当前时间')
}
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 1000))
// 创建订单数据
const newOrder = {
id: `order_${Date.now()}`,
...orderForm.value,
files: uploadedFiles.value.map(file => ({
name: file.name,
size: file.size,
type: file.type
})),
status: 'pending',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
}
console.log('创建订单:', newOrder)
// 显示成功消息
alert('订单创建成功')
// 返回订单列表页面
router.push('/orders')
} catch (error) {
alert(error.message || '创建订单失败,请重试')
} finally {
isSubmitting.value = false
}
}
</script>