up
This commit is contained in:
@@ -13,5 +13,5 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"lastUpdated": 1776148343594
|
"lastUpdated": 1776153171221
|
||||||
}
|
}
|
||||||
@@ -317,6 +317,7 @@ func ApiPurchase(r *gin.RouterGroup) {
|
|||||||
|
|
||||||
type From_purchase_getorders struct {
|
type From_purchase_getorders struct {
|
||||||
Search string
|
Search string
|
||||||
|
Status string
|
||||||
Entries int
|
Entries int
|
||||||
Page int
|
Page int
|
||||||
}
|
}
|
||||||
@@ -336,14 +337,20 @@ func ApiPurchase(r *gin.RouterGroup) {
|
|||||||
|
|
||||||
if is_data_ok {
|
if is_data_ok {
|
||||||
|
|
||||||
//读取有多少条目
|
//读取有多少条目
|
||||||
var count int64
|
var count int64
|
||||||
models.DB.Model(TabPurchaseOrder{}).Count(&count)
|
query := models.DB.Model(TabPurchaseOrder{})
|
||||||
//fmt.Println(count)
|
if jsondata.Search != "" {
|
||||||
|
query = query.Where("title LIKE ?", "%"+jsondata.Search+"%")
|
||||||
|
}
|
||||||
|
if jsondata.Status != "" {
|
||||||
|
query = query.Where("order_status = ?", jsondata.Status)
|
||||||
|
}
|
||||||
|
query.Count(&count)
|
||||||
|
|
||||||
//读取条目
|
//读取条目
|
||||||
var getorders []TabPurchaseOrder
|
var getorders []TabPurchaseOrder
|
||||||
models.DB.Order("created_at DESC").Offset(jsondata.Entries * (jsondata.Page - 1)).Limit(jsondata.Entries).Find(&getorders)
|
query.Order("created_at DESC").Offset(jsondata.Entries * (jsondata.Page - 1)).Limit(jsondata.Entries).Find(&getorders)
|
||||||
|
|
||||||
ReturnJson(ctx, "apiOK", map[string]interface{}{
|
ReturnJson(ctx, "apiOK", map[string]interface{}{
|
||||||
"all_count": count,
|
"all_count": count,
|
||||||
@@ -611,4 +618,39 @@ func ApiPurchase(r *gin.RouterGroup) {
|
|||||||
ReturnJson(ctx, "apiOK", nil)
|
ReturnJson(ctx, "apiOK", nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 删除订单
|
||||||
|
r.POST("/deleteorder", func(ctx *gin.Context) {
|
||||||
|
isAuth, _, data := AuthenticationAuthority(ctx)
|
||||||
|
if !isAuth {
|
||||||
|
ReturnJson(ctx, "userCookieError", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type FromDeleteOrder struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
}
|
||||||
|
var from FromDeleteOrder
|
||||||
|
if err := decodeJSON(data, &from); err != nil || from.ID == 0 {
|
||||||
|
ReturnJson(ctx, "jsonErr", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var order TabPurchaseOrder
|
||||||
|
if err := models.DB.Where("id = ?", from.ID).First(&order).Error; err != nil {
|
||||||
|
ReturnJson(ctx, "order_not_found", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关联删除(硬删,不保留)
|
||||||
|
models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseCosts{})
|
||||||
|
models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseFileBind{})
|
||||||
|
models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseCommit{})
|
||||||
|
models.DB.Where("order_id = ?", from.ID).Delete(&TabPurchaseLog{})
|
||||||
|
|
||||||
|
// 软删除订单本身
|
||||||
|
models.DB.Delete(&order)
|
||||||
|
|
||||||
|
ReturnJson(ctx, "apiOK", nil)
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,4 +25,9 @@ export const purchaseApi = {
|
|||||||
updateOrder(id, data) {
|
updateOrder(id, data) {
|
||||||
return api.post('/purchase/updateorder', { id, ...data })
|
return api.post('/purchase/updateorder', { id, ...data })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** 删除订单 */
|
||||||
|
deleteOrder(id) {
|
||||||
|
return api.post('/purchase/deleteorder', { id })
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<script setup>
|
||||||
|
/**
|
||||||
|
* ConfirmDialog —— 通用确认弹窗
|
||||||
|
*
|
||||||
|
* 使用方式:
|
||||||
|
* const ok = await confirmDialog({
|
||||||
|
* title: "提示标题",
|
||||||
|
* message: "确认要删除吗?",
|
||||||
|
* confirmText: "删除",
|
||||||
|
* cancelText: "取消",
|
||||||
|
* danger: true, // 红色确认按钮
|
||||||
|
* })
|
||||||
|
* if (ok) { ... }
|
||||||
|
*
|
||||||
|
* 或者作为组件使用 v-model:
|
||||||
|
* <ConfirmDialog v-model="show" @confirm="..." @cancel="..." />
|
||||||
|
*/
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
confirmText: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
danger: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue", "confirm", "cancel"]);
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
emit("update:modelValue", false);
|
||||||
|
emit("cancel");
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirm() {
|
||||||
|
emit("update:modelValue", false);
|
||||||
|
emit("confirm");
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
document.body.style.overflow = "hidden";
|
||||||
|
} else {
|
||||||
|
document.body.style.overflow = "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Teleport to="body">
|
||||||
|
<Transition name="fade">
|
||||||
|
<div
|
||||||
|
v-if="modelValue"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center bg-black/40"
|
||||||
|
@click.self="close"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="min-w-[320px] max-w-sm rounded-xl border border-gray-200 bg-white shadow-2xl dark:border-dk-muted dark:bg-dk-card"
|
||||||
|
>
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="flex items-center justify-between border-b border-gray-100 px-5 py-4 dark:border-dk-muted">
|
||||||
|
<h3 class="text-base font-semibold text-gray-900 dark:text-white">
|
||||||
|
{{ title || t("message.confirm") }}
|
||||||
|
</h3>
|
||||||
|
<button
|
||||||
|
class="ml-4 flex-shrink-0 rounded p-1 text-gray-400 hover:bg-gray-100 hover:text-gray-600 dark:hover:bg-dk-muted dark:hover:text-gray-200"
|
||||||
|
@click="close"
|
||||||
|
>
|
||||||
|
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 内容 -->
|
||||||
|
<div class="px-5 py-4">
|
||||||
|
<p class="text-sm leading-relaxed text-gray-600 dark:text-gray-300">
|
||||||
|
{{ message }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 操作栏 -->
|
||||||
|
<div class="flex justify-end gap-3 border-t border-gray-100 px-5 py-4 dark:border-dk-muted">
|
||||||
|
<button
|
||||||
|
class="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 dark:border-dk-muted dark:bg-dk-base dark:text-gray-200 dark:hover:bg-dk-muted"
|
||||||
|
@click="close"
|
||||||
|
>
|
||||||
|
{{ cancelText || t("message.cancel") }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="rounded-lg px-4 py-2 text-sm font-semibold text-white transition-colors"
|
||||||
|
:class="
|
||||||
|
danger
|
||||||
|
? 'bg-red-500 hover:bg-red-600'
|
||||||
|
: 'bg-blue-600 hover:bg-blue-700'
|
||||||
|
"
|
||||||
|
@click="confirm"
|
||||||
|
>
|
||||||
|
{{ confirmText || t("message.confirm") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity 0.15s ease;
|
||||||
|
}
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -66,6 +66,7 @@
|
|||||||
"created_at": "Created At",
|
"created_at": "Created At",
|
||||||
"updated_at": "Updated At",
|
"updated_at": "Updated At",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
|
"filter_all": "All",
|
||||||
"status_pending": "Pending",
|
"status_pending": "Pending",
|
||||||
"status_ordered": "Ordered",
|
"status_ordered": "Ordered",
|
||||||
"status_arrived": "Arrived",
|
"status_arrived": "Arrived",
|
||||||
@@ -82,8 +83,11 @@
|
|||||||
"There_are_a_total_of": ",There are a total of",
|
"There_are_a_total_of": ",There are a total of",
|
||||||
"items": "orders.",
|
"items": "orders.",
|
||||||
"order_detail": "Order Detail",
|
"order_detail": "Order Detail",
|
||||||
|
"back": "Back",
|
||||||
"back_to_list": "Back to List",
|
"back_to_list": "Back to List",
|
||||||
"order_not_found": "Order Not Found",
|
"order_not_found": "Order Not Found",
|
||||||
|
"delete_order": "Delete Order",
|
||||||
|
"confirm_delete": "Are you sure you want to delete this order? This action cannot be undone.",
|
||||||
"order_info": "Order Information",
|
"order_info": "Order Information",
|
||||||
"cost_detail": "Cost Details",
|
"cost_detail": "Cost Details",
|
||||||
"photo_remarks": "Photos",
|
"photo_remarks": "Photos",
|
||||||
@@ -227,12 +231,15 @@
|
|||||||
"administrator": "Administrator",
|
"administrator": "Administrator",
|
||||||
"select_date": "Select a date",
|
"select_date": "Select a date",
|
||||||
"save_ok": "Saved successfully",
|
"save_ok": "Saved successfully",
|
||||||
|
"delete_ok": "Deleted successfully",
|
||||||
"change_ok": "Changed successfully",
|
"change_ok": "Changed successfully",
|
||||||
"type_old_pass": "Enter old password",
|
"type_old_pass": "Enter old password",
|
||||||
"type_new_pass": "Enter new password",
|
"type_new_pass": "Enter new password",
|
||||||
"type_cof_pass": "Confirm new password",
|
"type_cof_pass": "Confirm new password",
|
||||||
"old_pass_incorrect": "Old password is incorrect",
|
"old_pass_incorrect": "Old password is incorrect",
|
||||||
"confirm_password_incorrect": "Confirm password is incorrect",
|
"confirm_password_incorrect": "Confirm password is incorrect",
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"cancel": "Cancel",
|
||||||
"save_success": "Saved successfully",
|
"save_success": "Saved successfully",
|
||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
"loading": "Loading..."
|
"loading": "Loading..."
|
||||||
|
|||||||
@@ -66,6 +66,7 @@
|
|||||||
"created_at": "创建日期",
|
"created_at": "创建日期",
|
||||||
"updated_at": "更新日期",
|
"updated_at": "更新日期",
|
||||||
"status": "状态",
|
"status": "状态",
|
||||||
|
"filter_all": "全部",
|
||||||
"status_pending": "待处理",
|
"status_pending": "待处理",
|
||||||
"status_ordered": "已下单",
|
"status_ordered": "已下单",
|
||||||
"status_arrived": "已到达",
|
"status_arrived": "已到达",
|
||||||
@@ -82,8 +83,11 @@
|
|||||||
"There_are_a_total_of": ",一共",
|
"There_are_a_total_of": ",一共",
|
||||||
"items": "个订单",
|
"items": "个订单",
|
||||||
"order_detail": "订单详情",
|
"order_detail": "订单详情",
|
||||||
|
"back": "返回",
|
||||||
"back_to_list": "返回列表",
|
"back_to_list": "返回列表",
|
||||||
"order_not_found": "订单不存在",
|
"order_not_found": "订单不存在",
|
||||||
|
"delete_order": "删除订单",
|
||||||
|
"confirm_delete": "确定要删除此订单吗?此操作不可撤销。",
|
||||||
"order_info": "订单信息",
|
"order_info": "订单信息",
|
||||||
"cost_detail": "费用明细",
|
"cost_detail": "费用明细",
|
||||||
"photo_remarks": "图片备注",
|
"photo_remarks": "图片备注",
|
||||||
@@ -233,6 +237,9 @@
|
|||||||
"type_cof_pass": "确认新密码",
|
"type_cof_pass": "确认新密码",
|
||||||
"old_pass_incorrect": "旧密码不正确",
|
"old_pass_incorrect": "旧密码不正确",
|
||||||
"confirm_password_incorrect": "确认密码不正确",
|
"confirm_password_incorrect": "确认密码不正确",
|
||||||
|
"confirm": "确认",
|
||||||
|
"cancel": "取消",
|
||||||
|
"delete_ok": "删除成功",
|
||||||
"save_success": "保存成功",
|
"save_success": "保存成功",
|
||||||
"submit": "提交",
|
"submit": "提交",
|
||||||
"loading": "加载中..."
|
"loading": "加载中..."
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import { useToastStore } from '@/stores/toast'
|
import { useToastStore } from '@/stores/toast'
|
||||||
import { usePageTitle } from '@/composables/usePageTitle'
|
import { usePageTitle } from '@/composables/usePageTitle'
|
||||||
import { purchaseApi } from '@/api/purchase'
|
import { purchaseApi } from '@/api/purchase'
|
||||||
import { IconPlus, IconChevronLeftPipe, IconChevronRightPipe, IconChevronsLeft, IconChevronsRight, IconSearch } from '@tabler/icons-vue'
|
import { IconPlus, IconChevronLeftPipe, IconChevronRightPipe, IconChevronsLeft, IconChevronsRight } from '@tabler/icons-vue'
|
||||||
|
|
||||||
usePageTitle('appname.purchase')
|
usePageTitle('appname.purchase')
|
||||||
const { t, locale } = useI18n()
|
const { t, locale } = useI18n()
|
||||||
@@ -16,9 +16,19 @@ const orders = ref([])
|
|||||||
const totalCount = ref(0)
|
const totalCount = ref(0)
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(10)
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const searchQuery = ref('')
|
const statusFilter = ref('')
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
|
const statusOptions = [
|
||||||
|
{ value: '', labelKey: 'purchase.filter_all' },
|
||||||
|
{ value: 'pending', labelKey: 'purchase.status_pending' },
|
||||||
|
{ value: 'ordered', labelKey: 'purchase.status_ordered' },
|
||||||
|
{ value: 'arrived', labelKey: 'purchase.status_arrived' },
|
||||||
|
{ value: 'received', labelKey: 'purchase.status_received' },
|
||||||
|
{ value: 'lost', labelKey: 'purchase.status_lost' },
|
||||||
|
{ value: 'returned', labelKey: 'purchase.status_returned' },
|
||||||
|
]
|
||||||
|
|
||||||
const totalPages = computed(() => Math.ceil(totalCount.value / pageSize.value) || 1)
|
const totalPages = computed(() => Math.ceil(totalCount.value / pageSize.value) || 1)
|
||||||
|
|
||||||
const pageRange = computed(() => {
|
const pageRange = computed(() => {
|
||||||
@@ -34,7 +44,7 @@ async function fetchOrders() {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const { errCode, data } = await purchaseApi.getOrders({
|
const { errCode, data } = await purchaseApi.getOrders({
|
||||||
search: searchQuery.value,
|
status: statusFilter.value,
|
||||||
entries: pageSize.value,
|
entries: pageSize.value,
|
||||||
page: currentPage.value,
|
page: currentPage.value,
|
||||||
})
|
})
|
||||||
@@ -107,11 +117,16 @@ onMounted(fetchOrders)
|
|||||||
<IconPlus :size="16" />
|
<IconPlus :size="16" />
|
||||||
{{ t('purchase.add_part') }}
|
{{ t('purchase.add_part') }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<button class="rounded-lg border border-gray-300 px-3 py-1.5 text-sm text-gray-600 transition-colors hover:bg-gray-50 dark:border-dk-muted dark:text-gray-400">{{ t('purchase.exp_report') }}</button>
|
<!-- 状态下拉筛选 -->
|
||||||
</div>
|
<select
|
||||||
<div class="flex items-center gap-2">
|
v-model="statusFilter"
|
||||||
<label class="text-sm text-gray-500">{{ t('purchase.search') }}</label>
|
class="rounded-lg border border-gray-300 bg-white px-3 py-1.5 text-sm dark:border-dk-muted dark:bg-dk-base dark:text-white"
|
||||||
<input v-model="searchQuery" type="text" class="w-48 rounded-lg border border-gray-300 bg-white px-3 py-1.5 text-sm outline-none transition-colors focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 dark:border-dk-muted dark:bg-dk-base dark:text-white" @keydown.enter="currentPage=1;fetchOrders()" />
|
@change="currentPage = 1; fetchOrders()"
|
||||||
|
>
|
||||||
|
<option v-for="opt in statusOptions" :key="opt.value" :value="opt.value">
|
||||||
|
{{ t(opt.labelKey) }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { useValidation } from "@/composables";
|
|||||||
import { purchaseApi } from "@/api/purchase";
|
import { purchaseApi } from "@/api/purchase";
|
||||||
import tagadder from "@/components/tagadder.vue";
|
import tagadder from "@/components/tagadder.vue";
|
||||||
import useDropzone from "@/components/useDropzone.vue";
|
import useDropzone from "@/components/useDropzone.vue";
|
||||||
|
import ConfirmDialog from "@/components/ConfirmDialog.vue";
|
||||||
|
|
||||||
usePageTitle("purchase_addorder.edit_order");
|
usePageTitle("purchase_addorder.edit_order");
|
||||||
|
|
||||||
@@ -96,6 +97,7 @@ watch(
|
|||||||
|
|
||||||
// ==================== 图片上传 ====================
|
// ==================== 图片上传 ====================
|
||||||
const dropzoneRef = ref(null);
|
const dropzoneRef = ref(null);
|
||||||
|
const showDeleteConfirm = ref(false);
|
||||||
|
|
||||||
function getPhotoHashes() {
|
function getPhotoHashes() {
|
||||||
return dropzoneRef.value?.return_files().map((f) => f.hash) ?? [];
|
return dropzoneRef.value?.return_files().map((f) => f.hash) ?? [];
|
||||||
@@ -152,6 +154,30 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ==================== 提交 ====================
|
||||||
|
// ==================== 删除订单 ====================
|
||||||
|
async function handleDelete() {
|
||||||
|
showDeleteConfirm.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doDelete() {
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const res = await purchaseApi.deleteOrder(orderId);
|
||||||
|
if (res.errCode === 0) {
|
||||||
|
toast.success(t("message.delete_ok"));
|
||||||
|
router.replace("/purchase");
|
||||||
|
} else {
|
||||||
|
toast.error(t("message.server_error"));
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
toast.error(t("message.server_error"));
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== 提交 ====================
|
// ==================== 提交 ====================
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
clearErrors();
|
clearErrors();
|
||||||
@@ -241,11 +267,24 @@ async function handleSubmit() {
|
|||||||
<h4 class="text-sm font-semibold text-gray-900 dark:text-white">
|
<h4 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||||
{{ t("purchase_addorder.edit_order") }}
|
{{ t("purchase_addorder.edit_order") }}
|
||||||
</h4>
|
</h4>
|
||||||
<!-- 返回按钮 -->
|
<!-- 操作按钮组 -->
|
||||||
<button
|
<div class="flex items-center gap-2">
|
||||||
class="flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-dk-base"
|
<!-- 删除按钮 -->
|
||||||
@click="router.back()"
|
<button
|
||||||
>
|
class="flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20"
|
||||||
|
:disabled="loading"
|
||||||
|
@click="handleDelete"
|
||||||
|
>
|
||||||
|
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||||
|
</svg>
|
||||||
|
{{ t("purchase.delete_order") }}
|
||||||
|
</button>
|
||||||
|
<!-- 返回按钮 -->
|
||||||
|
<button
|
||||||
|
class="flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-dk-base"
|
||||||
|
@click="router.back()"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="h-4 w-4"
|
class="h-4 w-4"
|
||||||
fill="none"
|
fill="none"
|
||||||
@@ -259,8 +298,9 @@ async function handleSubmit() {
|
|||||||
d="M15 19l-7-7 7-7"
|
d="M15 19l-7-7 7-7"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
{{ t("purchase.back_to_list") }}
|
{{ t("purchase.back") }}
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 错误提示(字段验证) -->
|
<!-- 错误提示(字段验证) -->
|
||||||
@@ -532,4 +572,12 @@ async function handleSubmit() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 通用确认弹窗 -->
|
||||||
|
<ConfirmDialog
|
||||||
|
v-model="showDeleteConfirm"
|
||||||
|
:title="t('purchase.confirm_delete')"
|
||||||
|
danger
|
||||||
|
@confirm="doDelete"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user