From bc363b195cfec62a44ee19c4577884984f3e06b8 Mon Sep 17 00:00:00 2001 From: zou Date: Sat, 8 Aug 2026 10:06:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(F006):=20=E8=A1=A5=E9=BD=905=E9=A1=B9?= =?UTF-8?q?=E5=B7=AE=E8=B7=9D=20-=20=E4=BB=B7=E6=A0=BC=E5=85=AC=E5=BC=8F?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E6=96=B0=E9=A1=B5=E9=9D=A2=20+=20goodunit=20?= =?UTF-8?q?CRUD=20+=20coupon=20FormDialog=20+=20=E5=94=AE=E5=90=8E/?= =?UTF-8?q?=E9=80=80=E6=AC=BE/=E6=94=AF=E4=BB=98=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E5=85=A8=E6=8E=A5=E7=9C=9FAPI=20(Playwright?= =?UTF-8?q?=206/6=20PASS)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/menu-labels.ts | 1 + .../order/aftersale/AftersaleListView.vue | 18 +- .../order/payment/PaymentCallbackListView.vue | 5 +- .../order/refund/RefundProcessListView.vue | 14 +- .../other/goodunit/GoodunitListView.vue | 42 ++++- .../supplier/coupon/CouponListView.vue | 42 ++++- .../PriceFormulaVariableListView.vue | 171 ++++++++++++++++++ src/router/index.ts | 2 + 8 files changed, 271 insertions(+), 24 deletions(-) create mode 100644 src/modules/supplier/priceformula/PriceFormulaVariableListView.vue diff --git a/src/config/menu-labels.ts b/src/config/menu-labels.ts index e154ba3..118ba70 100644 --- a/src/config/menu-labels.ts +++ b/src/config/menu-labels.ts @@ -123,6 +123,7 @@ export const MENU_LABELS: MenuLabel[] = [ { url: 'other/supplierBrand', label: '品牌管理', icon: 'Star', path: '/other/brand', sort: 709 }, { url: 'other/groupbuy', label: '拼团活动', icon: 'GoodsFilled', path: '/other/groupbuy', sort: 710 }, { url: 'other/seckill', label: '秒杀活动', icon: 'Lightning', path: '/other/seckill', sort: 711 }, + { url: 'other/priceFormulaVariable', label: '价格公式变量', icon: 'SetUp', path: '/supplier/priceFormulaVariable', sort: 713 }, { url: 'other/information', label: '资讯列表', icon: 'Document', path: '/other/information', sort: 712 }, // ===== 基础设施(message/job/oss) ===== diff --git a/src/modules/order/aftersale/AftersaleListView.vue b/src/modules/order/aftersale/AftersaleListView.vue index 599e722..c6ea09f 100644 --- a/src/modules/order/aftersale/AftersaleListView.vue +++ b/src/modules/order/aftersale/AftersaleListView.vue @@ -10,7 +10,7 @@ */ import { ref, reactive, onMounted, computed } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' -import { httpGet } from '@/utils/request' +import { httpGet, httpPost } from '@/utils/request' import PageHeader from '@/components/PageHeader/PageHeader.vue' import SearchBar from '@/components/SearchBar/SearchBar.vue' import DataTable from '@/components/DataTable/DataTable.vue' @@ -143,23 +143,23 @@ function onStatusTab(v: string) { statusTab.value = v; page.value = 1 } async function onAgree(row: AftersaleRow) { try { await ElMessageBox.confirm(`确认通过售后申请「${row.afterSalesOrderId}」?`, '提示', { type: 'warning' }) } catch { return } - row.status = 3 - ElMessage.success('已通过 (前端示例)') + try { await httpPost('/order/orderAfterSale/confirmOrderRefund', { afterSalesOrderId: row.afterSalesOrderId, status: 3 }); ElMessage.success('已通过'); load() } + catch (e: any) { ElMessage.error(e?.msg || '操作失败') } } async function onReject(row: AftersaleRow) { try { const { value } = await ElMessageBox.prompt('请填写拒绝原因', '拒绝售后', { inputPlaceholder: '原因', confirmButtonText: '拒绝', cancelButtonText: '取消' }) - row.status = 4 - row.reason = (value || '已拒绝').trim() - ElMessage.success('已拒绝 (前端示例)') + try { await httpPost('/order/orderAfterSale/confirmOrderRefund', { afterSalesOrderId: row.afterSalesOrderId, status: 4, reason: value }); ElMessage.success('已拒绝'); load() } + catch (e: any) { ElMessage.error(e?.msg || '操作失败') } } catch {} } async function onComplete(row: AftersaleRow) { - row.status = 6 - ElMessage.success('已标记完成') + try { await ElMessageBox.confirm(`确认完成售后「${row.afterSalesOrderId}」?`, '提示', { type: 'success' }) } catch { return } + try { await httpPost('/order/orderAfterSale/completeOrder', { afterSalesOrderId: row.afterSalesOrderId }); ElMessage.success('已完成'); load() } + catch (e: any) { ElMessage.error(e?.msg || '操作失败') } } function onView(row: AftersaleRow) { - ElMessage.info(`打开售后详情 ${row.afterSalesOrderId}`) + ElMessage.info(`售后单号: ${row.afterSalesOrderId}`) } function onExport() { ElMessage.success('已发起导出 (前端示例, 共 ' + filtered.value.length + ' 条)') diff --git a/src/modules/order/payment/PaymentCallbackListView.vue b/src/modules/order/payment/PaymentCallbackListView.vue index 8dffa10..6149515 100644 --- a/src/modules/order/payment/PaymentCallbackListView.vue +++ b/src/modules/order/payment/PaymentCallbackListView.vue @@ -14,7 +14,7 @@ */ import { ref, reactive, onMounted, computed } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' -import { httpGet } from '@/utils/request' +import { httpGet, httpPost } from '@/utils/request' import PageHeader from '@/components/PageHeader/PageHeader.vue' import SearchBar from '@/components/SearchBar/SearchBar.vue' import DataTable from '@/components/DataTable/DataTable.vue' @@ -161,7 +161,8 @@ function onSearch() { function onStatusTab(v: string) { statusTab.value = v; page.value = 1 } async function onMarkPaid(row: PaymentRow) { try { await ElMessageBox.confirm(`确认「${row.id}」该款项标记为已支付?`, '提示', { type: 'warning' }) } catch { return } - ElMessage.success('已标记 (前端示例)') + try { await httpPost('/order/orderrefund/updatePayStatus', { id: row.id, payStatus: 1 }); ElMessage.success('已标记'); load() } + catch (e: any) { ElMessage.error(e?.msg || '操作失败') } } function onViewOrder(row: PaymentRow) { ElMessage.info(`打开订单 ${row.orderId}`) diff --git a/src/modules/order/refund/RefundProcessListView.vue b/src/modules/order/refund/RefundProcessListView.vue index a8ba599..f6195bf 100644 --- a/src/modules/order/refund/RefundProcessListView.vue +++ b/src/modules/order/refund/RefundProcessListView.vue @@ -12,7 +12,7 @@ */ import { ref, reactive, onMounted, computed } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' -import { httpGet } from '@/utils/request' +import { httpGet, httpPost } from '@/utils/request' import PageHeader from '@/components/PageHeader/PageHeader.vue' import SearchBar from '@/components/SearchBar/SearchBar.vue' import DataTable from '@/components/DataTable/DataTable.vue' @@ -141,20 +141,18 @@ function onStatusTab(v: string) { statusTab.value = v; page.value = 1 } async function onApprove(row: RefundRow) { try { await ElMessageBox.confirm(`确认通过退款申请「${row.id}」?`, '提示', { type: 'warning' }) } catch { return } - row.refundStatus = 2 - row.refundTime = new Date().toLocaleString('zh-CN') - ElMessage.success('已通过 (前端示例)') + try { await httpPost('/order/orderrefund/updatePayStatus', { id: row.id, payStatus: 2 }); ElMessage.success('已通过'); load() } + catch (e: any) { ElMessage.error(e?.msg || '操作失败') } } async function onReject(row: RefundRow) { try { const { value } = await ElMessageBox.prompt('请填写拒绝原因', '拒绝退款', { inputPlaceholder: '原因', confirmButtonText: '拒绝', cancelButtonText: '取消' }) - row.refundStatus = 3 - row.remark = (value || '已拒绝').trim() - ElMessage.success('已拒绝 (前端示例)') + try { await httpPost('/order/orderrefund/updatePayStatus', { id: row.id, payStatus: 3, remark: value }); ElMessage.success('已拒绝'); load() } + catch (e: any) { ElMessage.error(e?.msg || '操作失败') } } catch {} } function onView(row: RefundRow) { - ElMessage.info(`打开退款详情 ${row.id}`) + ElMessage.info(`退款单号: ${row.id}`) } function onExport() { ElMessage.success('已发起导出 (前端示例, 共 ' + filtered.value.length + ' 条)') diff --git a/src/modules/other/goodunit/GoodunitListView.vue b/src/modules/other/goodunit/GoodunitListView.vue index 634c01e..40b71ec 100644 --- a/src/modules/other/goodunit/GoodunitListView.vue +++ b/src/modules/other/goodunit/GoodunitListView.vue @@ -7,7 +7,8 @@ * 字段: id/name/type/supplierId/enterpriseId/createTime */ import { onMounted, ref, computed, reactive } from 'vue' -import { httpGet } from '@/utils/request' +import { httpGet, httpPost } from '@/utils/request' +import { ElMessage, ElMessageBox } from 'element-plus' import DataTable from '@/components/DataTable/DataTable.vue' import PageHeader from '@/components/PageHeader/PageHeader.vue' import SearchBar from '@/components/SearchBar/SearchBar.vue' @@ -66,12 +67,31 @@ function fmtTime(s?: string | null) { return s } +const editVisible = ref(false) +const editForm = reactive({ id: '', name: '', type: 2 }) +function onAdd() { Object.assign(editForm, { id: '', name: '', type: 2 }); editVisible.value = true } +function onSubmitEdit() { + if (!editForm.name.trim()) { ElMessage.warning('请填写单位名称'); return } + const ep = editForm.id ? '/other/goodunit/update' : '/other/goodunit/save' + httpPost(ep, { ...editForm }).then(() => { + ElMessage.success(editForm.id ? '修改成功' : '新增成功'); editVisible.value = false; load() + }).catch((e: any) => ElMessage.error(e?.msg || '操作失败')) +} +function onDelete(row: any) { + ElMessageBox.confirm(`确认删除「${row.name}」?`, '提示', { type: 'warning' }).then(async () => { + try { await httpPost('/other/goodunit/delete', { id: row.id }); ElMessage.success('已删除'); load() } + catch (e: any) { ElMessage.error(e?.msg || '删除失败') } + }).catch(() => {}) +} + onMounted(load) + + + + + + + + diff --git a/src/modules/supplier/coupon/CouponListView.vue b/src/modules/supplier/coupon/CouponListView.vue index 27d2db8..3e5a8b1 100644 --- a/src/modules/supplier/coupon/CouponListView.vue +++ b/src/modules/supplier/coupon/CouponListView.vue @@ -80,10 +80,27 @@ function onPageChange(p: number) { page.value = p; load() } function onLimitChange(l: number) { limit.value = l; load() } function onSelectionChange(rows: Coupon[]) { selection.value = rows } -function onAdd() { ElMessage.info('新增优惠券弹窗 (mock) - 待 add-or-update 接入') } +const editVisible = ref(false) +const editMode = ref<'add' | 'edit'>('add') +const editForm = reactive({ name: '', type: 1, fullMoney: 0, deductedMoney: 0, quantity: 0, rebate: 1, limitCollar: 1, expirationDate: '' }) + +function onAdd() { + editMode.value = 'add' + Object.assign(editForm, { id: '', name: '', type: 1, fullMoney: 0, deductedMoney: 0, quantity: 0, rebate: 1, limitCollar: 1, expirationDate: '' }) + editVisible.value = true +} function onEdit(row: Coupon) { if (row.sourceType !== 2) { ElMessage.warning('只有平台券可编辑'); return } - ElMessage.info(`编辑「${row.name}」 (mock)`) + editMode.value = 'edit' + Object.assign(editForm, JSON.parse(JSON.stringify(row))) + editVisible.value = true +} +function onSubmitEdit() { + if (!editForm.name?.trim()) { ElMessage.warning('请填写券名称'); return } + const ep = editMode.value === 'add' ? '/supplier/coupon/saveCoupon' : '/supplier/coupon/updateCoupon' + httpPost(ep, { ...editForm, sourceType: 2 }).then(() => { + ElMessage.success(editMode.value === 'add' ? '新增成功' : '修改成功'); editVisible.value = false; load() + }).catch((e: any) => ElMessage.error(e?.msg || '操作失败')) } function onToggleStatus(row: Coupon) { const next = row.onShelf === 1 ? 0 : 1 @@ -215,6 +232,27 @@ onMounted(load) 关闭 + + + + + + + 满减券 + 折扣券 + + + + + + + + + + diff --git a/src/modules/supplier/priceformula/PriceFormulaVariableListView.vue b/src/modules/supplier/priceformula/PriceFormulaVariableListView.vue new file mode 100644 index 0000000..a9806ed --- /dev/null +++ b/src/modules/supplier/priceformula/PriceFormulaVariableListView.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/src/router/index.ts b/src/router/index.ts index 5d6b492..866a77f 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -244,6 +244,8 @@ const routes: RouteRecordRaw[] = [ { path: '/other/textconfig', component: () => import('@/modules/other/textconfig/TextconfigListView.vue'), meta: { title: '常量配置' } }, { path: '/other/groupbuy', component: () => import('@/modules/other/groupbuy/GroupbuyListView.vue'), meta: { title: '拼团活动' } }, { path: '/other/seckill', component: () => import('@/modules/other/seckill/SeckillListView.vue'), meta: { title: '秒杀活动' } }, + // 价格公式变量 + { path: '/supplier/priceFormulaVariable', component: () => import('@/modules/supplier/priceformula/PriceFormulaVariableListView.vue'), meta: { title: '价格公式变量' } }, // supplier 2 个 { path: '/supplier/coupon', component: () => import('@/modules/supplier/coupon/CouponListView.vue'), meta: { title: '优惠券' } }, // W7: 独立 view, 走 /supplier/coupon/page 真 API { path: '/supplier/promoter', component: () => import('@/modules/supplier/promoter/PromoterListView.vue'), meta: { title: '推广员管理' } },