feat(商品详情): 添加借还记录功能
- 在商品详情页新增借还记录标签页 - 添加借还记录列表组件,支持分页查询和状态筛选 - 实现借还记录相关接口和类型定义
This commit is contained in:
parent
59b19cd9e3
commit
59f8a9f744
|
|
@ -136,4 +136,57 @@ export const exportOrderExcelApi = (params: OrderQuery, fileName: string) => {
|
|||
payTime: params?.payTime ? params.payTime : undefined
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export interface BorrowReturnRecordQuery extends BasePageQuery {
|
||||
/** 商品ID */
|
||||
goodsId?: number;
|
||||
/**
|
||||
* 状态
|
||||
* @remarks
|
||||
* 0-未退还 | 1-待审批 | 2-已通过 | 3-已驳回
|
||||
*/
|
||||
status?: number;
|
||||
}
|
||||
|
||||
export interface BorrowReturnRecordDTO {
|
||||
/** 订单ID */
|
||||
orderId: number;
|
||||
/** 审批ID */
|
||||
approvalId?: number;
|
||||
/** 订单创建时间 */
|
||||
orderTime?: Date;
|
||||
/** 归还图片 */
|
||||
returnImages?: string;
|
||||
/** 审核图片 */
|
||||
auditImages?: string;
|
||||
/** 订单商品价格 */
|
||||
goodsPrice: number;
|
||||
/** 支付方式 */
|
||||
paymentMethod?: string;
|
||||
/** 订单姓名 */
|
||||
orderName?: string;
|
||||
/** 订单手机号 */
|
||||
orderMobile?: string;
|
||||
/** 订单商品数量 */
|
||||
quantity: number;
|
||||
/** 审批人 */
|
||||
auditName?: string;
|
||||
/** 审核说明 */
|
||||
auditRemark?: string;
|
||||
/**
|
||||
* 状态
|
||||
* @remarks
|
||||
* 0-未退还 | 1-待审批 | 2-已通过 | 3-已驳回
|
||||
*/
|
||||
status: number;
|
||||
/** 状态描述 */
|
||||
statusStr: string;
|
||||
}
|
||||
|
||||
/** 获取借还记录分页列表 */
|
||||
export const getBorrowReturnRecordListApi = (params?: BorrowReturnRecordQuery) => {
|
||||
return http.request<ResponseData<PageDTO<BorrowReturnRecordDTO>>>("get", "/shop/order/borrow-return-record", {
|
||||
params
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { getBorrowReturnRecordListApi, type BorrowReturnRecordDTO, type BorrowReturnRecordQuery } from "@/api/shop/order";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import Search from "@iconify-icons/ep/search";
|
||||
import Refresh from "@iconify-icons/ep/refresh";
|
||||
|
||||
defineOptions({
|
||||
name: "BorrowReturnRecord"
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
goodsId: number;
|
||||
}>();
|
||||
|
||||
const formRef = ref();
|
||||
const tableRef = ref();
|
||||
|
||||
const searchFormParams = ref<BorrowReturnRecordQuery>({
|
||||
goodsId: props.goodsId,
|
||||
status: null
|
||||
});
|
||||
|
||||
const pagination = ref({
|
||||
pageSize: 8,
|
||||
currentPage: 1,
|
||||
total: 0
|
||||
});
|
||||
|
||||
const loading = ref(false);
|
||||
const dataList = ref<BorrowReturnRecordDTO[]>([]);
|
||||
|
||||
const getList = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const { data } = await getBorrowReturnRecordListApi({
|
||||
...searchFormParams.value,
|
||||
pageSize: pagination.value.pageSize,
|
||||
pageNum: pagination.value.currentPage
|
||||
});
|
||||
dataList.value = data.rows;
|
||||
pagination.value.total = data.total;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onSearch = () => {
|
||||
pagination.value.currentPage = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
formRef.value.resetFields();
|
||||
onSearch();
|
||||
};
|
||||
|
||||
const onSizeChange = (val: number) => {
|
||||
pagination.value.pageSize = val;
|
||||
getList();
|
||||
};
|
||||
|
||||
const onCurrentChange = (val: number) => {
|
||||
pagination.value.currentPage = val;
|
||||
getList();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="borrow-return-record">
|
||||
<el-form ref="formRef" :inline="true" :model="searchFormParams"
|
||||
class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-[12px]">
|
||||
<el-form-item prop="status">
|
||||
<el-select v-model="searchFormParams.status" placeholder="请选择状态" clearable class="!w-[180px]">
|
||||
<el-option label="未退还" :value="0" />
|
||||
<el-option label="待审批" :value="1" />
|
||||
<el-option label="已通过" :value="2" />
|
||||
<el-option label="已驳回" :value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-form :inline="true" class="search-form bg-bg_color flex w-[99/100] pl-[22px] pt-0">
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="useRenderIcon(Search)" @click="onSearch" style="margin-right: 10px;">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="table-container">
|
||||
<el-table ref="tableRef" v-loading="loading" :data="dataList" row-key="orderId" border>
|
||||
<el-table-column label="订单ID" prop="orderId" width="120" />
|
||||
<el-table-column label="订单创建时间" prop="orderTime" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ row.orderTime ? new Date(row.orderTime).toLocaleString() : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品价格" prop="goodsPrice" width="120">
|
||||
<template #default="{ row }">{{ row.goodsPrice }}元</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品数量" prop="quantity" width="100" />
|
||||
<el-table-column label="订单姓名" prop="orderName" width="120" />
|
||||
<el-table-column label="订单手机号" prop="orderMobile" width="120" />
|
||||
<el-table-column label="支付方式" prop="paymentMethod" width="120">
|
||||
<template #default="{ row }">
|
||||
{{ { wechat: '微信支付', balance: '借呗支付' }[row.paymentMethod] || row.paymentMethod }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" prop="statusStr" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === 2 ? 'success' : row.status === 3 ? 'danger' : 'info'">
|
||||
{{ row.statusStr }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批人" prop="auditName" width="120" />
|
||||
<el-table-column label="归还图片" prop="returnImages" width="120">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.returnImages" class="flex gap-2">
|
||||
<el-image v-for="(img, index) in row.returnImages.split(',')" :key="index" :src="img"
|
||||
:preview-src-list="row.returnImages.split(',')" :z-index="9999" :preview-teleported="true"
|
||||
:hide-on-click-modal="true" fit="cover" class="rounded" width="40" height="40" />
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核图片" prop="auditImages" width="120">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.auditImages" class="flex gap-2">
|
||||
<el-image v-for="(img, index) in row.auditImages.split(',')" :key="index" :src="img"
|
||||
:preview-src-list="row.auditImages.split(',')" :z-index="9999" :preview-teleported="true"
|
||||
:hide-on-click-modal="true" fit="cover" class="rounded" width="40" height="40" />
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核说明" prop="auditRemark" min-width="150" />
|
||||
</el-table>
|
||||
<el-pagination v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[8, 10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
|
||||
@size-change="onSizeChange" @current-change="onCurrentChange" class="pagination" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.search-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-container {
|
||||
margin-top: 8px;
|
||||
background-color: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -7,6 +7,7 @@ import { ElMessage } from "element-plus";
|
|||
import { useRenderIcon } from '@/components/ReIcon/src/hooks';
|
||||
import EditPen from '@iconify-icons/ep/edit-pen';
|
||||
import GoodsEditModal from "./goods-edit-modal.vue";
|
||||
import BorrowReturnRecord from "./borrow-return-record.vue";
|
||||
import { useBtnPermissionStore } from "@/store/modules/btnPermission";
|
||||
|
||||
const handleEdit = (row: GoodsDTO) => {
|
||||
|
|
@ -120,6 +121,7 @@ watch(goodsId, () => {
|
|||
<el-tabs type="card" v-model="activeTab" class="tab-header-card">
|
||||
<el-tab-pane label="基本信息" name="basic"></el-tab-pane>
|
||||
<el-tab-pane label="购买记录" name="order"></el-tab-pane>
|
||||
<el-tab-pane label="借还记录" name="borrowReturn"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-button v-if="goodsInfo.belongType == 0 && hasPermission('shop:goods:write')" type="primary"
|
||||
@click="handleEdit(goodsInfo)" style="margin-bottom: 12px" :size="'default'">
|
||||
|
|
@ -197,6 +199,10 @@ watch(goodsId, () => {
|
|||
<div class="sales-details" v-if="activeTab === 'sales'">
|
||||
<!-- 销售记录表格 -->
|
||||
</div>
|
||||
|
||||
<div class="borrow-return-details" v-if="activeTab === 'borrowReturn'">
|
||||
<BorrowReturnRecord :goods-id="goodsId" />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue