|
|
@@ -0,0 +1,294 @@
|
|
|
+<template>
|
|
|
+ <ele-page flex-table>
|
|
|
+ <code-search @search="reload" />
|
|
|
+
|
|
|
+ <common-table ref="pageRef" :pageConfig="pageConfig" :columns="columns">
|
|
|
+ <template #bookInfo="{ row }">
|
|
|
+ <div class="book-info">
|
|
|
+ <div class="book-title">{{ row.bookName }}</div>
|
|
|
+ <div class="book-details">
|
|
|
+ <div class="book-detail-item">作者:{{ row.author || '-' }}</div>
|
|
|
+ <div class="book-detail-item">ISBN:{{ row.isbn || '-' }}</div>
|
|
|
+ <div class="book-detail-item">出版社:{{ row.publish || '-' }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #bookType>
|
|
|
+ <el-tag type="primary">激活码</el-tag>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #cover="{ row }">
|
|
|
+ <div class="book-cover">
|
|
|
+ <img :src="row.cover" alt="封面" style="width: 40px; height: 50px; object-fit: cover;" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #retailPrice="{ row }">
|
|
|
+ <div class="price-cell">
|
|
|
+ <span>{{ row.retailPrice ? `¥${row.retailPrice}` : '-' }}</span>
|
|
|
+ <el-button type="primary" link size="small" @click="handleEditPrice(row, 'retail')" style="margin-left: 8px;">
|
|
|
+ <el-icon style="font-size: 18px;"><Edit /></el-icon>
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #wholesalePrice="{ row }">
|
|
|
+ <div class="price-cell">
|
|
|
+ <span>{{ row.wholesalePrice ? `¥${row.wholesalePrice}` : '-' }}</span>
|
|
|
+ <el-button type="primary" link size="small" @click="handleEditPrice(row, 'wholesale')" style="margin-left: 8px;">
|
|
|
+ <el-icon style="font-size: 18px;"><Edit /></el-icon>
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #action="{ row }">
|
|
|
+ <div>
|
|
|
+ <el-button type="warning" v-permission="'code:activation:out'" link @click="handleViewDetails(row)">
|
|
|
+ 出库
|
|
|
+ </el-button>
|
|
|
+ <el-button type="danger" v-permission="'code:activation:in'" link @click="handleInDetails(row)">
|
|
|
+ 入库明细
|
|
|
+ </el-button>
|
|
|
+ <el-button type="success" v-permission="'code:activation:outDetails'" link
|
|
|
+ @click="handleOutDetails(row)">
|
|
|
+ 出库明细
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </common-table>
|
|
|
+
|
|
|
+ <!-- 出库明细弹窗 -->
|
|
|
+ <out-detail-modal ref="outDetailModalRef" v-model="outDetailVisible" />
|
|
|
+
|
|
|
+ <!-- 入库明细弹窗 -->
|
|
|
+ <in-detail-modal ref="inDetailModalRef" v-model="inDetailVisible" />
|
|
|
+
|
|
|
+ <!-- 出库操作弹窗 -->
|
|
|
+ <out-stock-modal ref="outStockModalRef" v-model="outStockVisible" @openActivationModal="handleOpenActivationModal" />
|
|
|
+
|
|
|
+ <!-- 激活码出库单弹窗 -->
|
|
|
+ <activation-out-stock-modal ref="activationOutStockModalRef" v-model="activationOutStockVisible" />
|
|
|
+
|
|
|
+ <!-- 价格编辑弹窗 -->
|
|
|
+ <price-edit-modal ref="priceEditModalRef" v-model="priceEditVisible" @success="handlePriceEditSuccess" />
|
|
|
+ </ele-page>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, reactive } from 'vue';
|
|
|
+import { useRouter } from 'vue-router';
|
|
|
+import { EleMessage } from 'ele-admin-plus/es';
|
|
|
+import { Edit } from '@element-plus/icons-vue';
|
|
|
+import CodeSearch from './components/code-search.vue';
|
|
|
+import CommonTable from '@/components/CommonPage/CommonTable.vue';
|
|
|
+import OutDetailModal from './components/out-detail-modal.vue';
|
|
|
+import InDetailModal from './components/in-detail-modal.vue';
|
|
|
+import OutStockModal from './components/out-stock-modal.vue';
|
|
|
+import ActivationOutStockModal from './components/activation-out-stock-modal.vue';
|
|
|
+import PriceEditModal from './components/price-edit-modal.vue';
|
|
|
+
|
|
|
+defineOptions({ name: 'CodeList' });
|
|
|
+
|
|
|
+/** 弹窗显示状态 */
|
|
|
+const outDetailVisible = ref(false);
|
|
|
+const inDetailVisible = ref(false);
|
|
|
+const outStockVisible = ref(false);
|
|
|
+const activationOutStockVisible = ref(false);
|
|
|
+const priceEditVisible = ref(false);
|
|
|
+
|
|
|
+/** 弹窗组件引用 */
|
|
|
+const outDetailModalRef = ref(null);
|
|
|
+const inDetailModalRef = ref(null);
|
|
|
+const outStockModalRef = ref(null);
|
|
|
+const activationOutStockModalRef = ref(null);
|
|
|
+const priceEditModalRef = ref(null);
|
|
|
+
|
|
|
+/** 表格列配置 */
|
|
|
+const columns = reactive([
|
|
|
+ {
|
|
|
+ type: 'selection',
|
|
|
+ columnKey: 'selection',
|
|
|
+ width: 50,
|
|
|
+ align: 'center',
|
|
|
+ fixed: 'left'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '商品图',
|
|
|
+ prop: 'cover',
|
|
|
+ align: 'center',
|
|
|
+ slot: 'cover',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '商品名称',
|
|
|
+ prop: 'bookName',
|
|
|
+ align: 'left',
|
|
|
+ minWidth: 300,
|
|
|
+ slot: 'bookInfo'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '商品类型',
|
|
|
+ prop: 'bookType',
|
|
|
+ align: 'center',
|
|
|
+ slot: 'bookType',
|
|
|
+ width: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '零售价',
|
|
|
+ prop: 'retailPrice',
|
|
|
+ align: 'center',
|
|
|
+ width: 120,
|
|
|
+ formatter: (row) => row.retailPrice ? `¥${row.retailPrice}` : '-',
|
|
|
+ slot: 'retailPrice'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '批发价',
|
|
|
+ prop: 'wholesalePrice',
|
|
|
+ align: 'center',
|
|
|
+ width: 120,
|
|
|
+ formatter: (row) => row.wholesalePrice ? `¥${row.wholesalePrice}` : '-',
|
|
|
+ slot: 'wholesalePrice'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '库存',
|
|
|
+ prop: 'stockNum',
|
|
|
+ align: 'center',
|
|
|
+ width: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '销量',
|
|
|
+ prop: 'salesNum',
|
|
|
+ align: 'center',
|
|
|
+ width: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ columnKey: 'action',
|
|
|
+ label: '操作',
|
|
|
+ width: 120,
|
|
|
+ align: 'center',
|
|
|
+ slot: 'action',
|
|
|
+ fixed: 'right'
|
|
|
+ }
|
|
|
+]);
|
|
|
+
|
|
|
+const router = useRouter();
|
|
|
+/** 页面组件实例 */
|
|
|
+const pageRef = ref(null);
|
|
|
+
|
|
|
+const pageConfig = reactive({
|
|
|
+ pageUrl: '/activation/bookActivationInfo/pageList',
|
|
|
+ exportUrl: '/activation/bookActivationInfo/export',
|
|
|
+ deleteUrl: '/activation/bookActivationInfo/delete'
|
|
|
+});
|
|
|
+
|
|
|
+/** 搜索 */
|
|
|
+function reload(where) {
|
|
|
+ pageRef.value?.reload({ page: 1, where });
|
|
|
+}
|
|
|
+
|
|
|
+/** 批量删除 */
|
|
|
+function handleBatchDelete(row) {
|
|
|
+ if (row) {
|
|
|
+ // 单个删除
|
|
|
+ pageRef.value?.remove([row]);
|
|
|
+ } else {
|
|
|
+ // 批量删除
|
|
|
+ pageRef.value?.removeBatch();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function handleExportExcel() {
|
|
|
+ pageRef.value?.exportData('激活码记录');
|
|
|
+}
|
|
|
+
|
|
|
+//新增
|
|
|
+function handleAdd() {
|
|
|
+ // TODO: 实现新增功能
|
|
|
+ EleMessage.info('新增功能开发中...');
|
|
|
+}
|
|
|
+
|
|
|
+//查看出库明细
|
|
|
+function handleViewDetails(row) {
|
|
|
+ if (row && row.isbn) {
|
|
|
+ outStockModalRef.value?.handleOpen(row);
|
|
|
+ } else {
|
|
|
+ EleMessage.warning('请选择有效的商品');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 打开激活码出库单弹窗 */
|
|
|
+function handleOpenActivationModal(data) {
|
|
|
+ activationOutStockModalRef.value?.handleOpen(data);
|
|
|
+}
|
|
|
+
|
|
|
+/** 编辑价格 */
|
|
|
+function handleEditPrice(row, type) {
|
|
|
+ if (row && row.isbn) {
|
|
|
+ priceEditModalRef.value?.handleOpen(row, type);
|
|
|
+ } else {
|
|
|
+ EleMessage.warning('请选择有效的商品');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 价格编辑成功回调 */
|
|
|
+function handlePriceEditSuccess() {
|
|
|
+ // 刷新列表数据
|
|
|
+ pageRef.value?.reload();
|
|
|
+}
|
|
|
+
|
|
|
+//查看出库明细
|
|
|
+function handleOutDetails(row) {
|
|
|
+ if (row && row.isbn) {
|
|
|
+ outDetailModalRef.value?.handleOpen(row.isbn);
|
|
|
+ } else {
|
|
|
+ EleMessage.warning('请选择有效的商品');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//查看入库明细
|
|
|
+function handleInDetails(row) {
|
|
|
+ if (row && row.isbn) {
|
|
|
+ inDetailModalRef.value?.handleOpen(row.isbn);
|
|
|
+ } else {
|
|
|
+ EleMessage.warning('请选择有效的商品');
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.book-info {
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
+
|
|
|
+.book-title {
|
|
|
+ font-weight: 500;
|
|
|
+ color: #1890ff;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 1.4;
|
|
|
+}
|
|
|
+
|
|
|
+.book-details {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #666;
|
|
|
+ line-height: 1.5;
|
|
|
+}
|
|
|
+
|
|
|
+.book-detail-item {
|
|
|
+ margin-bottom: 2px;
|
|
|
+}
|
|
|
+
|
|
|
+.book-detail-item:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.price-cell {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.price-cell span {
|
|
|
+ margin-right: 4px;
|
|
|
+}
|
|
|
+</style>
|