|
@@ -0,0 +1,720 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="p-6">
|
|
|
|
|
+ <!-- 页面标题 -->
|
|
|
|
|
+ <div class="mb-6">
|
|
|
|
|
+ <h1 class="text-2xl font-bold text-gray-800">官网基础信息管理</h1>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 操作栏 -->
|
|
|
|
|
+ <div class="mb-4 flex justify-between items-center">
|
|
|
|
|
+ <div class="flex gap-3">
|
|
|
|
|
+ <!-- 新增按钮:仅当 tableData.length === 0 时显示 -->
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-if="tableData.length === 0"
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ @click="handleAdd"
|
|
|
|
|
+ :icon="Plus"
|
|
|
|
|
+ >
|
|
|
|
|
+ 新增
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ :disabled="selectedIds.length === 0"
|
|
|
|
|
+ @click="handleBatchDelete"
|
|
|
|
|
+ :icon="Trash2"
|
|
|
|
|
+ >
|
|
|
|
|
+ 批量删除 ({{ selectedIds.length }})
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 已去掉搜索输入框和刷新按钮 -->
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 数据表格 -->
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ v-loading="loading"
|
|
|
|
|
+ :data="tableData"
|
|
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
|
|
+ stripe
|
|
|
|
|
+ class="w-full"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-table-column type="selection" width="55" />
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column prop="companyProfile" label="公司简介" min-width="200">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <div class="truncate" :title="row.companyProfile">
|
|
|
|
|
+ {{ row.companyProfile || '-' }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column prop="companyProfileTwo" label="公司简介二" min-width="200">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <div class="truncate" :title="row.companyProfileTwo">
|
|
|
|
|
+ {{ row.companyProfileTwo || '-' }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column prop="telephone" label="电话" width="120">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <div class="flex items-center gap-1" v-if="row.telephone">
|
|
|
|
|
+ <Phone class="w-4 h-4 text-gray-500" />
|
|
|
|
|
+ {{ row.telephone }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span v-else class="text-gray-400">-</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column prop="email" label="邮箱" width="180">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <div class="flex items-center gap-1" v-if="row.email">
|
|
|
|
|
+ <Mail class="w-4 h-4 text-gray-500" />
|
|
|
|
|
+ {{ row.email }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span v-else class="text-gray-400">-</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column prop="address" label="地址" min-width="150">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <div class="flex items-center gap-1" v-if="row.address">
|
|
|
|
|
+ <MapPin class="w-4 h-4 text-gray-500" />
|
|
|
|
|
+ <span class="truncate" :title="row.address">{{ row.address }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span v-else class="text-gray-400">-</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column prop="createTime" label="创建时间" width="160">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ formatDate(row.createTime) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column label="操作" width="180" fixed="right">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <div class="flex gap-2">
|
|
|
|
|
+ <el-button size="small" type="primary" @click="handleView(row)" :icon="Eye">
|
|
|
|
|
+ 查看
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button size="small" type="warning" @click="handleEdit(row)" :icon="Edit">
|
|
|
|
|
+ 编辑
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button size="small" type="danger" @click="handleDelete(row)" :icon="Trash2">
|
|
|
|
|
+ 删除
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 分页 -->
|
|
|
|
|
+ <div class="mt-6 flex justify-center">
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ v-model:current-page="pagination.pageNum"
|
|
|
|
|
+ v-model:page-size="pagination.pageSize"
|
|
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
|
|
+ :total="pagination.total"
|
|
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
|
+ @size-change="handleSizeChange"
|
|
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 新增/编辑对话框 -->
|
|
|
|
|
+ <el-dialog
|
|
|
|
|
+ v-model="dialogVisible"
|
|
|
|
|
+ :title="dialogTitle"
|
|
|
|
|
+ width="800px"
|
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ ref="formRef"
|
|
|
|
|
+ :model="formData"
|
|
|
|
|
+ :rules="formRules"
|
|
|
|
|
+ label-width="120px"
|
|
|
|
|
+ class="pr-4"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="24">
|
|
|
|
|
+ <el-form-item label="公司简介" prop="companyProfile">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.companyProfile"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="3"
|
|
|
|
|
+ placeholder="请输入公司简介"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item label="公司简介二" prop="companyProfileTwo">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.companyProfileTwo"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="3"
|
|
|
|
|
+ placeholder="请输入公司简介二"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="24">
|
|
|
|
|
+ <el-form-item label="公司简介图片">
|
|
|
|
|
+ <el-upload
|
|
|
|
|
+ ref="companyImageUpload"
|
|
|
|
|
+ :auto-upload="false"
|
|
|
|
|
+ :show-file-list="true"
|
|
|
|
|
+ :limit="1"
|
|
|
|
|
+ accept="image/*"
|
|
|
|
|
+ @change="handleCompanyImageChange"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-button :icon="Upload">选择图片</el-button>
|
|
|
|
|
+ <template #tip>
|
|
|
|
|
+ <div class="text-gray-500 text-sm">只能上传jpg/png文件,且不超过2MB</div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-upload>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="软件简介" prop="softwareIntroduction">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.softwareIntroduction"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="2"
|
|
|
|
|
+ placeholder="请输入软件简介"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="硬件简介" prop="hardwareIntroduction">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.hardwareIntroduction"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="2"
|
|
|
|
|
+ placeholder="请输入硬件简介"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="电话" prop="telephone">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.telephone"
|
|
|
|
|
+ placeholder="请输入电话"
|
|
|
|
|
+ :prefix-icon="Phone"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="服务热线" prop="serviceHotline">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.serviceHotline"
|
|
|
|
|
+ placeholder="请输入服务热线"
|
|
|
|
|
+ :prefix-icon="Phone"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="咨询热线" prop="consultationHotline">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.consultationHotline"
|
|
|
|
|
+ placeholder="请输入咨询热线"
|
|
|
|
|
+ :prefix-icon="Phone"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="邮箱" prop="email">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.email"
|
|
|
|
|
+ placeholder="请输入邮箱"
|
|
|
|
|
+ :prefix-icon="Mail"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="地址" prop="address">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.address"
|
|
|
|
|
+ placeholder="请输入地址"
|
|
|
|
|
+ :prefix-icon="MapPin"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+
|
|
|
|
|
+ <el-col :span="24">
|
|
|
|
|
+ <el-form-item label="二维码图片">
|
|
|
|
|
+ <el-upload
|
|
|
|
|
+ ref="qrCodeUpload"
|
|
|
|
|
+ :auto-upload="false"
|
|
|
|
|
+ :show-file-list="true"
|
|
|
|
|
+ :limit="1"
|
|
|
|
|
+ accept="image/*"
|
|
|
|
|
+ @change="handleQrCodeChange"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-button :icon="Upload">选择二维码</el-button>
|
|
|
|
|
+ <template #tip>
|
|
|
|
|
+ <div class="text-gray-500 text-sm">只能上传jpg/png文件,且不超过2MB</div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-upload>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <div class="flex justify-end gap-3">
|
|
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="handleSubmit" :loading="submitLoading">
|
|
|
|
|
+ {{ isEdit ? '更新' : '保存' }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 查看详情对话框 -->
|
|
|
|
|
+ <el-dialog
|
|
|
|
|
+ v-model="viewDialogVisible"
|
|
|
|
|
+ title="查看详情"
|
|
|
|
|
+ width="700px"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="space-y-4" v-if="viewData">
|
|
|
|
|
+ <div class="grid grid-cols-2 gap-4">
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <label class="text-gray-600 text-sm">公司简介:</label>
|
|
|
|
|
+ <p class="mt-1">{{ viewData.companyProfile || '-' }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <label class="text-gray-600 text-sm">公司简介二:</label>
|
|
|
|
|
+ <p class="mt-1">{{ viewData.companyProfileTwo || '-' }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <label class="text-gray-600 text-sm">软件简介:</label>
|
|
|
|
|
+ <p class="mt-1">{{ viewData.softwareIntroduction || '-' }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <label class="text-gray-600 text-sm">硬件简介:</label>
|
|
|
|
|
+ <p class="mt-1">{{ viewData.hardwareIntroduction || '-' }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <label class="text-gray-600 text-sm">电话:</label>
|
|
|
|
|
+ <p class="mt-1">{{ viewData.telephone || '-' }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <label class="text-gray-600 text-sm">服务热线:</label>
|
|
|
|
|
+ <p class="mt-1">{{ viewData.serviceHotline || '-' }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <label class="text-gray-600 text-sm">咨询热线:</label>
|
|
|
|
|
+ <p class="mt-1">{{ viewData.consultationHotline || '-' }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <label class="text-gray-600 text-sm">邮箱:</label>
|
|
|
|
|
+ <p class="mt-1">{{ viewData.email || '-' }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <label class="text-gray-600 text-sm">地址:</label>
|
|
|
|
|
+ <p class="mt-1">{{ viewData.address || '-' }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="flex gap-4" v-if="viewData.companyProfileUrl || viewData.qrCodeUrl">
|
|
|
|
|
+ <div v-if="viewData.companyProfileUrl">
|
|
|
|
|
+ <label class="text-gray-600 text-sm">公司简介图片:</label>
|
|
|
|
|
+ <img :src="BASE_URL + viewData.companyProfileUrl" alt="公司简介" class="mt-2 max-w-48 rounded" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="viewData.qrCodeUrl">
|
|
|
|
|
+ <label class="text-gray-600 text-sm">二维码:</label>
|
|
|
|
|
+ <img :src="BASE_URL + viewData.qrCodeUrl" alt="二维码" class="mt-2 max-w-48 rounded" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import {computed, onMounted, reactive, ref} from 'vue'
|
|
|
|
|
+import {ElMessage, ElMessageBox} from 'element-plus'
|
|
|
|
|
+import {Edit, Eye, Mail, MapPin, Phone, Plus, Trash2, Upload} from 'lucide-vue-next'
|
|
|
|
|
+import request from "@/utils/request.js";
|
|
|
|
|
+
|
|
|
|
|
+// 响应式数据
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+const submitLoading = ref(false)
|
|
|
|
|
+const tableData = ref([])
|
|
|
|
|
+const selectedIds = ref([])
|
|
|
|
|
+const searchKeyword = ref('')
|
|
|
|
|
+const dialogVisible = ref(false)
|
|
|
|
|
+const viewDialogVisible = ref(false)
|
|
|
|
|
+const isEdit = ref(false)
|
|
|
|
|
+const viewData = ref(null)
|
|
|
|
|
+
|
|
|
|
|
+const BASE_URL = import.meta.env.VITE_APP_BASE_URL
|
|
|
|
|
+
|
|
|
|
|
+// 分页数据
|
|
|
|
|
+const pagination = reactive({
|
|
|
|
|
+ pageNum: 1,
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
|
+ total: 0
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 表单数据
|
|
|
|
|
+const formData = reactive({
|
|
|
|
|
+ id: '',
|
|
|
|
|
+ companyProfile: '',
|
|
|
|
|
+ companyProfileTwo: '',
|
|
|
|
|
+ softwareIntroduction: '',
|
|
|
|
|
+ hardwareIntroduction: '',
|
|
|
|
|
+ telephone: '',
|
|
|
|
|
+ serviceHotline: '',
|
|
|
|
|
+ consultationHotline: '',
|
|
|
|
|
+ email: '',
|
|
|
|
|
+ address: ''
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 文件数据
|
|
|
|
|
+const companyImageFile = ref(null)
|
|
|
|
|
+const qrCodeFile = ref(null)
|
|
|
|
|
+
|
|
|
|
|
+// 表单引用
|
|
|
|
|
+const formRef = ref(null)
|
|
|
|
|
+const companyImageUpload = ref(null)
|
|
|
|
|
+const qrCodeUpload = ref(null)
|
|
|
|
|
+
|
|
|
|
|
+// 表单验证规则
|
|
|
|
|
+const formRules = {
|
|
|
|
|
+ companyProfile: [
|
|
|
|
|
+ { required: true, message: '请输入公司简介', trigger: 'blur' }
|
|
|
|
|
+ ],
|
|
|
|
|
+ email: [
|
|
|
|
|
+ { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 计算属性
|
|
|
|
|
+const dialogTitle = computed(() => {
|
|
|
|
|
+ return isEdit.value ? '编辑基础信息' : '新增基础信息'
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 获取列表数据
|
|
|
|
|
+const getList = async () => {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = await apiGetList(pagination.pageNum, pagination.pageSize)
|
|
|
|
|
+ if (data) {
|
|
|
|
|
+ tableData.value = data.records || []
|
|
|
|
|
+ pagination.total = data.total || 0
|
|
|
|
|
+ }
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 事件处理函数
|
|
|
|
|
+const handleAdd = () => {
|
|
|
|
|
+ isEdit.value = false
|
|
|
|
|
+ resetForm()
|
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleEdit = async (row) => {
|
|
|
|
|
+ isEdit.value = true
|
|
|
|
|
+ const data = await getById(row.id)
|
|
|
|
|
+ if (data) {
|
|
|
|
|
+ Object.assign(formData, data)
|
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleView = async (row) => {
|
|
|
|
|
+ const data = await getById(row.id)
|
|
|
|
|
+ if (data) {
|
|
|
|
|
+ viewData.value = data
|
|
|
|
|
+ viewDialogVisible.value = true
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleDelete = async (row) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await ElMessageBox.confirm(
|
|
|
|
|
+ '确定要删除这条记录吗?',
|
|
|
|
|
+ '删除确认',
|
|
|
|
|
+ {
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ cancelButtonText: '取消',
|
|
|
|
|
+ type: 'warning'
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ const success = await batchDelete([row.id])
|
|
|
|
|
+ if (success) {
|
|
|
|
|
+ await getList()
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ // 用户取消删除
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleBatchDelete = async () => {
|
|
|
|
|
+ if (selectedIds.value.length === 0) {
|
|
|
|
|
+ ElMessage.warning('请选择要删除的记录')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ await ElMessageBox.confirm(
|
|
|
|
|
+ `确定要删除选中的 ${selectedIds.value.length} 条记录吗?`,
|
|
|
|
|
+ '批量删除确认',
|
|
|
|
|
+ {
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ cancelButtonText: '取消',
|
|
|
|
|
+ type: 'warning'
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ const success = await batchDelete(selectedIds.value)
|
|
|
|
|
+ if (success) {
|
|
|
|
|
+ selectedIds.value = []
|
|
|
|
|
+ await getList()
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ // 用户取消删除
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleSelectionChange = (selection) => {
|
|
|
|
|
+ selectedIds.value = selection.map(item => item.id)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleSearch = () => {
|
|
|
|
|
+ // 这里可以实现搜索逻辑
|
|
|
|
|
+ // 由于接口没有提供搜索参数,这里只是演示
|
|
|
|
|
+ console.log('搜索关键词:', searchKeyword.value)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const refreshList = () => {
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleSizeChange = (size) => {
|
|
|
|
|
+ pagination.pageSize = size
|
|
|
|
|
+ pagination.pageNum = 1
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleCurrentChange = (page) => {
|
|
|
|
|
+ pagination.pageNum = page
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleCompanyImageChange = (file) => {
|
|
|
|
|
+ companyImageFile.value = file.raw
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleQrCodeChange = (file) => {
|
|
|
|
|
+ qrCodeFile.value = file.raw
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleSubmit = async () => {
|
|
|
|
|
+ if (!formRef.value) return
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ await formRef.value.validate()
|
|
|
|
|
+
|
|
|
|
|
+ submitLoading.value = true
|
|
|
|
|
+
|
|
|
|
|
+ // 构建FormData
|
|
|
|
|
+ const submitFormData = new FormData()
|
|
|
|
|
+
|
|
|
|
|
+ if (isEdit.value) {
|
|
|
|
|
+ submitFormData.append('id', formData.id)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ submitFormData.append('companyProfile', formData.companyProfile || '')
|
|
|
|
|
+ submitFormData.append('companyProfileTwo', formData.companyProfileTwo || '')
|
|
|
|
|
+ submitFormData.append('softwareIntroduction', formData.softwareIntroduction || '')
|
|
|
|
|
+ submitFormData.append('hardwareIntroduction', formData.hardwareIntroduction || '')
|
|
|
|
|
+ submitFormData.append('telephone', formData.telephone || '')
|
|
|
|
|
+ submitFormData.append('serviceHotline', formData.serviceHotline || '')
|
|
|
|
|
+ submitFormData.append('consultationHotline', formData.consultationHotline || '')
|
|
|
|
|
+ submitFormData.append('email', formData.email || '')
|
|
|
|
|
+ submitFormData.append('address', formData.address || '')
|
|
|
|
|
+
|
|
|
|
|
+ // 添加文件
|
|
|
|
|
+ if (companyImageFile.value) {
|
|
|
|
|
+ submitFormData.append('companyProMultipartFile', companyImageFile.value)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (qrCodeFile.value) {
|
|
|
|
|
+ submitFormData.append('qrCodeMultipartFile', qrCodeFile.value)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let success = false
|
|
|
|
|
+ if (isEdit.value) {
|
|
|
|
|
+ success = await update(submitFormData)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ success = await save(submitFormData)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (success) {
|
|
|
|
|
+ dialogVisible.value = false
|
|
|
|
|
+ await getList()
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('表单验证失败:', error)
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ submitLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const resetForm = () => {
|
|
|
|
|
+ Object.assign(formData, {
|
|
|
|
|
+ id: '',
|
|
|
|
|
+ companyProfile: '',
|
|
|
|
|
+ companyProfileTwo: '',
|
|
|
|
|
+ softwareIntroduction: '',
|
|
|
|
|
+ hardwareIntroduction: '',
|
|
|
|
|
+ telephone: '',
|
|
|
|
|
+ serviceHotline: '',
|
|
|
|
|
+ consultationHotline: '',
|
|
|
|
|
+ email: '',
|
|
|
|
|
+ address: ''
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ companyImageFile.value = null
|
|
|
|
|
+ qrCodeFile.value = null
|
|
|
|
|
+
|
|
|
|
|
+ // 清空上传组件
|
|
|
|
|
+ if (companyImageUpload.value) {
|
|
|
|
|
+ companyImageUpload.value.clearFiles()
|
|
|
|
|
+ }
|
|
|
|
|
+ if (qrCodeUpload.value) {
|
|
|
|
|
+ qrCodeUpload.value.clearFiles()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (formRef.value) {
|
|
|
|
|
+ formRef.value.resetFields()
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const formatDate = (dateString) => {
|
|
|
|
|
+ if (!dateString) return '-'
|
|
|
|
|
+ return new Date(dateString).toLocaleString('zh-CN')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 获取分页列表
|
|
|
|
|
+const apiGetList = async (pageNum = 1, pageSize = 10) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await request.get("/basicInfo/findByPage", {
|
|
|
|
|
+ params: {
|
|
|
|
|
+ pageNum,
|
|
|
|
|
+ pageSize,
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+ return res.data
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error("获取列表失败")
|
|
|
|
|
+ console.error(error)
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 根据ID获取详情
|
|
|
|
|
+const getById = async (id) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await request.get("/basicInfo/getById/" + id)
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+ return res.data
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error("获取详情失败")
|
|
|
|
|
+ console.error(error)
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 保存数据
|
|
|
|
|
+const save = async (formData) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await request.post("/basicInfo/save", formData, {
|
|
|
|
|
+ headers: {
|
|
|
|
|
+ "Content-Type": "multipart/form-data",
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ ElMessage.success(res.msg)
|
|
|
|
|
+ return true
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error("保存失败")
|
|
|
|
|
+ console.error(error)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 更新数据
|
|
|
|
|
+const update = async (formData) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await request.post("/basicInfo/update", formData, {
|
|
|
|
|
+ headers: {
|
|
|
|
|
+ "Content-Type": "multipart/form-data",
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ ElMessage.success(res.msg)
|
|
|
|
|
+ return true
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error("更新失败")
|
|
|
|
|
+ console.error(error)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 批量删除
|
|
|
|
|
+const batchDelete = async (ids) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await request.post("/basicInfo/deleteBatch", ids)
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ ElMessage.success(res.msg)
|
|
|
|
|
+ return true
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error("删除失败")
|
|
|
|
|
+ console.error(error)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 生命周期
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ getList()
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.truncate {
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|