feat(F006): 补齐5项差距 - 价格公式变量新页面 + goodunit CRUD + coupon FormDialog + 售后/退款/支付操作按钮全接真API (Playwright 6/6 PASS)

This commit is contained in:
zou 2026-08-08 10:06:20 +08:00
parent c161f68d03
commit bc363b195c
8 changed files with 271 additions and 24 deletions

View File

@ -123,6 +123,7 @@ export const MENU_LABELS: MenuLabel[] = [
{ url: 'other/supplierBrand', label: '品牌管理', icon: 'Star', path: '/other/brand', sort: 709 }, { url: 'other/supplierBrand', label: '品牌管理', icon: 'Star', path: '/other/brand', sort: 709 },
{ url: 'other/groupbuy', label: '拼团活动', icon: 'GoodsFilled', path: '/other/groupbuy', sort: 710 }, { url: 'other/groupbuy', label: '拼团活动', icon: 'GoodsFilled', path: '/other/groupbuy', sort: 710 },
{ url: 'other/seckill', label: '秒杀活动', icon: 'Lightning', path: '/other/seckill', sort: 711 }, { 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 }, { url: 'other/information', label: '资讯列表', icon: 'Document', path: '/other/information', sort: 712 },
// ===== 基础设施(message/job/oss) ===== // ===== 基础设施(message/job/oss) =====

View File

@ -10,7 +10,7 @@
*/ */
import { ref, reactive, onMounted, computed } from 'vue' import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' 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 PageHeader from '@/components/PageHeader/PageHeader.vue'
import SearchBar from '@/components/SearchBar/SearchBar.vue' import SearchBar from '@/components/SearchBar/SearchBar.vue'
import DataTable from '@/components/DataTable/DataTable.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) { async function onAgree(row: AftersaleRow) {
try { await ElMessageBox.confirm(`确认通过售后申请「${row.afterSalesOrderId}」?`, '提示', { type: 'warning' }) } catch { return } try { await ElMessageBox.confirm(`确认通过售后申请「${row.afterSalesOrderId}」?`, '提示', { type: 'warning' }) } catch { return }
row.status = 3 try { await httpPost('/order/orderAfterSale/confirmOrderRefund', { afterSalesOrderId: row.afterSalesOrderId, status: 3 }); ElMessage.success('已通过'); load() }
ElMessage.success('已通过 (前端示例)') catch (e: any) { ElMessage.error(e?.msg || '操作失败') }
} }
async function onReject(row: AftersaleRow) { async function onReject(row: AftersaleRow) {
try { try {
const { value } = await ElMessageBox.prompt('请填写拒绝原因', '拒绝售后', { inputPlaceholder: '原因', confirmButtonText: '拒绝', cancelButtonText: '取消' }) const { value } = await ElMessageBox.prompt('请填写拒绝原因', '拒绝售后', { inputPlaceholder: '原因', confirmButtonText: '拒绝', cancelButtonText: '取消' })
row.status = 4 try { await httpPost('/order/orderAfterSale/confirmOrderRefund', { afterSalesOrderId: row.afterSalesOrderId, status: 4, reason: value }); ElMessage.success('已拒绝'); load() }
row.reason = (value || '已拒绝').trim() catch (e: any) { ElMessage.error(e?.msg || '操作失败') }
ElMessage.success('已拒绝 (前端示例)')
} catch {} } catch {}
} }
async function onComplete(row: AftersaleRow) { async function onComplete(row: AftersaleRow) {
row.status = 6 try { await ElMessageBox.confirm(`确认完成售后「${row.afterSalesOrderId}」?`, '提示', { type: 'success' }) } catch { return }
ElMessage.success('已标记完成') try { await httpPost('/order/orderAfterSale/completeOrder', { afterSalesOrderId: row.afterSalesOrderId }); ElMessage.success('已完成'); load() }
catch (e: any) { ElMessage.error(e?.msg || '操作失败') }
} }
function onView(row: AftersaleRow) { function onView(row: AftersaleRow) {
ElMessage.info(`打开售后详情 ${row.afterSalesOrderId}`) ElMessage.info(`售后单号: ${row.afterSalesOrderId}`)
} }
function onExport() { function onExport() {
ElMessage.success('已发起导出 (前端示例, 共 ' + filtered.value.length + ' 条)') ElMessage.success('已发起导出 (前端示例, 共 ' + filtered.value.length + ' 条)')

View File

@ -14,7 +14,7 @@
*/ */
import { ref, reactive, onMounted, computed } from 'vue' import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' 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 PageHeader from '@/components/PageHeader/PageHeader.vue'
import SearchBar from '@/components/SearchBar/SearchBar.vue' import SearchBar from '@/components/SearchBar/SearchBar.vue'
import DataTable from '@/components/DataTable/DataTable.vue' import DataTable from '@/components/DataTable/DataTable.vue'
@ -161,7 +161,8 @@ function onSearch() {
function onStatusTab(v: string) { statusTab.value = v; page.value = 1 } function onStatusTab(v: string) { statusTab.value = v; page.value = 1 }
async function onMarkPaid(row: PaymentRow) { async function onMarkPaid(row: PaymentRow) {
try { await ElMessageBox.confirm(`确认「${row.id}」该款项标记为已支付?`, '提示', { type: 'warning' }) } catch { return } 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) { function onViewOrder(row: PaymentRow) {
ElMessage.info(`打开订单 ${row.orderId}`) ElMessage.info(`打开订单 ${row.orderId}`)

View File

@ -12,7 +12,7 @@
*/ */
import { ref, reactive, onMounted, computed } from 'vue' import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' 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 PageHeader from '@/components/PageHeader/PageHeader.vue'
import SearchBar from '@/components/SearchBar/SearchBar.vue' import SearchBar from '@/components/SearchBar/SearchBar.vue'
import DataTable from '@/components/DataTable/DataTable.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) { async function onApprove(row: RefundRow) {
try { await ElMessageBox.confirm(`确认通过退款申请「${row.id}」?`, '提示', { type: 'warning' }) } catch { return } try { await ElMessageBox.confirm(`确认通过退款申请「${row.id}」?`, '提示', { type: 'warning' }) } catch { return }
row.refundStatus = 2 try { await httpPost('/order/orderrefund/updatePayStatus', { id: row.id, payStatus: 2 }); ElMessage.success('已通过'); load() }
row.refundTime = new Date().toLocaleString('zh-CN') catch (e: any) { ElMessage.error(e?.msg || '操作失败') }
ElMessage.success('已通过 (前端示例)')
} }
async function onReject(row: RefundRow) { async function onReject(row: RefundRow) {
try { try {
const { value } = await ElMessageBox.prompt('请填写拒绝原因', '拒绝退款', { inputPlaceholder: '原因', confirmButtonText: '拒绝', cancelButtonText: '取消' }) const { value } = await ElMessageBox.prompt('请填写拒绝原因', '拒绝退款', { inputPlaceholder: '原因', confirmButtonText: '拒绝', cancelButtonText: '取消' })
row.refundStatus = 3 try { await httpPost('/order/orderrefund/updatePayStatus', { id: row.id, payStatus: 3, remark: value }); ElMessage.success('已拒绝'); load() }
row.remark = (value || '已拒绝').trim() catch (e: any) { ElMessage.error(e?.msg || '操作失败') }
ElMessage.success('已拒绝 (前端示例)')
} catch {} } catch {}
} }
function onView(row: RefundRow) { function onView(row: RefundRow) {
ElMessage.info(`打开退款详情 ${row.id}`) ElMessage.info(`退款单号: ${row.id}`)
} }
function onExport() { function onExport() {
ElMessage.success('已发起导出 (前端示例, 共 ' + filtered.value.length + ' 条)') ElMessage.success('已发起导出 (前端示例, 共 ' + filtered.value.length + ' 条)')

View File

@ -7,7 +7,8 @@
* 字段: id/name/type/supplierId/enterpriseId/createTime * 字段: id/name/type/supplierId/enterpriseId/createTime
*/ */
import { onMounted, ref, computed, reactive } from 'vue' 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 DataTable from '@/components/DataTable/DataTable.vue'
import PageHeader from '@/components/PageHeader/PageHeader.vue' import PageHeader from '@/components/PageHeader/PageHeader.vue'
import SearchBar from '@/components/SearchBar/SearchBar.vue' import SearchBar from '@/components/SearchBar/SearchBar.vue'
@ -66,12 +67,31 @@ function fmtTime(s?: string | null) {
return s 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) onMounted(load)
</script> </script>
<template> <template>
<div class="rr-page"> <div class="rr-page">
<PageHeader title="商品单位" :sub="`商品计量单位管理 (共 ${list.length} 个, 筛选后 ${filtered.length} 个)`" /> <PageHeader title="商品单位" :sub="`商品计量单位管理 (共 ${list.length} 个, 筛选后 ${filtered.length} 个)`">
<el-button type="primary" @click="onAdd">新增单位</el-button>
</PageHeader>
<SearchBar <SearchBar
v-model:filters="filters" v-model:filters="filters"
@ -91,7 +111,8 @@ onMounted(load)
{ prop: 'type', label: '类型', width: 100, slot: 'type' }, { prop: 'type', label: '类型', width: 100, slot: 'type' },
{ prop: 'supplierId', label: '供应商ID', width: 120 }, { prop: 'supplierId', label: '供应商ID', width: 120 },
{ prop: 'enterpriseId', label: '企业ID', width: 120 }, { prop: 'enterpriseId', label: '企业ID', width: 120 },
{ prop: 'createTime', label: '创建时间', width: 180, slot: 'createTime' } { prop: 'createTime', label: '创建时间', width: 180, slot: 'createTime' },
{ prop: 'action', label: '操作', width: 120, slot: 'action' }
]" ]"
:data="filtered" :data="filtered"
:loading="loading" :loading="loading"
@ -113,8 +134,23 @@ onMounted(load)
<template #createTime="{ row }"> <template #createTime="{ row }">
<span class="rr-time">{{ fmtTime(row.createTime) }}</span> <span class="rr-time">{{ fmtTime(row.createTime) }}</span>
</template> </template>
<template #action="{ row }">
<span class="rr-actions">
<el-link type="danger" @click="onDelete(row)">删除</el-link>
</span>
</template>
</DataTable> </DataTable>
</div> </div>
<el-dialog v-model="editVisible" title="新增单位" width="400px">
<el-form label-width="80px">
<el-form-item label="名称" required><el-input v-model="editForm.name" placeholder="如: 吨" /></el-form-item>
</el-form>
<template #footer>
<el-button @click="editVisible = false">取消</el-button>
<el-button type="primary" @click="onSubmitEdit">保存</el-button>
</template>
</el-dialog>
</div> </div>
</template> </template>

View File

@ -80,10 +80,27 @@ function onPageChange(p: number) { page.value = p; load() }
function onLimitChange(l: number) { limit.value = l; load() } function onLimitChange(l: number) { limit.value = l; load() }
function onSelectionChange(rows: Coupon[]) { selection.value = rows } 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<any>({ 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) { function onEdit(row: Coupon) {
if (row.sourceType !== 2) { ElMessage.warning('只有平台券可编辑'); return } 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) { function onToggleStatus(row: Coupon) {
const next = row.onShelf === 1 ? 0 : 1 const next = row.onShelf === 1 ? 0 : 1
@ -215,6 +232,27 @@ onMounted(load)
<el-button @click="recordVisible = false">关闭</el-button> <el-button @click="recordVisible = false">关闭</el-button>
</template> </template>
</el-dialog> </el-dialog>
<el-dialog v-model="editVisible" :title="editMode === 'add' ? '新增优惠券' : '编辑优惠券'" width="520px">
<el-form label-width="100px">
<el-form-item label="券名称" required><el-input v-model="editForm.name" placeholder="如: 满100减20" /></el-form-item>
<el-form-item label="类型">
<el-radio-group v-model="editForm.type">
<el-radio :value="1">满减券</el-radio>
<el-radio :value="2">折扣券</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="满"><el-input-number v-model="editForm.fullMoney" :min="0" :precision="2" /></el-form-item>
<el-form-item label="减/折"><el-input-number v-model="editForm.deductedMoney" :min="0" :precision="2" /></el-form-item>
<el-form-item label="发放数量"><el-input-number v-model="editForm.quantity" :min="0" /></el-form-item>
<el-form-item label="限领"><el-input-number v-model="editForm.limitCollar" :min="1" /></el-form-item>
<el-form-item label="到期日期"><el-input v-model="editForm.expirationDate" placeholder="如: 2026-12-31" /></el-form-item>
</el-form>
<template #footer>
<el-button @click="editVisible = false">取消</el-button>
<el-button type="primary" @click="onSubmitEdit">保存</el-button>
</template>
</el-dialog>
</div> </div>
</template> </template>

View File

@ -0,0 +1,171 @@
<script setup lang="ts">
/**
* F006 价格公式变量管理
* 走 /supplier/supplierGoodPriceFormulaVariable/page (2026-08-08 探测: 200, total=5)
* CRUD: save/update/delete + updateValue
* 字段: id/var_key/var_name/var_unit/current_value/source_type/source_code/formula/sort/status/create_date
*/
import { ref, onMounted, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { httpGet, httpPost } from '@/utils/request'
import DataTable from '@/components/DataTable/DataTable.vue'
import PageHeader from '@/components/PageHeader/PageHeader.vue'
import SearchBar from '@/components/SearchBar/SearchBar.vue'
interface FormulaVar {
id: string
var_key: string
var_name: string
var_unit: string
current_value: number
source_type: number
source_code: string
formula: string
sort: number
status: number
create_date: any
raw: any
}
const SOURCE_MAP: Record<number, { label: string; type: string }> = {
1: { label: '手动输入', type: 'info' },
2: { label: '自动采集', type: 'success' },
3: { label: '公式计算', type: 'warning' }
}
const STATUS_MAP: Record<number, { label: string; type: string }> = {
0: { label: '禁用', type: 'danger' },
1: { label: '启用', type: 'success' }
}
const list = ref<FormulaVar[]>([])
const total = ref(0)
const loading = ref(false)
const query = reactive({ page: 1, limit: 10 })
const filters = reactive({ var_name: '' })
const editVisible = ref(false)
const editMode = ref<'add' | 'edit'>('add')
const editForm = reactive<FormulaVar>({ id: '', var_key: '', var_name: '', var_unit: '', current_value: 0, source_type: 1, source_code: '', formula: '', sort: 0, status: 1, create_date: null, raw: {} })
const columns = [
{ prop: 'id', label: 'ID', width: 60 },
{ prop: 'var_name', label: '变量名称', minWidth: 120 },
{ prop: 'var_key', label: '变量标识', width: 120 },
{ prop: 'var_unit', label: '单位', width: 80 },
{ prop: 'current_value', label: '当前值', width: 120, formatter: (r: FormulaVar) => r.current_value?.toLocaleString() || '0' },
{ prop: 'source_type', label: '数据来源', width: 100, slot: 'source' },
{ prop: 'formula', label: '计算公式', minWidth: 150, formatter: (r: FormulaVar) => r.formula || '--' },
{ prop: 'sort', label: '排序', width: 60 },
{ prop: 'status', label: '状态', width: 80, slot: 'status' },
{ prop: 'create_date', label: '创建时间', width: 160, formatter: (r: FormulaVar) => fmtDate(r.create_date) }
]
function fmtDate(d: any): string {
if (!d) return '--'
if (typeof d === 'string') return d.slice(0, 19)
try { return `${d.year}-${String(d.monthValue).padStart(2,'0')}-${String(d.dayOfMonth).padStart(2,'0')} ${String(d.hour).padStart(2,'0')}:${String(d.minute).padStart(2,'0')}` } catch { return '--' }
}
async function load() {
loading.value = true
try {
const resp: any = await httpGet('/supplier/supplierGoodPriceFormulaVariable/page', { page: query.page, limit: query.limit, ...(filters.var_name ? { var_name: filters.var_name } : {}) })
list.value = (resp?.list || []).map((it: any) => ({ ...it, raw: it }))
total.value = Number(resp?.total || 0)
} catch { list.value = []; total.value = 0 } finally { loading.value = false }
}
function onSearch() { query.page = 1; load() }
function onReset() { filters.var_name = ''; query.page = 1; load() }
function onPageChange(p: number) { query.page = p; load() }
function onLimitChange(l: number) { query.limit = l; query.page = 1; load() }
function onAdd() {
editMode.value = 'add'
Object.assign(editForm, { id: '', var_key: '', var_name: '', var_unit: '', current_value: 0, source_type: 1, source_code: '', formula: '', sort: 0, status: 1, create_date: null, raw: {} })
editVisible.value = true
}
function onEdit(row: FormulaVar) {
editMode.value = 'edit'
Object.assign(editForm, JSON.parse(JSON.stringify(row)))
editVisible.value = true
}
function onSubmitEdit() {
if (!editForm.var_name.trim() || !editForm.var_key.trim()) { ElMessage.warning('请填写变量名称和标识'); return }
const ep = editMode.value === 'add' ? '/supplier/supplierGoodPriceFormulaVariable/save' : '/supplier/supplierGoodPriceFormulaVariable/updateValue'
httpPost(ep, { ...editForm }).then(() => {
ElMessage.success(editMode.value === 'add' ? '新增成功' : '修改成功')
editVisible.value = false; load()
}).catch((e: any) => ElMessage.error(e?.msg || '操作失败'))
}
function onDelete(row: FormulaVar) {
ElMessageBox.confirm(`确认删除「${row.var_name}」?`, '提示', { type: 'warning' }).then(async () => {
try { await httpPost('/supplier/supplierGoodPriceFormulaVariable/delete', { id: row.id }); ElMessage.success('已删除'); load() }
catch (e: any) { ElMessage.error(e?.msg || '删除失败') }
}).catch(() => {})
}
onMounted(load)
</script>
<template>
<div class="rr-page">
<PageHeader title="价格公式变量" :sub="`动态定价公式变量管理 (共 ${total} 个)`">
<el-button type="primary" @click="onAdd">新增变量</el-button>
</PageHeader>
<SearchBar v-model:filters="filters" :fields="[
{ key: 'var_name', label: '变量名称', type: 'text', placeholder: '请输入变量名称' }
]" @search="onSearch" @reset="onReset" />
<div class="rr-card">
<DataTable :columns="columns" :data="list" :borderless="true" :loading="loading" :total="total"
:page="query.page" :limit="query.limit" :show-pagination="true" :page-sizes="[10, 20, 50, 100]" row-key="id"
empty-text="暂无数据" @page-change="onPageChange" @limit-change="onLimitChange">
<template #source="{ row }">
<el-tag :type="(SOURCE_MAP[row.source_type]?.type as any) || 'info'">{{ SOURCE_MAP[row.source_type]?.label || row.source_type }}</el-tag>
</template>
<template #status="{ row }">
<el-tag :type="(STATUS_MAP[row.status]?.type as any) || 'info'">{{ STATUS_MAP[row.status]?.label || row.status }}</el-tag>
</template>
<template #action="{ row }">
<span class="rr-actions">
<el-link type="primary" @click="onEdit(row)">编辑</el-link>
<span class="rr-actions__sep">|</span>
<el-link type="danger" @click="onDelete(row)">删除</el-link>
</span>
</template>
</DataTable>
</div>
<el-dialog v-model="editVisible" :title="editMode === 'add' ? '新增变量' : '编辑变量'" width="500px">
<el-form label-width="100px">
<el-form-item label="变量名称" required><el-input v-model="editForm.var_name" placeholder="如: 铜价" /></el-form-item>
<el-form-item label="变量标识" required><el-input v-model="editForm.var_key" placeholder="如: copper_price" /></el-form-item>
<el-form-item label="单位"><el-input v-model="editForm.var_unit" placeholder="如: 元/吨" /></el-form-item>
<el-form-item label="当前值"><el-input-number v-model="editForm.current_value" :precision="2" :step="100" /></el-form-item>
<el-form-item label="数据来源">
<el-radio-group v-model="editForm.source_type">
<el-radio :value="1">手动输入</el-radio>
<el-radio :value="2">自动采集</el-radio>
<el-radio :value="3">公式计算</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="采集编码" v-if="editForm.source_type === 2"><el-input v-model="editForm.source_code" placeholder="如: copper" /></el-form-item>
<el-form-item label="计算公式" v-if="editForm.source_type === 3"><el-input v-model="editForm.formula" placeholder="如: copper_price * 1.05" /></el-form-item>
<el-form-item label="排序"><el-input-number v-model="editForm.sort" :min="0" /></el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="editForm.status">
<el-radio :value="1">启用</el-radio>
<el-radio :value="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="editVisible = false">取消</el-button>
<el-button type="primary" @click="onSubmitEdit">保存</el-button>
</template>
</el-dialog>
</div>
</template>
<style scoped lang="scss">
.rr-page { max-width: 1400px; }
.rr-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; }
</style>

View File

@ -244,6 +244,8 @@ const routes: RouteRecordRaw[] = [
{ path: '/other/textconfig', component: () => import('@/modules/other/textconfig/TextconfigListView.vue'), meta: { title: '常量配置' } }, { 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/groupbuy', component: () => import('@/modules/other/groupbuy/GroupbuyListView.vue'), meta: { title: '拼团活动' } },
{ path: '/other/seckill', component: () => import('@/modules/other/seckill/SeckillListView.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 个 // supplier 2 个
{ path: '/supplier/coupon', component: () => import('@/modules/supplier/coupon/CouponListView.vue'), meta: { title: '优惠券' } }, // W7: 独立 view, 走 /supplier/coupon/page 真 API { 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: '推广员管理' } }, { path: '/supplier/promoter', component: () => import('@/modules/supplier/promoter/PromoterListView.vue'), meta: { title: '推广员管理' } },