소스 검색

fix 激活码接口对接和优化

ylong 4 달 전
부모
커밋
e42dfb6908

+ 1 - 1
src/views/code/list/components/in-detail-modal.vue

@@ -54,7 +54,7 @@
             }
         },
         { label: '操作人', prop: 'operatorName', width: 120, align: 'center' },
-        { label: '描述', prop: 'remark', minWidth: 150, align: 'left' },
+        { label: '描述', prop: 'remark', minWidth: 150, align: 'left', formatter: (row) => row.remark || '-' },
         { label: '操作时间', prop: 'operatorTime', width: 160, align: 'center' }
     ]);
 

+ 1 - 1
src/views/code/list/components/out-detail-modal.vue

@@ -51,7 +51,7 @@ const columns = ref([
         }
     },
     { label: '操作人', prop: 'operatorName', width: 120, align: 'center' },
-    { label: '描述', prop: 'remark', minWidth: 150, align: 'left' },
+    { label: '描述', prop: 'remark', minWidth: 150, align: 'left', formatter: (row) => row.remark || '-' },
     {
         label: '使用次数',
         prop: 'useTimes',

+ 157 - 0
src/views/code/record/components/in-detail-modal.vue

@@ -0,0 +1,157 @@
+<!-- 入库详情弹窗 -->
+<template>
+    <ele-modal v-model="visible" title="入库详情" :width="600" @closed="handleClosed">
+        <div v-loading="loading" class="detail-container">
+            <!-- 图片详情 -->
+            <div class="image-section">
+                <div v-if="imageUrl" class="image-container">
+                    <div class="image-item" @click="previewImage">
+                        <img :src="imageUrl" alt="入库图片" class="main-image" />
+                    </div>
+                </div>
+                <div v-else class="no-images">
+                    暂无图片
+                </div>
+            </div>
+        </div>
+
+        <!-- 图片预览 -->
+        <el-image-viewer
+            v-if="showImageViewer"
+            :url-list="[imageUrl]"
+            :initial-index="0"
+            @close="closeImageViewer"
+        />
+
+        <template #footer>
+            <el-button @click="handleClose">关闭</el-button>
+        </template>
+    </ele-modal>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { EleMessage } from 'ele-admin-plus/es';
+import request from '@/utils/request';
+
+/** 弹窗是否打开 */
+const visible = defineModel({ type: Boolean });
+
+/** 加载状态 */
+const loading = ref(false);
+
+/** 图片地址 */
+const imageUrl = ref('');
+
+/** 图片预览相关 */
+const showImageViewer = ref(false);
+
+/** 关闭弹窗 */
+const handleClose = () => {
+    visible.value = false;
+};
+
+/** 弹窗关闭事件 */
+const handleClosed = () => {
+    // 重置数据
+    imageUrl.value = '';
+    loading.value = false;
+    showImageViewer.value = false;
+};
+
+/** 预览图片 */
+const previewImage = () => {
+    if (imageUrl.value) {
+        showImageViewer.value = true;
+    }
+};
+
+/** 关闭图片预览 */
+const closeImageViewer = () => {
+    showImageViewer.value = false;
+};
+
+/** 获取入库详情 */
+const fetchInDetail = async (id) => {
+    try {
+        loading.value = true;
+        const response = await request.get(`/activation/bookActivationInfo/inDetail/${id}`);
+        
+        if (response.data.code === 200) {
+            imageUrl.value = response.data.data || '';
+        } else {
+            EleMessage.error(response.data.msg || '获取详情失败');
+        }
+    } catch (error) {
+        console.error('获取入库详情失败:', error);
+        EleMessage.error('获取详情失败');
+    } finally {
+        loading.value = false;
+    }
+};
+
+/** 打开弹窗 */
+const handleOpen = (id) => {
+    if (id) {
+        visible.value = true;
+        fetchInDetail(id);
+    } else {
+        EleMessage.warning('缺少必要参数');
+    }
+};
+
+defineExpose({
+    handleOpen
+});
+</script>
+
+<style scoped>
+.detail-container {
+    min-height: 300px;
+}
+
+.image-section {
+    text-align: center;
+}
+
+.section-title {
+    font-size: 16px;
+    font-weight: bold;
+    color: #333;
+    margin-bottom: 16px;
+}
+
+.image-container {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.image-item {
+    cursor: pointer;
+    border: 2px solid transparent;
+    border-radius: 8px;
+    overflow: hidden;
+    transition: all 0.3s ease;
+    max-width: 600px;
+}
+
+.image-item:hover {
+    border-color: #409eff;
+    transform: scale(1.02);
+}
+
+.main-image {
+    width: 100%;
+    max-height: 400px;
+    object-fit: contain;
+    display: block;
+}
+
+.no-images {
+    text-align: center;
+    color: #999;
+    padding: 40px 0;
+    font-size: 14px;
+}
+</style>

+ 105 - 72
src/views/code/record/index.vue

@@ -7,48 +7,40 @@
                 <div class="flex items-center mb-4">
                     <el-statistic :value="statistics.totalStockNum || 0" title="累计激活码数量" value-style="font-size:30px"
                         class="mr-20" />
-                    <el-statistic :value="statistics.totalOutNum || 0" title="已出库数量" value-style="font-size:30px"  
+                    <el-statistic :value="statistics.totalOutNum || 0" title="已出库数量" value-style="font-size:30px"
                         class="mr-20" />
                     <el-statistic :value="statistics.totalOutPrice || 0" title="已出库金额" :precision="2"
                         value-style="font-size:30px" class="mr-20" />
-                    <el-statistic :value="statistics.stockNum || 0" title="待出库数量" value-style="font-size:30px" 
+                    <el-statistic :value="statistics.stockNum || 0" title="待出库数量" value-style="font-size:30px"
                         class="mr-20" />
                 </div>
             </template>
 
-            <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.publisher || '-' }}</div>
-                    </div>
-                </div>
-            </template>
-
             <template #type="{ row }">
-                <el-tag :type="row.type == 0 ? 'success' : 'warning'">
-                    {{ row.type == 0 ? '入库' : '出库' }}
+                <el-tag :type="row.type == 1 ? 'success' : 'warning'">
+                    {{ row.type == 1 ? "入库" : "出库" }}
                 </el-tag>
             </template>
 
             <template #status="{ row }">
-                <el-tag :type="row.status == 1 ? 'success' : row.status == 2 ? 'warning' : 'info'">
+                <el-tag :type="row.status == 1 ? 'success' : row.status == 2 ? 'warning' : 'info'
+                    ">
                     {{ getStatusText(row.status) }}
                 </el-tag>
             </template>
 
             <template #operatorName="{ row }">
-                {{ row.operatorName || '-' }}
+                {{ row.operatorName || "-" }}
             </template>
 
             <template #action="{ row }">
                 <div>
-                    <el-button type="primary" v-permission="'code:activation:detail'" link @click="handleViewDetails(row)">
+                    <el-button type="primary" v-permission="'code:activation:detail'" link
+                        @click="handleViewDetails(row)">
                         [查看详情]
                     </el-button>
-                    <el-button type="danger" v-permission="'code:activation:invalid'" link @click="handleInvalid(row)" v-if="row.type == 1">
+                    <el-button type="danger" v-permission="'code:activation:invalid'" link @click="handleInvalid(row)"
+                        v-if="row.canCancel == 1">
                         [作废]
                     </el-button>
                 </div>
@@ -57,43 +49,50 @@
 
         <!-- 出库详情弹窗 -->
         <out-detail-modal ref="outDetailModalRef" />
-        
+
+        <!-- 入库详情弹窗 -->
+        <in-detail-modal ref="inDetailModalRef" />
+
         <!-- 作废弹窗 -->
         <invalid-modal ref="invalidModalRef" @success="handleInvalidSuccess" />
     </ele-page>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted } from 'vue';
-import CommonTable from '@/components/CommonPage/CommonTable.vue';
-import pageSearch from './page-search.vue';
-import OutDetailModal from './components/out-detail-modal.vue';
-import InvalidModal from './components/invalid-modal.vue';
-import request from '@/utils/request';
+import { ref, reactive, onMounted } from "vue";
+import CommonTable from "@/components/CommonPage/CommonTable.vue";
+import pageSearch from "./page-search.vue";
+import OutDetailModal from "./components/out-detail-modal.vue";
+import InDetailModal from "./components/in-detail-modal.vue";
+import InvalidModal from "./components/invalid-modal.vue";
+import request from "@/utils/request";
+import { ElMessage } from "element-plus";
 
-defineOptions({ name: 'CodeRecord' });
+defineOptions({ name: "CodeRecord" });
 
 // 统计数据的响应式对象
 const statistics = reactive({
     totalStockNum: 0,
     totalOutNum: 0,
     totalOutPrice: 0,
-    stockNum: 0
+    stockNum: 0,
 });
 
 // 获取统计数据
-async function fetchStatistics() {
-    request.get('/activation/bookActivationInfo/inOutSum', {
-        params: {
-            startTime: '',
-            endTime: ''
-        }
-    }).then(res => {
-        console.log('获取统计数据:', res);
-        if (res.data.code === 200) {
-            Object.assign(statistics, res.data.data || {});
-        }
-    })
+async function fetchStatistics(where = {}) {
+    request
+        .get("/activation/bookActivationInfo/inOutSum", {
+            params: {
+                startTime: where.startTime || "",
+                endTime: where.endTime || "",
+            },
+        })
+        .then((res) => {
+            console.log("获取统计数据:", res);
+            if (res.data.code === 200) {
+                Object.assign(statistics, res.data.data || {});
+            }
+        });
 }
 
 onMounted(() => {
@@ -103,37 +102,60 @@ onMounted(() => {
 // 获取状态文本
 function getStatusText(status) {
     const statusMap = {
-        1: '已完成',
-        2: '进行中',
-        3: '待处理'
+        1: "已完成",
+        2: "进行中",
+        3: "待处理",
     };
-    return statusMap[status] || '未知';
+    return statusMap[status] || "未知";
 }
 
 /** 表格列配置 */
 const columns = ref([
-    { label: 'ISBN', prop: 'isbn', align: 'center', width: 150 },
+    { label: "ISBN", prop: "isbn", align: "center", width: 150 },
     {
-        label: '商品名称',
-        prop: 'bookName',
-        align: 'left',
+        label: "商品名称",
+        prop: "bookName",
+        align: "left",
         minWidth: 300,
-        slot: 'bookInfo'
     },
-    { label: '操作类型', prop: 'type', align: 'center', width: 100, slot: 'type' },
-    { label: '操作时间', prop: 'operatorTime', align: 'center', width: 180 },
-    { label: '数量', prop: 'num', align: 'center', width: 100 },
-    { label: '金额', prop: 'totalPrice', align: 'center', width: 120 },
-    { label: '单价', prop: 'price', align: 'center', width: 100 },
-    { label: '操作', prop: 'operatorName', align: 'center', width: 120, slot: 'operatorName' },
     {
-        columnKey: 'action',
-        label: '操作',
+        label: "操作类型",
+        prop: "type",
+        align: "center",
+        width: 100,
+        slot: "type",
+    },
+    { label: "操作时间", prop: "operatorTime", align: "center", width: 180 },
+    { label: "数量", prop: "num", align: "center", width: 100 },
+    {
+        label: "金额",
+        prop: "totalPrice",
+        align: "center",
         width: 120,
-        align: 'center',
-        slot: 'action',
-        fixed: 'right'
-    }
+        formatter: (row) => (row.totalPrice == null ? "-" : row.totalPrice),
+    },
+    {
+        label: "单价",
+        prop: "price",
+        align: "center",
+        width: 100,
+        formatter: (row) => (row.price == null ? "-" : row.price),
+    },
+    {
+        label: "操作",
+        prop: "operatorName",
+        align: "center",
+        width: 120,
+        slot: "operatorName",
+    },
+    {
+        columnKey: "action",
+        label: "操作",
+        width: 150,
+        align: "center",
+        slot: "action",
+        fixed: "right",
+    },
 ]);
 
 /** 页面组件实例 */
@@ -142,38 +164,50 @@ const pageRef = ref(null);
 /** 出库详情弹窗引用 */
 const outDetailModalRef = ref(null);
 
+/** 入库详情弹窗引用 */
+const inDetailModalRef = ref(null);
+
 /** 作废弹窗引用 */
 const invalidModalRef = ref(null);
 
 const pageConfig = reactive({
-    pageUrl: '/activation/bookActivationInfo/inOutList',
-    fileName: '出入库记录',
-    cacheKey: 'codeRecord',
-    rowKey: 'id',
+    pageUrl: "/activation/bookActivationInfo/inOutList",
+    fileName: "出入库记录",
+    cacheKey: "codeRecord",
+    rowKey: "id",
 });
 
 //刷新表格
+const whereCache = ref({});
 function reload(where) {
     pageRef.value?.reload(where);
+    whereCache.value = where;
+    fetchStatistics(whereCache.value);
 }
 
 // 查看详情
 const handleViewDetails = (row) => {
-    console.log('查看详情:', row);
     if (row && row.id) {
-        outDetailModalRef.value?.handleOpen(row.id);
+        // 根据 type 类型打开不同的详情弹窗
+        // type: 1-入库, 2-出库
+        if (row.type == 1) {
+            inDetailModalRef.value?.handleOpen(row.id);
+        } else if (row.type == 2) {
+            outDetailModalRef.value?.handleOpen(row.id);
+        } else {
+            ElMessage.error("未知的记录类型");
+        }
     } else {
-        console.error('缺少记录ID');
+        ElMessage.error("缺少记录ID");
     }
 };
 
 // 作废操作
 const handleInvalid = (row) => {
-    console.log('作废操作:', row);
     if (row && row.id) {
         invalidModalRef.value?.handleOpen(row);
     } else {
-        console.error('缺少记录信息');
+        ElMessage.error("缺少记录ID");
     }
 };
 
@@ -182,9 +216,8 @@ const handleInvalidSuccess = () => {
     // 刷新表格数据
     reload();
     // 刷新统计数据
-    fetchStatistics();
+    fetchStatistics(whereCache.value);
 };
-
 </script>
 
 <style scoped>

+ 10 - 9
src/views/code/record/page-search.vue

@@ -22,24 +22,25 @@ const formItems = reactive([
     {
         type: 'select',
         label: '请选择操作类型',
-        prop: 'operationType',
+        prop: 'type',
         props: {
             placeholder: '请选择操作类型',
-            options: [
+            
+        },
+        options: [
                 { label: '全部', value: '' },
-                { label: '入库', value: '0' },
-                { label: '出库', value: '1' }
+                { label: '入库', value: '1' },
+                { label: '出库', value: '2' }
             ]
-        }
     },
     { type: 'input', label: '请输入备注信息', prop: 'remark', placeholder: '请输入备注信息' },
     {
-        type: 'datetimerange',
+        type: 'daterange',
         label: '时间',
         prop: 'timeRange',
         props: {
-            valueFormat: 'YYYY-MM-DD HH:mm:ss',
-            format: 'YYYY-MM-DD HH:mm:ss',
+            valueFormat: 'YYYY-MM-DD',
+            format: 'YYYY-MM-DD',
             startPlaceholder: '开始时间',
             endPlaceholder: '结束时间',
             shortcuts: [
@@ -87,7 +88,7 @@ const initKeys = reactive({
     timeRange: [],
     isbn: '',
     bookName: '',
-    operationType: '',
+    type: '',
     remark: ''
 });