Files
cashier-web/src/views/order/index/index.vue
2025-12-06 15:46:57 +08:00

369 lines
9.1 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="app-container">
<!-- 列表 -->
<!-- 搜索 -->
<page-search ref="searchRef" :search-config="searchConfig" :isOpenAutoSearch="true" @query-click="handleQueryClick"
@reset-click="handleResetClick" />
<!-- 列表 -->
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
<template #originAmount="scope">
{{ returnOriginAmount(scope.row) }}
</template>
<template #orderNo="scope">
<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
<el-tooltip class="box-item" effect="dark" :content="scope.row.orderNo" placement="top-start">
{{ scope.row.orderNo }}
</el-tooltip>
</div>
</template>
<template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
</el-tag>
</template>
<template #goods="scope">
<div class="goods_info">
<div v-for="item in scope.row.goods" :key="item.id" class="row">
<el-image :src="item.productImg" class="cover" lazy />
<div class="info">
<div class="name">
<span :class="[item.isVip == 1 ? 'colorStyle' : '']">
{{ item.productName }}
</span>
<span v-if="item.refundNum" class="refund">(退 - {{ item.refundNum }})</span>
</div>
<div class="sku">{{ item.skuName }}</div>
</div>
</div>
</div>
</template>
<template #table="scope">
<div>
<p>
名称
<el-tag type="primary">{{ scope.row.tableName || "无" }}</el-tag>
</p>
<p v-if="scope.row.tableCode">编号{{ scope.row.tableCode }}</p>
</div>
</template>
<template #options="scope">
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
</template>
<template #state="scope">
<el-tag :type="returnStateType(scope.row[scope.prop])">
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
</el-tag>
</template>
<template #mobile="scope">
<el-text>{{ scope.row[scope.prop] }}</el-text>
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
</template>
<template #operate="scope">
<div>
<el-button link @click="showdetail(scope.row)">详情</el-button>
<el-button v-if="scope.row.status == 'done'" link>开票</el-button>
<el-button v-if="scope.row.status == 'unpaid'" type="primary" @click="toPayOrder(scope.row)">
结账
</el-button>
</div>
</template>
</page-content>
<!-- 新增 -->
<page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick">
<template #url="scope">
<FileUpload v-model="scope.formData[scope.prop]" :limit="1" v-bind="scope.attrs" />
<!-- <Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" /> -->
</template>
</page-modal>
<!-- 编辑 -->
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
<template #url="scope">
<FileUpload v-model="scope.formData[scope.prop]" :limit="1" v-bind="scope.attrs" />
<!-- <Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" /> -->
</template>
</page-modal>
<orderDetail ref="refDetail" @close="refresh" />
</div>
</template>
<script setup lang="ts">
import orderDetail from "./components/detail.vue";
import orderApi, { type getListResponse, OrderInfoVo } from "@/api/order/order";
import type { IObject, IOperatData } from "@/components/CURD/types";
import usePage from "@/components/CURD/usePage";
import addModalConfig from "./config/add";
import contentConfig from "./config/content";
import editModalConfig from "./config/edit";
import searchConfig from "./config/search";
import { returnOptionsLabel } from "./config/config";
const {
searchRef,
contentRef,
addModalRef,
editModalRef,
handleQueryClick,
handleResetClick,
// handleAddClick,
// handleEditClick,
handleSubmitClick,
handleExportClick,
handleSearchClick,
handleFilterChange,
} = usePage();
function refresh() {
console.log("refresh");
contentRef.value?.fetchPageData();
}
//计算订单原金额
function returnOriginAmount(order: OrderInfoVo) {
let amount = 0;
if (order.originAmount) {
return order.originAmount;
}
order.goods?.forEach((item) => {
amount += item.payAmount * 1;
});
return amount.toFixed(2);
}
const route = useRoute();
const { orderNo, tableName, tableCode } = route.query;
if (orderNo || tableCode || tableName) {
contentConfig.indexActionData = { orderNo, tableCode, tableName };
}
onMounted(() => {
if (orderNo || tableCode || tableName) {
searchRef.value?.setQueryValue("orderNo", orderNo);
searchRef.value?.setQueryValue("tableName", tableName);
}
});
// 新增
async function handleAddClick() {
addModalRef.value?.setModalVisible();
// 加载部门下拉数据源
// addModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
// 加载角色下拉数据源
// addModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
}
// 编辑
async function handleEditClick(row: IObject) {
editModalRef.value?.handleDisabled(false);
editModalRef.value?.setModalVisible();
// 根据id获取数据进行填充
// const data = await VersionApi.getFormData(row.id);
console.log({ ...row, url: [row.url] });
editModalRef.value?.setFormData({ ...row, url: [row.url] });
}
1;
// 其他工具栏
function handleToolbarClick(name: string) {
console.log(name);
if (name === "custom1") {
ElMessage.success("点击了自定义1按钮");
}
}
// 其他操作列
async function handleOperatClick(data: IOperatData) {
console.log(data);
if (data.name === "detail") {
return;
}
if (data.name === "printer") {
}
}
function returnStateType(status: string) {
if (status === "unpaid") {
return "warning";
}
if (status === "done") {
return "primary";
}
if (status === "cancelled") {
return "info";
}
if (status === "refund") {
return "danger";
}
}
const router = useRouter();
// 结账
function toPayOrder(order: getListResponse) {
router.push({
path: "/Instead",
query: {
id: order.id,
key: "isPayOrder",
},
});
}
//详情
const refDetail = ref();
function showdetail(row: OrderInfoVo) {
refDetail.value.show(row);
}
</script>
<style scoped lang="scss">
.collect_wrap {
display: flex;
gap: 14px;
.item {
flex: 1;
display: flex;
align-items: center;
background-color: #f5f5f5;
padding: 20px;
.icon_wrap {
$size: 34px;
$border: 6px;
width: $size;
height: $size;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--bg-color);
border-radius: 50%;
position: relative;
&::after {
content: "";
width: $size + $border;
height: $size + $border;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: var(--bg-color);
opacity: 0.3;
}
.icon {
font-size: 16px;
color: #fff;
}
.img {
width: 20px;
height: 20px;
}
}
.info {
flex: 1;
display: flex;
flex-direction: column;
padding-left: 10px;
.m {
font-weight: bold;
}
.t {
font-size: 12px;
color: #999;
padding-top: 4px;
}
}
}
}
.refund {
color: #ff9731;
font-weight: bold;
}
.table_order_info {
.order_no {
color: #999;
}
.type {
color: #e6a23c;
}
}
.goods_info {
.row {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
&:not(:first-child) {
margin-top: 10px;
}
.cover {
width: 40px;
height: 40px;
}
.info {
flex: 1;
display: flex;
flex-direction: column;
margin-top: 2px;
.sku {
color: #999;
}
}
}
}
.colorStyle {
color: #ffc315;
}
.qrStyle {
width: 100%;
height: 100%;
background-color: rgba($color: #000000, $alpha: 0.7);
position: fixed;
z-index: 999999;
top: 0;
left: 0;
.box {
width: 380px;
height: 320px;
position: absolute;
background: #fff;
top: 26%;
left: 36%;
padding: 18px;
>div:first-child {
display: flex;
align-items: center;
justify-content: space-between;
}
#canvas {
margin-left: 49%;
transform: translateX(-80px);
}
>div:last-child {
text-align: center;
}
}
}
</style>