Files
integral-shop/backend-adminend/src/views/integral-external/order/index.vue
apple f8ba25e7d5 feat(integral-external): order/user list, integral log, wa selfBonus
- Fix ExternalIntegral order list (no double restPage); default 普通订单; UI columns for useIntegral and buyer uid/nickname/phone; enrich StoreOrderDetailResponse and admin query select.
- External user list: UserResponse.selfBonus and fillWaSelfBonus from wa_users.id=uid.
- Integral log: AdminIntegralSearchRequest nickName/phone; findAdminList filters and ordering; integralExternal API sends page/limit as query params.
- Integral detail page: linkType Chinese mapping including selfbonus; update docs/newpage.md.
- Dashboard grid menu entries for integral-external routes.

Made-with: Cursor
2026-04-09 15:10:16 +08:00

254 lines
8.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="divBox relative">
<el-card class="box-card">
<div class="clearfix">
<div class="container">
<el-form size="small" label-width="100px">
<el-form-item label="订单状态:">
<el-radio-group v-model="tableFrom.status" type="button" @change="seachList">
<el-radio-button label="all">全部</el-radio-button>
<el-radio-button label="unPaid">未支付</el-radio-button>
<el-radio-button label="notShipped">未发货</el-radio-button>
<el-radio-button label="spike">待收货</el-radio-button>
<el-radio-button label="bargain">待评价</el-radio-button>
<el-radio-button label="complete">交易完成</el-radio-button>
<el-radio-button label="refunding">退款中</el-radio-button>
<el-radio-button label="refunded">已退款</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="时间选择:" class="width100">
<el-radio-group
v-model="tableFrom.dateLimit"
type="button"
class="mr20"
size="small"
@change="selectChange(tableFrom.dateLimit)"
>
<el-radio-button v-for="(item, i) in fromList.fromTxt" :key="i" :label="item.val">
{{ item.text }}
</el-radio-button>
</el-radio-group>
<el-date-picker
v-model="timeVal"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
size="small"
type="daterange"
placement="bottom-end"
placeholder="自定义时间"
style="width: 220px"
@change="onchangeTime"
/>
</el-form-item>
<el-form-item label="订单号:" class="width100">
<el-input
v-model="tableFrom.orderNo"
placeholder="请输入订单号"
class="selWidth"
size="small"
clearable
>
<el-button slot="append" icon="el-icon-search" size="small" @click="seachList" />
</el-input>
</el-form-item>
</el-form>
</div>
</div>
</el-card>
<el-card class="box-card mt10">
<el-table
v-loading="listLoading"
:data="tableData.data"
size="mini"
class="table"
highlight-current-row
:header-cell-style="{ fontWeight: 'bold' }"
>
<el-table-column label="订单号" min-width="210">
<template slot-scope="scope">
<span style="display: block">{{ scope.row.orderId }}</span>
<span v-if="scope.row.isDel" style="color: #ed4014; display: block">用户已删除</span>
</template>
</el-table-column>
<el-table-column prop="uid" label="用户ID" min-width="80" />
<el-table-column prop="nickname" label="用户昵称" min-width="120" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{ scope.row.nickname || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="用户手机号" min-width="120">
<template slot-scope="scope">
<span>{{ scope.row.userPhone | phoneDesensitize }}</span>
</template>
</el-table-column>
<el-table-column prop="realName" label="收货人" min-width="100" />
<el-table-column label="商品信息" min-width="280">
<template slot-scope="scope">
<div v-if="scope.row.productList && scope.row.productList.length">
<div
v-for="(val, i) in scope.row.productList"
:key="i"
class="tabBox acea-row row-middle"
style="flex-wrap: inherit; margin-bottom: 4px"
>
<div class="demo-image__preview mr10" style="width: 40px; height: 40px; flex-shrink: 0">
<el-image :src="val.info.image" :preview-src-list="[val.info.image]" style="width: 40px; height: 40px" />
</div>
<div class="text_overflow">
<span class="tabBox_tit mr10">{{ val.info.productName }}</span>
<span class="tabBox_pice">{{ val.info.price }} × {{ val.info.payNum }}</span>
</div>
</div>
</div>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="使用积分" min-width="90">
<template slot-scope="scope">
<span>{{ scope.row.useIntegral != null ? scope.row.useIntegral : '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="payPrice" label="实际支付" min-width="90">
<template slot-scope="scope">
<span>{{ scope.row.payPrice }}</span>
</template>
</el-table-column>
<el-table-column label="支付方式" min-width="90">
<template slot-scope="scope">
<span>{{ scope.row.payTypeStr || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="订单状态" min-width="100">
<template slot-scope="scope">
<span :class="scope.row.refundStatus === 1 || scope.row.refundStatus === 2 ? 'refund-tag' : ''">
{{ scope.row.statusStr ? scope.row.statusStr.value : '-' }}
</span>
</template>
</el-table-column>
<el-table-column prop="createTime" label="下单时间" min-width="150" />
</el-table>
<div class="block mt20">
<el-pagination
:page-sizes="[15, 30, 45, 60]"
:page-size="tableFrom.limit"
:current-page="tableFrom.page"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
</div>
</template>
<script>
import { getExternalOrderList } from '@/api/integralExternal';
export default {
name: 'IntegralExternalOrder',
data() {
return {
listLoading: false,
tableData: {
data: [],
total: 0,
},
tableFrom: {
type: 0,
status: 'all',
dateLimit: '',
orderNo: '',
page: 1,
limit: 15,
},
timeVal: [],
fromList: {
fromTxt: [
{ text: '全部', val: '' },
{ text: '今天', val: 'today' },
{ text: '昨天', val: 'yesterday' },
{ text: '最近7天', val: 'lately7' },
{ text: '最近30天', val: 'lately30' },
{ text: '本月', val: 'month' },
{ text: '本年', val: 'year' },
],
},
};
},
mounted() {
this.getList();
},
methods: {
getList() {
this.listLoading = true;
const params = { ...this.tableFrom };
if (!params.dateLimit) delete params.dateLimit;
if (!params.orderNo) delete params.orderNo;
getExternalOrderList(params)
.then((res) => {
this.tableData.data = res.list || [];
this.tableData.total = res.total || 0;
})
.catch(() => {})
.finally(() => {
this.listLoading = false;
});
},
seachList() {
this.tableFrom.page = 1;
this.getList();
},
selectChange(val) {
if (val) this.timeVal = [];
this.tableFrom.dateLimit = val;
this.seachList();
},
onchangeTime(e) {
this.timeVal = e;
this.tableFrom.dateLimit = e ? e.join(',') : '';
this.seachList();
},
handleSizeChange(val) {
this.tableFrom.limit = val;
this.getList();
},
handleCurrentChange(val) {
this.tableFrom.page = val;
this.getList();
},
},
};
</script>
<style scoped lang="scss">
.mt10 {
margin-top: 10px;
}
.mt20 {
margin-top: 20px;
}
.refund-tag {
color: #f124c7;
font-weight: bold;
}
.tabBox {
display: flex;
align-items: center;
}
.tabBox_tit {
font-size: 12px;
color: #333;
}
.tabBox_pice {
font-size: 12px;
color: #999;
}
.block {
text-align: right;
}
</style>