shop-front-end/src/views/cabinet/shop/card.vue

264 lines
7.5 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.

<script setup lang="ts">
import { onMounted, ref } from "vue";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { getShopList, type ShopDTO, ShopQuery, getModeText, getBalanceEnableText } from "@/api/shop/shop";
import { type PaginationProps } from "@pureadmin/table";
import { useRouter } from "vue-router";
import { useWxStore } from "@/store/modules/wx";
import Search from "@iconify-icons/ep/search";
import Refresh from "@iconify-icons/ep/refresh";
import View from "@iconify-icons/ep/view";
import AddFill from "@iconify-icons/ri/add-circle-line";
import ShopFormModal from "./shop-form-modal.vue";
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
const { VITE_PUBLIC_IMG_PATH: IMG_PATH } = import.meta.env;
defineOptions({
name: "ShopCard"
});
const router = useRouter();
const wxStore = useWxStore();
const formRef = ref();
const modalVisible = ref(false);
const currentRow = ref<ShopDTO | null>(null);
const searchFormParams = ref<ShopQuery>({
shopName: "",
corpid: wxStore.corpid
});
const pageLoading = ref(false);
const dataList = ref<ShopDTO[]>([]);
const pagination = ref<PaginationProps>({
total: 0,
pageSize: 12,
currentPage: 1,
background: true
});
async function onSearch() {
pagination.value.currentPage = 1;
getList();
}
async function getList() {
try {
pageLoading.value = true;
const { data } = await getShopList({
...searchFormParams.value,
corpid: wxStore.corpid,
pageSize: pagination.value.pageSize,
pageNum: pagination.value.currentPage
});
dataList.value = data.rows;
pagination.value.total = data.total;
} finally {
pageLoading.value = false;
}
}
const resetForm = formEl => {
if (!formEl) return;
formEl.resetFields();
onSearch();
};
const handleViewDetail = (row: ShopDTO) => {
currentRow.value = row;
modalVisible.value = true;
};
function getModeType(mode: number): "" | "success" | "warning" | "info" | "danger" {
switch (mode) {
case 0: return 'success';
case 1: return 'info';
case 2: return 'warning';
case 3: return 'danger';
default: return '';
}
}
function getBalanceType(enable: number): "" | "success" | "warning" | "info" | "danger" {
return enable == 1 ? 'success' : 'danger';
}
onMounted(() => {
getList();
});
</script>
<template>
<div class="main">
<div class="float-right w-full">
<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 label="" prop="shopName">
<el-input @keydown.enter.prevent="onSearch" v-model="searchFormParams.shopName" placeholder="请输入地址名称"
clearable class="!w-[200px]" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="useRenderIcon(Search)" :loading="pageLoading" @click="onSearch">
搜索
</el-button>
</el-form-item>
<el-form-item class="space-item">
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="useRenderIcon(AddFill)" @click="modalVisible = true; currentRow = null"
style="margin-right: 10px;">
新增地址
</el-button>
</el-form-item>
</el-form>
<div class="grid-container">
<el-row :gutter="12">
<el-col v-for="(item, index) in dataList" :key="item.shopId" :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
<el-card class="cabinet-card" :body-style="{ padding: '8px 10px' }">
<div class="card-content">
<img v-if="item.coverImg" :src="item.coverImg" alt="" class="cabinet-image">
<svg v-if="!item.coverImg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 100" width="160" height="100"
class="cabinet-image">
<!-- 背景:浅灰色填充,模拟图片容器 -->
<rect width="100%" height="100%" fill="#f8f8f8" rx="4" ry="4" /> <!-- 可选圆角,适配卡片风格 -->
<!-- 图片图标:简化的“图片”符号(矩形+交叉线),直观关联“图片” -->
<g stroke="#ccc" stroke-width="2" fill="none">
<rect x="20" y="10" width="120" height="65" /> <!-- 图片框 -->
<line x1="20" y1="10" x2="140" y2="75" /> <!-- 对角线1 -->
<line x1="140" y1="10" x2="20" y2="75" /> <!-- 对角线2 -->
</g>
<!-- 说明文字:明确提示“未设置图片”,居中对齐 -->
<text x="50%" y="92" font-size="12" fill="#888" text-anchor="middle" font-family="Arial, sans-serif">
未设置图片
</text>
</svg>
<el-descriptions class="cabinet-info" :column="1">
<!-- <el-descriptions-item class="type">模式{{ item.belongType === 0 ? '借还模式' : '固资模式' }}</el-descriptions-item> -->
<el-descriptions-item class="mode">运行模式<el-tag :type="getModeType(item.mode)">{{ getModeText(item.mode) }}</el-tag></el-descriptions-item>
<el-descriptions-item class="balance">借呗支付<el-tag :type="getBalanceType(item.balanceEnable)">{{ getBalanceEnableText(item.balanceEnable) }}</el-tag></el-descriptions-item>
</el-descriptions>
</div>
<el-divider class="divider" />
<el-button class="detail-btn" link @click="handleViewDetail(item)">
{{ item.shopName }}
</el-button>
</el-card>
</el-col>
</el-row>
<div class="pagination-wrapper">
<el-pagination background layout="prev, pager, next" :page-size="pagination.pageSize"
:total="pagination.total" v-model:current-page="pagination.currentPage" @current-change="getList"
@size-change="getList" />
</div>
</div>
</div>
<shop-form-modal v-model:visible="modalVisible" :row="currentRow" @refresh="getList" />
</div>
</template>
<style scoped lang="scss">
.search-form {
:deep(.el-form-item) {
margin-bottom: 12px;
margin-right: 12px;
}
}
:deep(.el-descriptions__cell) {
padding-bottom: 1px !important;
}
.cabinet-card {
margin-bottom: 12px;
min-height: 190px;
display: flex;
flex-direction: column;
justify-content: space-between;
.cabinet-image {
width: 50%;
height: 130px;
padding: 0 3px;
object-fit: contain;
border-radius: 4px;
margin-bottom: 10px;
}
.card-content {
flex: 1;
margin: 0px;
display: flex;
flex-direction: row;
.cabinet-info {
text-align: left;
padding: 16px 0px;
.name,
.type,
.shop,
.location,
.template {
width: 100%;
font-size: 14px;
color: #606266;
margin-bottom: 12px;
line-height: 1;
text-align: left;
}
.name {
width: 100%;
font-weight: 500;
color: #303133;
}
}
}
.divider {
margin: 5px 0px;
}
.detail-btn {
width: 100%;
border: 0;
margin-top: auto;
padding: 8px 0;
&:hover {
color: var(--el-color-primary);
}
}
}
.grid-container {
margin: 12px 0;
position: relative;
.el-row {
margin-bottom: -20px;
}
}
.pagination-wrapper {
position: relative;
background: var(--el-bg-color);
padding: 8px 12px;
margin-top: 20px;
text-align: center;
:deep(.el-pagination) {
margin: 0;
padding: 4px 0;
}
}
.space-item {
flex: 1;
width: 100%;
}
</style>