zhangwencui
6 天以前 5333935ae59999c47653122a669f4326f0173c1c
src/views/productManagement/productIdentifier/index.vue
@@ -1,159 +1,231 @@
<template>
  <div class="app-container">
    <el-card class="box-card">
             <!-- 搜索区域 -->
       <el-row :gutter="20" class="search-row">
         <el-col :span="6">
           <el-input
             v-model="searchForm.productName"
             placeholder="请输入产品名称"
             clearable
             @keyup.enter="handleSearch"
           >
             <template #prefix>
               <el-icon><Search /></el-icon>
             </template>
           </el-input>
         </el-col>
         <el-col :span="6">
           <el-select v-model="searchForm.identifierType" placeholder="请选择标识类型" clearable>
             <el-option label="二维码" value="二维码"></el-option>
             <el-option label="防伪码" value="防伪码"></el-option>
           </el-select>
         </el-col>
         <el-col :span="6">
           <el-select v-model="searchForm.status" placeholder="请选择状态" clearable>
             <el-option label="已生成" value="已生成"></el-option>
             <el-option label="已分配" value="已分配"></el-option>
             <el-option label="已使用" value="已使用"></el-option>
             <el-option label="已作废" value="已作废"></el-option>
           </el-select>
         </el-col>
         <el-col :span="6">
           <el-button type="primary" @click="handleSearch">搜索</el-button>
           <el-button @click="resetSearch">重置</el-button>
           <el-button style="float: right;" type="primary" @click="handleAdd">
             新增标识
           </el-button>
         </el-col>
       </el-row>
      <!-- 搜索区域 -->
      <el-row :gutter="20"
              class="search-row">
        <el-col :span="6">
          <el-input v-model="searchForm.productName"
                    placeholder="请输入产品名称"
                    clearable
                    @keyup.enter="handleSearch">
            <template #prefix>
              <el-icon>
                <Search />
              </el-icon>
            </template>
          </el-input>
        </el-col>
        <el-col :span="6">
          <el-select v-model="searchForm.identifierType"
                     placeholder="请选择标识类型"
                     clearable>
            <el-option label="二维码"
                       value="二维码"></el-option>
            <el-option label="防伪码"
                       value="防伪码"></el-option>
          </el-select>
        </el-col>
        <el-col :span="6">
          <el-select v-model="searchForm.status"
                     placeholder="请选择状态"
                     clearable>
            <el-option label="已生成"
                       value="已生成"></el-option>
            <el-option label="已分配"
                       value="已分配"></el-option>
            <el-option label="已使用"
                       value="已使用"></el-option>
            <el-option label="已作废"
                       value="已作废"></el-option>
          </el-select>
        </el-col>
        <el-col :span="6">
          <el-button type="primary"
                     @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
          <el-button style="float: right;"
                     type="primary"
                     @click="handleAdd">
            新增标识
          </el-button>
        </el-col>
      </el-row>
      <!-- 产品标识列表 -->
      <el-table
        :data="filteredList"
        style="width: 100%"
        v-loading="loading"
        border
        stripe
        height="calc(100vh - 22em)"
      >
        <el-table-column prop="id" label="ID" width="80" align="center"/>
        <el-table-column prop="productName" label="产品名称" width="150" />
        <el-table-column prop="productCode" label="产品编码" width="120" />
        <el-table-column prop="batchNo" label="批次号" width="120" />
        <el-table-column prop="identifierType" label="标识类型" width="100">
      <el-table :data="filteredList"
                style="width: 100%"
                v-loading="loading"
                border
                stripe
                height="calc(100vh - 22em)">
        <el-table-column prop="id"
                         label="ID"
                         width="80"
                         align="center" />
        <el-table-column prop="productName"
                         label="产品名称"
                         width="150" />
        <el-table-column prop="productCode"
                         label="产品编码"
                         width="120" />
        <el-table-column prop="batchNo"
                         label="批次号"
                         width="120" />
        <el-table-column prop="identifierType"
                         label="标识类型"
                         width="100">
          <template #default="scope">
            <el-tag :type="getIdentifierTypeType(scope.row.identifierType)">
              {{ scope.row.identifierType }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="identifierCode" label="标识码" />
        <el-table-column prop="status" label="状态" width="100">
        <el-table-column prop="identifierCode"
                         label="标识码" />
        <el-table-column prop="status"
                         label="状态"
                         width="100">
          <template #default="scope">
            <el-tag :type="getStatusType(scope.row.status)">
              {{ scope.row.status }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="generateTime" label="生成时间" width="160" />
        <el-table-column label="操作" fixed="right" align="center" width="280">
        <el-table-column prop="generateTime"
                         label="生成时间"
                         width="160" />
        <el-table-column label="操作"
                         fixed="right"
                         align="center"
                         width="280">
          <template #default="scope">
            <el-button link type="primary" @click="handleView(scope.row)">查看</el-button>
            <el-button link type="primary" @click="handleEdit(scope.row)">编辑</el-button>
            <el-button link type="success" @click="generateQRCode(scope.row)">生成二维码</el-button>
            <el-button link type="primary" @click="handleExport(scope.row)">导出</el-button>
            <el-button link type="primary" @click="handleReassign(scope.row)" v-if="scope.row.status === '已分配'">重新分配</el-button>
            <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
            <el-button link
                       type="primary"
                       @click="handleView(scope.row)">查看</el-button>
            <el-button link
                       type="primary"
                       @click="handleEdit(scope.row)">编辑</el-button>
            <el-button link
                       type="success"
                       @click="generateQRCode(scope.row)">生成二维码</el-button>
            <el-button link
                       type="primary"
                       @click="handleExport(scope.row)">导出</el-button>
            <el-button link
                       type="primary"
                       @click="handleReassign(scope.row)"
                       v-if="scope.row.status === '已分配'">重新分配</el-button>
            <el-button link
                       type="danger"
                       @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <pagination
        :total="pagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        :page="pagination.currentPage"
        :limit="pagination.pageSize"
        @pagination="handleCurrentChange"
      />
      <pagination :total="pagination.total"
                  layout="total, sizes, prev, pager, next, jumper"
                  :page="pagination.currentPage"
                  :limit="pagination.pageSize"
                  @pagination="handleCurrentChange" />
    </el-card>
    <!-- 新增/编辑对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
    <el-dialog v-model="dialogVisible"
               :title="dialogTitle"
               width="700px">
      <el-form :model="form"
               :rules="rules"
               ref="formRef"
               label-width="100px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="产品名称" prop="productName">
              <el-input v-model="form.productName" placeholder="请输入产品名称"></el-input>
            <el-form-item label="产品名称"
                          prop="productName">
              <el-input v-model="form.productName"
                        placeholder="请输入产品名称"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="产品编码" prop="productCode">
              <el-input v-model="form.productCode" placeholder="请输入产品编码"></el-input>
            <el-form-item label="产品编码"
                          prop="productCode">
              <el-input v-model="form.productCode"
                        placeholder="请输入产品编码"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="批次号" prop="batchNo">
              <el-input v-model="form.batchNo" placeholder="请输入批次号"></el-input>
            <el-form-item label="批次号"
                          prop="batchNo">
              <el-input v-model="form.batchNo"
                        placeholder="请输入批次号"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="标识类型" prop="identifierType">
              <el-select v-model="form.identifierType" placeholder="请选择标识类型" style="width: 100%">
                <el-option label="二维码" value="二维码"></el-option>
                <el-option label="防伪码" value="防伪码"></el-option>
            <el-form-item label="标识类型"
                          prop="identifierType">
              <el-select v-model="form.identifierType"
                         placeholder="请选择标识类型"
                         style="width: 100%">
                <el-option label="二维码"
                           value="二维码"></el-option>
                <el-option label="防伪码"
                           value="防伪码"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="生成数量" prop="quantity">
              <el-input-number v-model="form.quantity" :min="1" :max="10000" style="width: 100%"></el-input-number>
            <el-form-item label="生成数量"
                          prop="quantity">
              <el-input-number v-model="form.quantity"
                               :min="1"
                               :max="10000"
                               style="width: 100%"></el-input-number>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态" prop="status">
              <el-select v-model="form.status" placeholder="请选择状态" style="width: 100%">
                <el-option label="已生成" value="已生成"></el-option>
                <el-option label="已分配" value="已分配"></el-option>
                <el-option label="已使用" value="已使用"></el-option>
                <el-option label="已作废" value="已作废"></el-option>
            <el-form-item label="状态"
                          prop="status">
              <el-select v-model="form.status"
                         placeholder="请选择状态"
                         style="width: 100%">
                <el-option label="已生成"
                           value="已生成"></el-option>
                <el-option label="已分配"
                           value="已分配"></el-option>
                <el-option label="已使用"
                           value="已使用"></el-option>
                <el-option label="已作废"
                           value="已作废"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item label="备注" prop="remark">
              <el-input type="textarea" v-model="form.remark" placeholder="请输入备注信息" rows="3"></el-input>
            <el-form-item label="备注"
                          prop="remark">
              <el-input type="textarea"
                        v-model="form.remark"
                        placeholder="请输入备注信息"
                        rows="3"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="handleSubmit">确 定</el-button>
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="handleSubmit">确 定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 标识生成对话框 -->
    <el-dialog v-model="generateDialogVisible" title="标识生成" width="500px">
    <el-dialog v-model="generateDialogVisible"
               title="标识生成"
               width="500px">
      <el-form label-width="100px">
        <el-form-item label="产品名称">
          <span>{{ currentProduct.productName }}</span>
@@ -167,30 +239,45 @@
        <el-form-item label="标识类型">
          <span>{{ currentProduct.identifierType }}</span>
        </el-form-item>
        <el-form-item label="生成数量" prop="generateQuantity">
          <el-input-number v-model="generateQuantity" :min="1" :max="10000" style="width: 100%"></el-input-number>
        <el-form-item label="生成数量"
                      prop="generateQuantity">
          <el-input-number v-model="generateQuantity"
                           :min="1"
                           :max="10000"
                           style="width: 100%"></el-input-number>
        </el-form-item>
        <el-form-item label="编码规则" prop="codeRule">
          <el-select v-model="codeRule" placeholder="请选择编码规则" style="width: 100%">
            <el-option label="产品编码+批次号+序号" value="产品编码+批次号+序号"></el-option>
            <el-option label="时间戳+随机数" value="时间戳+随机数"></el-option>
            <el-option label="自定义规则" value="自定义规则"></el-option>
        <el-form-item label="编码规则"
                      prop="codeRule">
          <el-select v-model="codeRule"
                     placeholder="请选择编码规则"
                     style="width: 100%">
            <el-option label="产品编码+批次号+序号"
                       value="产品编码+批次号+序号"></el-option>
            <el-option label="时间戳+随机数"
                       value="时间戳+随机数"></el-option>
            <el-option label="自定义规则"
                       value="自定义规则"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="自定义前缀" prop="customPrefix" v-if="codeRule === '自定义规则'">
          <el-input v-model="customPrefix" placeholder="请输入自定义前缀"></el-input>
        <el-form-item label="自定义前缀"
                      prop="customPrefix"
                      v-if="codeRule === '自定义规则'">
          <el-input v-model="customPrefix"
                    placeholder="请输入自定义前缀"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="generateIdentifiers">生 成</el-button>
          <el-button @click="generateDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="generateIdentifiers">生 成</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 重新分配对话框 -->
    <el-dialog v-model="reassignDialogVisible" title="重新分配标识" width="500px">
    <el-dialog v-model="reassignDialogVisible"
               title="重新分配标识"
               width="500px">
      <el-form label-width="100px">
        <el-form-item label="产品名称">
          <span>{{ currentProduct.productName }}</span>
@@ -198,26 +285,38 @@
        <el-form-item label="标识码">
          <span>{{ currentProduct.identifierCode }}</span>
        </el-form-item>
        <el-form-item label="新批次号" prop="newBatchNo">
          <el-input v-model="newBatchNo" placeholder="请输入新批次号"></el-input>
        <el-form-item label="新批次号"
                      prop="newBatchNo">
          <el-input v-model="newBatchNo"
                    placeholder="请输入新批次号"></el-input>
        </el-form-item>
        <el-form-item label="分配原因" prop="reassignReason">
          <el-input type="textarea" v-model="reassignReason" rows="3" placeholder="请输入重新分配原因"></el-input>
        <el-form-item label="分配原因"
                      prop="reassignReason">
          <el-input type="textarea"
                    v-model="reassignReason"
                    rows="3"
                    placeholder="请输入重新分配原因"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="saveReassign">确 定</el-button>
          <el-button @click="reassignDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="saveReassign">确 定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 二维码预览对话框 -->
    <el-dialog v-model="qrCodeDialogVisible" title="二维码预览" width="500px" center>
    <el-dialog v-model="qrCodeDialogVisible"
               title="二维码预览"
               width="500px"
               center>
      <div class="qr-preview-container">
        <div v-if="qrCodeUrl" class="qr-image-container">
          <img :src="qrCodeUrl" alt="二维码" class="qr-image" />
        <div v-if="qrCodeUrl"
             class="qr-image-container">
          <img :src="qrCodeUrl"
               alt="二维码"
               class="qr-image" />
          <div class="qr-info">
            <p><strong>产品名称:</strong>{{ currentQRProduct.productName }}</p>
            <p><strong>产品编码:</strong>{{ currentQRProduct.productCode }}</p>
@@ -226,29 +325,27 @@
            <p><strong>标识类型:</strong>{{ currentQRProduct.identifierType }}</p>
          </div>
        </div>
        <div v-else class="qr-loading">
          <el-icon class="is-loading"><Loading /></el-icon>
        <div v-else
             class="qr-loading">
          <el-icon class="is-loading">
            <Loading />
          </el-icon>
          <p>正在生成二维码...</p>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="qrCodeDialogVisible = false">关闭</el-button>
          <el-button
            v-if="qrCodeUrl"
            type="primary"
            @click="copyQRContent"
            icon="CopyDocument"
          >
          <el-button v-if="qrCodeUrl"
                     type="primary"
                     @click="copyQRContent"
                     icon="CopyDocument">
            复制内容
          </el-button>
          <el-button
            v-if="qrCodeUrl"
            type="success"
            @click="downloadQRCode"
            icon="Download"
          >
          <el-button v-if="qrCodeUrl"
                     type="success"
                     @click="downloadQRCode"
                     icon="Download">
            下载二维码
          </el-button>
        </div>
@@ -258,451 +355,465 @@
</template>
<script setup>
import { ref, reactive, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Search, Loading, Download } from '@element-plus/icons-vue'
import Pagination from '@/components/PIMTable/Pagination.vue'
import QRCode from 'qrcode'
  import { ref, reactive, computed } from "vue";
  import { ElMessage, ElMessageBox } from "element-plus";
  import { Plus, Search, Loading, Download } from "@element-plus/icons-vue";
  import Pagination from "@/components/PIMTable/Pagination.vue";
  import QRCode from "qrcode";
// 响应式数据
const loading = ref(false)
const searchForm = reactive({
  productName: '',
  identifierType: '',
  status: ''
})
  // 响应式数据
  const loading = ref(false);
  const searchForm = reactive({
    productName: "",
    identifierType: "",
    status: "",
  });
const identifierList = ref([
  {
    id: 1,
    productName: '工业传感器A型',
    productCode: 'SENSOR001',
    batchNo: 'B202312001',
    identifierType: '二维码',
    identifierCode: 'QR_SENSOR001_B202312001_001',
    status: '已分配',
    generateTime: '2023-12-01 10:00:00',
    remark: '重要产品标识'
  },
  {
    id: 2,
    productName: '控制面板B型',
    productCode: 'PANEL002',
    batchNo: 'B202312002',
    identifierType: '防伪码',
    identifierCode: 'SEC_PANEL002_B202312002_001',
    status: '已生成',
    generateTime: '2023-12-02 14:30:00',
    remark: '常规产品标识'
  },
  {
    id: 3,
    productName: '数据采集器C型',
    productCode: 'COLLECTOR003',
    batchNo: 'B202312003',
    identifierType: '防伪码',
    identifierCode: 'SEC_COLLECTOR003_B202312003_001',
    status: '已使用',
    generateTime: '2023-12-03 09:15:00',
    remark: '测试产品标识'
  }
])
  const identifierList = ref([
    {
      id: 1,
      productName: "工业传感器A型",
      productCode: "SENSOR001",
      batchNo: "B202312001",
      identifierType: "二维码",
      identifierCode: "QR_SENSOR001_B202312001_001",
      status: "已分配",
      generateTime: "2023-12-01 10:00:00",
      remark: "重要产品标识",
    },
    {
      id: 2,
      productName: "控制面板B型",
      productCode: "PANEL002",
      batchNo: "B202312002",
      identifierType: "防伪码",
      identifierCode: "SEC_PANEL002_B202312002_001",
      status: "已生成",
      generateTime: "2023-12-02 14:30:00",
      remark: "常规产品标识",
    },
    {
      id: 3,
      productName: "数据采集器C型",
      productCode: "COLLECTOR003",
      batchNo: "B202312003",
      identifierType: "防伪码",
      identifierCode: "SEC_COLLECTOR003_B202312003_001",
      status: "已使用",
      generateTime: "2023-12-03 09:15:00",
      remark: "测试产品标识",
    },
  ]);
const pagination = reactive({
  total: 3,
  currentPage: 1,
  pageSize: 10
})
  const pagination = reactive({
    total: 3,
    currentPage: 1,
    pageSize: 10,
  });
const dialogVisible = ref(false)
const dialogTitle = ref('新增标识')
const form = reactive({
  productName: '',
  productCode: '',
  batchNo: '',
  identifierType: '',
  quantity: 1,
  status: '已生成',
  remark: ''
})
  const dialogVisible = ref(false);
  const dialogTitle = ref("新增标识");
  const form = reactive({
    productName: "",
    productCode: "",
    batchNo: "",
    identifierType: "",
    quantity: 1,
    status: "已生成",
    remark: "",
  });
const rules = {
  productName: [{ required: true, message: '请输入产品名称', trigger: 'blur' }],
  productCode: [{ required: true, message: '请输入产品编码', trigger: 'blur' }],
  batchNo: [{ required: true, message: '请输入批次号', trigger: 'blur' }],
  identifierType: [{ required: true, message: '请选择标识类型', trigger: 'change' }],
  quantity: [{ required: true, message: '请输入生成数量', trigger: 'blur' }],
  status: [{ required: true, message: '请选择状态', trigger: 'change' }]
}
  const rules = {
    productName: [{ required: true, message: "请输入产品名称", trigger: "blur" }],
    productCode: [{ required: true, message: "请输入产品编码", trigger: "blur" }],
    batchNo: [{ required: true, message: "请输入批次号", trigger: "blur" }],
    identifierType: [
      { required: true, message: "请选择标识类型", trigger: "change" },
    ],
    quantity: [{ required: true, message: "请输入生成数量", trigger: "blur" }],
    status: [{ required: true, message: "请选择状态", trigger: "change" }],
  };
const isEdit = ref(false)
const editId = ref(null)
const generateDialogVisible = ref(false)
const reassignDialogVisible = ref(false)
const currentProduct = ref({})
const generateQuantity = ref(1)
const codeRule = ref('')
const customPrefix = ref('')
const newBatchNo = ref('')
const reassignReason = ref('')
const formRef = ref()
  const isEdit = ref(false);
  const editId = ref(null);
  const generateDialogVisible = ref(false);
  const reassignDialogVisible = ref(false);
  const currentProduct = ref({});
  const generateQuantity = ref(1);
  const codeRule = ref("");
  const customPrefix = ref("");
  const newBatchNo = ref("");
  const reassignReason = ref("");
  const formRef = ref();
// 二维码相关变量
const qrCodeDialogVisible = ref(false)
const qrCodeUrl = ref('')
const currentQRProduct = ref({})
  // 二维码相关变量
  const qrCodeDialogVisible = ref(false);
  const qrCodeUrl = ref("");
  const currentQRProduct = ref({});
// 计算属性
const filteredList = computed(() => {
  let list = identifierList.value
  if (searchForm.productName) {
    list = list.filter(item => item.productName.includes(searchForm.productName))
  }
  if (searchForm.identifierType) {
    list = list.filter(item => item.identifierType === searchForm.identifierType)
  }
  if (searchForm.status) {
    list = list.filter(item => item.status === searchForm.status)
  }
  return list
})
  // 计算属性
  const filteredList = computed(() => {
    let list = identifierList.value;
    if (searchForm.productName) {
      list = list.filter(item =>
        item.productName.includes(searchForm.productName)
      );
    }
    if (searchForm.identifierType) {
      list = list.filter(
        item => item.identifierType === searchForm.identifierType
      );
    }
    if (searchForm.status) {
      list = list.filter(item => item.status === searchForm.status);
    }
    return list;
  });
// 方法
const getIdentifierTypeType = (type) => {
  const typeMap = {
    '二维码': 'success',
    '防伪码': 'warning'
  }
  return typeMap[type] || 'info'
}
  // 方法
  const getIdentifierTypeType = type => {
    const typeMap = {
      二维码: "success",
      防伪码: "warning",
    };
    return typeMap[type] || "info";
  };
const getStatusType = (status) => {
  const statusMap = {
    '已生成': 'info',
    '已分配': 'primary',
    '已使用': 'success',
    '已作废': 'danger'
  }
  return statusMap[status] || 'info'
}
  const getStatusType = status => {
    const statusMap = {
      已生成: "info",
      已分配: "primary",
      已使用: "success",
      已作废: "danger",
    };
    return statusMap[status] || "info";
  };
const handleSearch = () => {
  // 搜索逻辑已在computed中处理
}
  const handleSearch = () => {
    // 搜索逻辑已在computed中处理
  };
const resetSearch = () => {
  searchForm.productName = ''
  searchForm.identifierType = ''
  searchForm.status = ''
}
  const resetSearch = () => {
    searchForm.productName = "";
    searchForm.identifierType = "";
    searchForm.status = "";
  };
const handleAdd = () => {
  dialogTitle.value = '新增标识'
  isEdit.value = false
  form.productName = ''
  form.productCode = ''
  form.batchNo = ''
  form.identifierType = ''
  form.quantity = 1
  form.status = '已生成'
  form.remark = ''
  dialogVisible.value = true
}
  const handleAdd = () => {
    dialogTitle.value = "新增标识";
    isEdit.value = false;
    form.productName = "";
    form.productCode = "";
    form.batchNo = "";
    form.identifierType = "";
    form.quantity = 1;
    form.status = "已生成";
    form.remark = "";
    dialogVisible.value = true;
  };
const handleView = (row) => {
  // 查看标识详情
  ElMessage.info('查看标识详情功能待实现')
}
  const handleView = row => {
    // 查看标识详情
    ElMessage.info("查看标识详情功能待实现");
  };
const handleEdit = (row) => {
  dialogTitle.value = '编辑标识'
  isEdit.value = true
  editId.value = row.id
  Object.assign(form, row)
  dialogVisible.value = true
}
  const handleEdit = row => {
    dialogTitle.value = "编辑标识";
    isEdit.value = true;
    editId.value = row.id;
    Object.assign(form, row);
    dialogVisible.value = true;
  };
const handleExport = (row) => {
  // 导出标识
  ElMessage.success(`已导出标识: ${row.identifierCode}`)
}
  const handleExport = row => {
    // 导出标识
    ElMessage.success(`已导出标识: ${row.identifierCode}`);
  };
const handleReassign = (row) => {
  currentProduct.value = row
  newBatchNo.value = ''
  reassignReason.value = ''
  reassignDialogVisible.value = true
}
  const handleReassign = row => {
    currentProduct.value = row;
    newBatchNo.value = "";
    reassignReason.value = "";
    reassignDialogVisible.value = true;
  };
const handleDelete = (row) => {
  ElMessageBox.confirm('确认删除该标识吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    const index = identifierList.value.findIndex(item => item.id === row.id)
  const handleDelete = row => {
    ElMessageBox.confirm("确认删除该标识吗?", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }).then(() => {
      const index = identifierList.value.findIndex(item => item.id === row.id);
      if (index > -1) {
        identifierList.value.splice(index, 1);
        pagination.total--;
        ElMessage.success("删除成功");
      }
    });
  };
  // 生成二维码
  const generateQRCode = async row => {
    try {
      // 检查必要字段
      if (!row.productName || !row.productCode || !row.batchNo) {
        ElMessage.warning("产品信息不完整,无法生成二维码");
        return;
      }
      currentQRProduct.value = row;
      qrCodeUrl.value = "";
      qrCodeDialogVisible.value = true;
      // 构建二维码内容
      let qrContent = "";
      if (row.identifierType === "二维码") {
        qrContent = `${row.productName}|${row.productCode}|${row.batchNo}|${row.identifierCode}`;
      } else if (row.identifierType === "防伪码") {
        // 防伪码格式:SEC_产品编码_批次号_时间戳_随机数
        const timestamp = Date.now();
        const random = Math.random().toString(36).substr(2, 8);
        qrContent = `SEC_${row.productCode}_${row.batchNo}_${timestamp}_${random}`;
      }
      // 生成二维码
      qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
        width: 256,
        margin: 2,
        color: {
          dark: "#000000",
          light: "#FFFFFF",
        },
        errorCorrectionLevel: row.identifierType === "防伪码" ? "H" : "M",
      });
      ElMessage.success("二维码生成成功!");
    } catch (error) {
      console.error("生成二维码失败:", error);
      ElMessage.error("生成二维码失败:" + error.message);
      qrCodeDialogVisible.value = false;
    }
  };
  // 下载二维码
  const downloadQRCode = () => {
    if (!qrCodeUrl.value) {
      ElMessage.warning("请先生成二维码");
      return;
    }
    const a = document.createElement("a");
    a.href = qrCodeUrl.value;
    a.download = `${currentQRProduct.value.productName}_${
      currentQRProduct.value.identifierType
    }_${new Date().getTime()}.png`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    ElMessage.success("下载成功!");
  };
  // 复制二维码内容
  const copyQRContent = async () => {
    if (!currentQRProduct.value) {
      ElMessage.warning("没有可复制的内容");
      return;
    }
    try {
      let content = "";
      if (currentQRProduct.value.identifierType === "二维码") {
        content = `${currentQRProduct.value.productName}|${currentQRProduct.value.productCode}|${currentQRProduct.value.batchNo}|${currentQRProduct.value.identifierCode}`;
      } else if (currentQRProduct.value.identifierType === "防伪码") {
        const timestamp = Date.now();
        const random = Math.random().toString(36).substr(2, 8);
        content = `SEC_${currentQRProduct.value.productCode}_${currentQRProduct.value.batchNo}_${timestamp}_${random}`;
      }
      await navigator.clipboard.writeText(content);
      ElMessage.success("内容已复制到剪贴板");
    } catch (error) {
      // 降级方案
      const textArea = document.createElement("textarea");
      textArea.value = content;
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand("copy");
      document.body.removeChild(textArea);
      ElMessage.success("内容已复制到剪贴板");
    }
  };
  const generateIdentifiers = () => {
    if (!codeRule.value) {
      ElMessage.warning("请选择编码规则");
      return;
    }
    // 生成标识的逻辑
    const newIdentifiers = [];
    for (let i = 1; i <= generateQuantity.value; i++) {
      let identifierCode = "";
      if (codeRule.value === "产品编码+批次号+序号") {
        identifierCode = `${currentProduct.value.productCode}_${
          currentProduct.value.batchNo
        }_${String(i).padStart(3, "0")}`;
      } else if (codeRule.value === "时间戳+随机数") {
        identifierCode = `TS_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
      } else if (codeRule.value === "自定义规则") {
        identifierCode = `${customPrefix.value || "CUSTOM"}_${Date.now()}_${i}`;
      }
      newIdentifiers.push({
        id: Math.max(...identifierList.value.map(item => item.id)) + i,
        productName: currentProduct.value.productName,
        productCode: currentProduct.value.productCode,
        batchNo: currentProduct.value.batchNo,
        identifierType: currentProduct.value.identifierType,
        identifierCode: identifierCode,
        status: "已生成",
        generateTime: new Date().toLocaleString(),
        remark: "批量生成",
      });
    }
    identifierList.value.push(...newIdentifiers);
    pagination.total += newIdentifiers.length;
    ElMessage.success(`成功生成 ${newIdentifiers.length} 个标识`);
    generateDialogVisible.value = false;
  };
  const saveReassign = () => {
    if (!newBatchNo.value) {
      ElMessage.warning("请输入新批次号");
      return;
    }
    const index = identifierList.value.findIndex(
      item => item.id === currentProduct.value.id
    );
    if (index > -1) {
      identifierList.value.splice(index, 1)
      pagination.total--
      ElMessage.success('删除成功')
      identifierList.value[index].batchNo = newBatchNo.value;
      identifierList.value[index].status = "已分配";
      ElMessage.success("标识重新分配成功");
      reassignDialogVisible.value = false;
    }
  })
}
  };
// 生成二维码
const generateQRCode = async (row) => {
  try {
    // 检查必要字段
    if (!row.productName || !row.productCode || !row.batchNo) {
      ElMessage.warning('产品信息不完整,无法生成二维码')
      return
    }
    currentQRProduct.value = row
    qrCodeUrl.value = ''
    qrCodeDialogVisible.value = true
    // 构建二维码内容
    let qrContent = ''
    if (row.identifierType === '二维码') {
      qrContent = `${row.productName}|${row.productCode}|${row.batchNo}|${row.identifierCode}`
    } else if (row.identifierType === '防伪码') {
      // 防伪码格式:SEC_产品编码_批次号_时间戳_随机数
      const timestamp = Date.now()
      const random = Math.random().toString(36).substr(2, 8)
      qrContent = `SEC_${row.productCode}_${row.batchNo}_${timestamp}_${random}`
    }
    // 生成二维码
    qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
      width: 256,
      margin: 2,
      color: {
        dark: '#000000',
        light: '#FFFFFF'
      },
      errorCorrectionLevel: row.identifierType === '防伪码' ? 'H' : 'M'
    })
    ElMessage.success('二维码生成成功!')
  } catch (error) {
    console.error('生成二维码失败:', error)
    ElMessage.error('生成二维码失败:' + error.message)
    qrCodeDialogVisible.value = false
  }
}
  const handleSubmit = () => {
    formRef.value.validate(valid => {
      if (valid) {
        if (isEdit.value) {
          // 编辑
          const index = identifierList.value.findIndex(
            item => item.id === editId.value
          );
          if (index > -1) {
            identifierList.value[index] = { ...form, id: editId.value };
            ElMessage.success("编辑成功");
          }
        } else {
          // 新增
          const newId =
            Math.max(...identifierList.value.map(item => item.id)) + 1;
// 下载二维码
const downloadQRCode = () => {
  if (!qrCodeUrl.value) {
    ElMessage.warning('请先生成二维码')
    return
  }
  const a = document.createElement('a')
  a.href = qrCodeUrl.value
  a.download = `${currentQRProduct.value.productName}_${currentQRProduct.value.identifierType}_${new Date().getTime()}.png`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  ElMessage.success('下载成功!')
}
          // 根据标识类型生成不同的标识码
          let identifierCode = "";
          if (form.identifierType === "二维码") {
            identifierCode = `QR_${form.productCode}_${form.batchNo}_001`;
          } else if (form.identifierType === "防伪码") {
            identifierCode = `SEC_${form.productCode}_${form.batchNo}_001`;
          }
// 复制二维码内容
const copyQRContent = async () => {
  if (!currentQRProduct.value) {
    ElMessage.warning('没有可复制的内容')
    return
  }
  try {
    let content = ''
    if (currentQRProduct.value.identifierType === '二维码') {
      content = `${currentQRProduct.value.productName}|${currentQRProduct.value.productCode}|${currentQRProduct.value.batchNo}|${currentQRProduct.value.identifierCode}`
    } else if (currentQRProduct.value.identifierType === '防伪码') {
      const timestamp = Date.now()
      const random = Math.random().toString(36).substr(2, 8)
      content = `SEC_${currentQRProduct.value.productCode}_${currentQRProduct.value.batchNo}_${timestamp}_${random}`
    }
    await navigator.clipboard.writeText(content)
    ElMessage.success('内容已复制到剪贴板')
  } catch (error) {
    // 降级方案
    const textArea = document.createElement('textarea')
    textArea.value = content
    document.body.appendChild(textArea)
    textArea.select()
    document.execCommand('copy')
    document.body.removeChild(textArea)
    ElMessage.success('内容已复制到剪贴板')
  }
}
const generateIdentifiers = () => {
  if (!codeRule.value) {
    ElMessage.warning('请选择编码规则')
    return
  }
  // 生成标识的逻辑
  const newIdentifiers = []
  for (let i = 1; i <= generateQuantity.value; i++) {
    let identifierCode = ''
    if (codeRule.value === '产品编码+批次号+序号') {
      identifierCode = `${currentProduct.value.productCode}_${currentProduct.value.batchNo}_${String(i).padStart(3, '0')}`
    } else if (codeRule.value === '时间戳+随机数') {
      identifierCode = `TS_${Date.now()}_${Math.floor(Math.random() * 1000)}`
    } else if (codeRule.value === '自定义规则') {
      identifierCode = `${customPrefix.value || 'CUSTOM'}_${Date.now()}_${i}`
    }
    newIdentifiers.push({
      id: Math.max(...identifierList.value.map(item => item.id)) + i,
      productName: currentProduct.value.productName,
      productCode: currentProduct.value.productCode,
      batchNo: currentProduct.value.batchNo,
      identifierType: currentProduct.value.identifierType,
      identifierCode: identifierCode,
      status: '已生成',
      generateTime: new Date().toLocaleString(),
      remark: '批量生成'
    })
  }
  identifierList.value.push(...newIdentifiers)
  pagination.total += newIdentifiers.length
  ElMessage.success(`成功生成 ${newIdentifiers.length} 个标识`)
  generateDialogVisible.value = false
}
const saveReassign = () => {
  if (!newBatchNo.value) {
    ElMessage.warning('请输入新批次号')
    return
  }
  const index = identifierList.value.findIndex(item => item.id === currentProduct.value.id)
  if (index > -1) {
    identifierList.value[index].batchNo = newBatchNo.value
    identifierList.value[index].status = '已分配'
    ElMessage.success('标识重新分配成功')
    reassignDialogVisible.value = false
  }
}
const handleSubmit = () => {
  formRef.value.validate((valid) => {
    if (valid) {
      if (isEdit.value) {
        // 编辑
        const index = identifierList.value.findIndex(item => item.id === editId.value)
        if (index > -1) {
          identifierList.value[index] = { ...form, id: editId.value }
          ElMessage.success('编辑成功')
          identifierList.value.push({
            ...form,
            id: newId,
            identifierCode: identifierCode,
            generateTime: new Date().toLocaleString(),
          });
          pagination.total++;
          ElMessage.success("新增成功");
        }
             } else {
         // 新增
         const newId = Math.max(...identifierList.value.map(item => item.id)) + 1
         // 根据标识类型生成不同的标识码
         let identifierCode = ''
         if (form.identifierType === '二维码') {
           identifierCode = `QR_${form.productCode}_${form.batchNo}_001`
         } else if (form.identifierType === '防伪码') {
           identifierCode = `SEC_${form.productCode}_${form.batchNo}_001`
         }
         identifierList.value.push({
           ...form,
           id: newId,
           identifierCode: identifierCode,
           generateTime: new Date().toLocaleString()
         })
         pagination.total++
         ElMessage.success('新增成功')
       }
      dialogVisible.value = false
    }
  })
}
        dialogVisible.value = false;
      }
    });
  };
const handleCurrentChange = (val) => {
  pagination.currentPage = val.page
  pagination.pageSize = val.limit
}
  const handleCurrentChange = val => {
    pagination.currentPage = val.page;
    pagination.pageSize = val.limit;
  };
</script>
<style scoped>
.search-row {
  margin-bottom: 20px;
}
  .search-row {
    margin-bottom: 20px;
  }
.quick-actions-row {
  margin-bottom: 20px;
}
  .quick-actions-row {
    margin-bottom: 20px;
  }
.quick-actions-row .el-alert {
  margin-bottom: 0;
}
  .quick-actions-row .el-alert {
    margin-bottom: 0;
  }
.quick-actions-row .el-alert p {
  margin: 5px 0;
  font-size: 14px;
  line-height: 1.5;
}
  .quick-actions-row .el-alert p {
    margin: 5px 0;
    font-size: 14px;
    line-height: 1.5;
  }
/* 二维码预览样式 */
.qr-preview-container {
  text-align: center;
  padding: 20px;
}
  /* 二维码预览样式 */
  .qr-preview-container {
    text-align: center;
    padding: 20px;
  }
.qr-image-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}
  .qr-image-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
  }
.qr-image {
  max-width: 100%;
  height: auto;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
  .qr-image {
    max-width: 100%;
    height: auto;
    border: 2px solid #e0e0e0;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  }
.qr-info {
  text-align: left;
  background: #f8f9fa;
  padding: 15px;
  border-radius: 8px;
  min-width: 300px;
}
  .qr-info {
    text-align: left;
    background: #f8f9fa;
    padding: 15px;
    border-radius: 8px;
    min-width: 300px;
  }
.qr-info p {
  margin: 8px 0;
  color: #666;
  font-size: 14px;
}
  .qr-info p {
    margin: 8px 0;
    color: #666;
    font-size: 14px;
  }
.qr-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  padding: 40px 0;
}
  .qr-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 15px;
    padding: 40px 0;
  }
.qr-loading .el-icon {
  font-size: 32px;
  color: #409EFF;
}
  .qr-loading .el-icon {
    font-size: 32px;
    color: #409eff;
  }
.qr-loading p {
  color: #666;
  margin: 0;
}
  .qr-loading p {
    color: #666;
    margin: 0;
  }
</style>