feat: 完善会员交易与任务管理流程

This commit is contained in:
richjohnrambo
2026-10-13 14:20:27 +08:00
parent df95801672
commit 40bfa4cba0
25 changed files with 1198 additions and 297 deletions
+11 -6
View File
@@ -56,7 +56,7 @@
</n-modal>
<n-modal v-model:show="showDetail" preset="card" title="订单详情" class="max-w-900px">
<n-descriptions v-if="detail" bordered label-placement="left" :column="2">
<n-descriptions-item label="订单号">{{ detail.orderNo }}</n-descriptions-item><n-descriptions-item label="会员">{{ detail.username }} / {{ detail.mobileMask }}</n-descriptions-item>
<n-descriptions-item label="订单号">{{ detail.orderNo }}</n-descriptions-item><n-descriptions-item label="会员">{{ detail.username }} / {{ detail.mobile }}</n-descriptions-item>
<n-descriptions-item label="商品/任务">{{ detail.productName || '-' }}</n-descriptions-item><n-descriptions-item label="规则等级ID">{{ detail.memberLevelId }}</n-descriptions-item>
<n-descriptions-item label="订单金额">{{ yuan(detail.totalAmount) }}</n-descriptions-item><n-descriptions-item label="佣金">{{ yuan(detail.commissionAmount) }}</n-descriptions-item>
<n-descriptions-item label="规则快照" :span="2"><n-code :code="JSON.stringify(detail.ruleSnapshot || {}, null, 2)" language="json" word-wrap /></n-descriptions-item>
@@ -66,10 +66,11 @@
</template>
<script lang="ts" setup>
import { computed, h, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { NButton, NImage, NTag, useMessage } from 'naive-ui';
import { BasicTable, TableAction } from '@/components/Table';import { BasicForm,useForm } from '@/components/Form';import { adaTableScrollX } from '@/utils/hotgo';
import { TradeOrderList,TradeOrderMatch,TradeOrderMatchProducts,TradeOrderView } from '@/api/trade';import { columns,schemas,loadOptions } from './model';
const message=useMessage();const actionRef=ref(),searchFormRef=ref<any>({}),showDetail=ref(false),showMatch=ref(false),detail=ref<any>(),current=ref<any>(),autoRefresh=ref(false),refreshCountdown=ref(10);let timer:any;
const message=useMessage();const router=useRouter();const actionRef=ref(),searchFormRef=ref<any>({}),showDetail=ref(false),showMatch=ref(false),detail=ref<any>(),current=ref<any>(),autoRefresh=ref(false),refreshCountdown=ref(10);let timer:any;
const [register]=useForm({gridProps:{cols:'1 s:1 m:2 l:3 xl:5'},labelWidth:80,schemas});const loadDataTable=(res)=>TradeOrderList({...searchFormRef.value?.formModel,...res});const reloadTable=()=>actionRef.value?.reload();const yuan=(v)=>`¥${((v||0)/100).toFixed(2)}`;
const yuanPlain=(v)=>((v||0)/100).toFixed(2);
const matchLoading=ref(false),productLoading=ref(false),matchSubmitting=ref(false),products=ref<any[]>([]),selectedProduct=ref<any>();
@@ -99,10 +100,14 @@ async function confirmMatch(){
matchSubmitting.value=true;try{await TradeOrderMatch(matchForm);message.success('订单匹配成功');showMatch.value=false;reloadTable()}finally{matchSubmitting.value=false}
}
async function view(row){detail.value=await TradeOrderView({id:row.id});showDetail.value=true}
const actionColumn=reactive({width:180,title:'操作',key:'action',fixed:'right',render:(row)=>h(TableAction as any,{style:'button',actions:[
{label:'匹配订单',type:'primary',disabled:!row.canMatch,title:row.canMatch?'匹配订单':'仅“匹配中”的订单可操作',onClick:()=>openMatch(row)},
{label:'详情',onClick:()=>view(row)},
]})});const scrollX=computed(()=>adaTableScrollX(columns,actionColumn.width));
const actionColumn=reactive({width:210,title:'操作',key:'action',fixed:'right',render:(row)=>{
const actions:any[]=[];
if(row.canMatch)actions.push({label:'匹配订单',type:'primary',onClick:()=>openMatch(row)});
if(row.orderType===2&&row.orderStatus===2&&row.canReview)actions.push({label:'审核任务',type:'warning',onClick:()=>router.push({name:'task_submission_list',query:{tradeOrderId:String(row.id)}})});
else if(row.orderType===2&&row.orderStatus===2)actions.push({label:'等待会员提交',disabled:true,title:'会员提交任务凭证后即可审核'});
actions.push({label:'详情',onClick:()=>view(row)});
return h(TableAction as any,{style:'button',actions});
}});const scrollX=computed(()=>adaTableScrollX(columns,actionColumn.width));
watch(autoRefresh,(enabled)=>{
clearInterval(timer);refreshCountdown.value=10;
if(!enabled)return;