From e661e138338680dbe34bb7c358936c26017ac7ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=96=87=E5=B3=B0?= Date: Mon, 13 Apr 2026 15:32:34 +0800 Subject: [PATCH] up --- frontend/ops_vue_js/src/i18n/en.json | 2 +- frontend/ops_vue_js/src/i18n/zh-CN.json | 2 +- .../src/views/purchase/addorder.vue | 414 ++++++++++-------- 3 files changed, 244 insertions(+), 174 deletions(-) diff --git a/frontend/ops_vue_js/src/i18n/en.json b/frontend/ops_vue_js/src/i18n/en.json index cd0a3ac..66a09ce 100644 --- a/frontend/ops_vue_js/src/i18n/en.json +++ b/frontend/ops_vue_js/src/i18n/en.json @@ -81,7 +81,7 @@ "order_info": "Order Information", "title": "Title", "input_title": "Enter order title", - "remarks": "Remarks", + "remarks": "Usage Remarks", "photo_remarks": "Photos Remarks", "remarks_text": "Enter text notes", "purchase_channel": "Purchase Channel", diff --git a/frontend/ops_vue_js/src/i18n/zh-CN.json b/frontend/ops_vue_js/src/i18n/zh-CN.json index 06f33ed..7313d69 100644 --- a/frontend/ops_vue_js/src/i18n/zh-CN.json +++ b/frontend/ops_vue_js/src/i18n/zh-CN.json @@ -81,7 +81,7 @@ "order_info": "订单信息", "title": "标题", "input_title": "输入订单标题", - "remarks": "备注", + "remarks": "用途备注", "photo_remarks": "图片备注", "remarks_text": "输入文字备注", "purchase_channel": "采购途径", diff --git a/frontend/ops_vue_js/src/views/purchase/addorder.vue b/frontend/ops_vue_js/src/views/purchase/addorder.vue index 7e0f548..febd9d9 100644 --- a/frontend/ops_vue_js/src/views/purchase/addorder.vue +++ b/frontend/ops_vue_js/src/views/purchase/addorder.vue @@ -22,93 +22,98 @@ */ // ==================== 依赖导入 ==================== -import { reactive, ref, computed, watch } from 'vue' -import { useI18n } from 'vue-i18n' -import { useToastStore } from '@/stores/toast' -import { usePageTitle } from '@/composables/usePageTitle' -import { useValidation } from '@/composables' -import { purchaseApi } from '@/api/purchase' +import { reactive, ref, computed, watch } from "vue"; +import { useI18n } from "vue-i18n"; +import { useToastStore } from "@/stores/toast"; +import { usePageTitle } from "@/composables/usePageTitle"; +import { useValidation } from "@/composables"; +import { purchaseApi } from "@/api/purchase"; // 组件导入 -import tagadder from '@/components/tagadder.vue' // 标签添加组件 -import datePicker from '@/components/datePicker.vue' // 日期选择组件 -import useDropzone from '@/components/useDropzone.vue' // 文件上传组件(图片) +import tagadder from "@/components/tagadder.vue"; // 标签添加组件 +import datePicker from "@/components/datePicker.vue"; // 日期选择组件 +import useDropzone from "@/components/useDropzone.vue"; // 文件上传组件(图片) // ==================== 页面初始化 ==================== // 设置页面标题,使用 i18n key -usePageTitle('purchase.add_part') +usePageTitle("purchase.add_part"); // 获取国际化实例,用于多语言文本 -const { t, locale } = useI18n() +const { t, locale } = useI18n(); // Toast 消息提示 -const toast = useToastStore() +const toast = useToastStore(); // 表单验证工具 -const { validate, errors, clearErrors } = useValidation() +const { validate, errors, clearErrors } = useValidation(); // ==================== 常量定义 ==================== /** * 备注文字最大长度限制 * 超过此长度将显示字符计数警告 */ -const textMaxLen = 256 +const textMaxLen = 256; /** * 文件上传组件的引用 * 用于获取已上传的图片列表 */ -const photosRef = ref(null) +const photosRef = ref(null); /** * 货币类型选项 * key: 数据库中存储的值 * value: 显示的货币符号 */ -const currencyOptions = { 1: 'CNY', 2: 'MOP', 3: 'HKD', 4: 'USD' } +const currencyOptions = { 1: "CNY", 2: "MOP", 3: "HKD", 4: "USD" }; /** * 货币类型对应的国旗图标路径 */ -const currencyFlags = { 1: '/static/flags/cn.svg', 2: '/static/flags/mo.svg', 3: '/static/flags/hk.svg', 4: '/static/flags/us.svg' } +const currencyFlags = { + 1: "/static/flags/cn.svg", + 2: "/static/flags/mo.svg", + 3: "/static/flags/hk.svg", + 4: "/static/flags/us.svg", +}; // ==================== 费用类型映射 ==================== // 费用类型:单价 / 运费 const costType = computed(() => ({ - 1: t('cost_type.unit_price'), // 单价 - 2: t('cost_type.freight'), // 运费 -})) + 1: t("cost_type.unit_price"), // 单价 + 2: t("cost_type.freight"), // 运费 +})); // ==================== 订单状态映射 ==================== // 订单的各种状态选项 const orderStatus = computed(() => ({ - 1: t('order_status.pending_order'), // 待下单 - 2: t('order_status.order_placed'), // 已下单 - 3: t('order_status.in_transit'), // 运输中 - 4: t('order_status.completed'), // 已完成 - 5: t('order_status.refund_requested'), // 退款中 - 6: t('order_status.returning'), // 退货中 - 7: t('order_status.refunded'), // 已退款 - 8: t('order_status.lost_package'), // 丢件 -})) + 1: t("order_status.pending_order"), // 待下单 + 2: t("order_status.order_placed"), // 已下单 + 3: t("order_status.in_transit"), // 运输中 + 4: t("order_status.completed"), // 已完成 + 5: t("order_status.refund_requested"), // 退款中 + 6: t("order_status.returning"), // 退货中 + 7: t("order_status.refunded"), // 已退款 + 8: t("order_status.lost_package"), // 丢件 +})); // ==================== 费用明细管理 ==================== /** * 已添加的费用明细列表 * 每项包含:类型、数量、单价、总价、货币类型 */ -const costEntries = reactive([]) +const costEntries = reactive([]); /** * 新费用条目的临时数据 * 用户填写完表单后点击"添加"按钮加入 costEntries */ const newCost = reactive({ - type: '1', // 费用类型:默认"单价" - int: 1, // 数量:默认1 - cost: 0, // 单价:默认0 - currencyType: '1', // 货币类型:默认人民币 -}) + type: "1", // 费用类型:默认"单价" + int: 1, // 数量:默认1 + cost: 0, // 单价:默认0 + currencyType: "1", // 货币类型:默认人民币 +}); // ==================== 表单数据 ==================== /** @@ -116,44 +121,44 @@ const newCost = reactive({ * 包含所有需要提交的字段 */ const form = reactive({ - title: '', // 订单标题(必填) - remark: '', // 备注说明 - photos: [], // 图片列表(上传后由 dropzone 填充) - link: '', // 采购链接 - partname: '', // 配件名称 - styles: '', // 款式标签 - costs: [], // 费用明细(提交前由 costEntries 转换) - tracking_number: '', // 快递单号 - updatetime: '', // 更新时间 - order_status: '1', // 订单状态(默认待下单) -}) + title: "", // 订单标题(必填) + remark: "", // 备注说明 + photos: [], // 图片列表(上传后由 dropzone 填充) + link: "", // 采购链接 + partname: "", // 配件名称 + styles: "", // 款式标签 + costs: [], // 费用明细(提交前由 costEntries 转换) + tracking_number: "", // 快递单号 + updatetime: "", // 更新时间 + order_status: "1", // 订单状态(默认待下单) +}); /** * 计算新费用条目的总价 * 总价 = 数量 × 单价,保留2位小数 */ const newCostTotal = computed(() => - parseFloat((newCost.int * newCost.cost).toFixed(2)) -) + parseFloat((newCost.int * newCost.cost).toFixed(2)), +); /** * 添加一条费用明细到列表 * 条件:单价必须大于0 */ function addCostEntry() { - if (newCost.cost <= 0) return + if (newCost.cost <= 0) return; costEntries.push({ type: newCost.type, int: newCost.int, cost: newCost.cost, costt: newCostTotal.value, currencytype: newCost.currencyType, - }) + }); // 添加后重置表单,以便继续添加下一条 - newCost.type = '1' - newCost.int = 1 - newCost.cost = 0 - newCost.currencyType = '1' + newCost.type = "1"; + newCost.int = 1; + newCost.cost = 0; + newCost.currencyType = "1"; } /** @@ -161,25 +166,26 @@ function addCostEntry() { * @param {number} index - 要删除的条目索引 */ function removeCostEntry(index) { - costEntries.splice(index, 1) + costEntries.splice(index, 1); } /** * 监听单价输入,自动保留2位小数 * 防止用户输入如 10.999 这样的值 */ -watch(() => newCost.cost, (val) => { - const fixed = parseFloat(val).toFixed(2) - if (parseFloat(fixed) !== val) newCost.cost = parseFloat(fixed) -}) - - +watch( + () => newCost.cost, + (val) => { + const fixed = parseFloat(val).toFixed(2); + if (parseFloat(fixed) !== val) newCost.cost = parseFloat(fixed); + }, +); /** * 提交按钮 loading 状态 * 防止重复提交 */ -const loading = ref(false) +const loading = ref(false); // ==================== 表单提交 ==================== /** @@ -191,44 +197,44 @@ const loading = ref(false) */ async function handleSubmit() { // 清空之前的验证错误 - clearErrors() + clearErrors(); // 验证标题是否填写 - const err = validate('title', form.title, t('purchase_addorder.title')) - if (!err) return + const err = validate("title", form.title, t("purchase_addorder.title")); + if (!err) return; // 从 dropzone 组件获取已上传的图片文件名 - form.photos = [] + form.photos = []; if (photosRef.value?.has_some_files) { - const result = photosRef.value.get_some_files() - form.photos = result.map(f => f.name) + const result = photosRef.value.get_some_files(); + form.photos = result.map((f) => f.name); } // 将费用明细转换为提交格式 // 注意:金额需要从"元"转为"分"(乘以100)存储 - form.costs = costEntries.map(h => ({ + form.costs = costEntries.map((h) => ({ ...h, cost: Math.round(h.cost * 100), costt: Math.round(h.costt * 100), - })) + })); // 开始 loading - loading.value = true + loading.value = true; try { // 调用采购 API 添加订单 - const { errCode } = await purchaseApi.addOrder(form) + const { errCode } = await purchaseApi.addOrder(form); if (errCode === 0) { // 保存成功,显示成功提示 - toast.success(t('message.save_ok')) + toast.success(t("message.save_ok")); } else { // 服务器错误,显示错误提示 - toast.error(t('message.server_error')) + toast.error(t("message.server_error")); } } catch { // 错误已被 HTTP 拦截器处理,此处无需额外处理 } finally { // 无论成功失败,都要关闭 loading - loading.value = false + loading.value = false; } } @@ -237,37 +243,50 @@ async function handleSubmit() {
-
- +
-

{{ t('purchase_addorder.order_info') }}

+

+ {{ t("purchase_addorder.order_info") }} +

-
-