fix返回用户管理筛选
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
<template #stats v-if="singleUserMode">
|
<template #stats v-if="singleUserMode">
|
||||||
<div class="flex items-center gap-2 text-sm text-gray-600">
|
<div class="flex items-center gap-2 text-sm text-gray-600">
|
||||||
<User class="w-4 h-4" />
|
<User class="w-4 h-4" />
|
||||||
<span>当前用户:{{ currentUser?.company_name || currentUser?.phone }}</span>
|
<span>当前用户:{{ currentUser?.enterprise_info?.company_name || currentUser?.phone }}</span>
|
||||||
<span class="text-gray-400">(仅显示当前用户)</span>
|
<span class="text-gray-400">(仅显示当前用户)</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="flex items-center gap-2 text-sm text-gray-600">
|
<div class="flex items-center gap-2 text-sm text-gray-600">
|
||||||
<User class="w-4 h-4" />
|
<User class="w-4 h-4" />
|
||||||
<span>{{ currentUser?.company_name || currentUser?.phone }}</span>
|
<span>{{ currentUser?.enterprise_info?.company_name || currentUser?.phone }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-button size="small" @click="exitSingleUserMode">
|
<el-button size="small" @click="exitSingleUserMode">
|
||||||
<Close class="w-4 h-4 mr-1" />
|
<Close class="w-4 h-4 mr-1" />
|
||||||
@@ -622,7 +622,22 @@ const exitSingleUserMode = () => {
|
|||||||
|
|
||||||
// 返回用户管理
|
// 返回用户管理
|
||||||
const goBackToUsers = () => {
|
const goBackToUsers = () => {
|
||||||
router.push({ name: 'AdminUsers' })
|
const query = { user_id: currentUser.value?.id }
|
||||||
|
|
||||||
|
// 如果当前用户有企业名称,添加到查询参数
|
||||||
|
if (currentUser.value?.enterprise_info?.company_name) {
|
||||||
|
query.company_name = currentUser.value.enterprise_info.company_name
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果当前用户有手机号,添加到查询参数
|
||||||
|
if (currentUser.value?.phone) {
|
||||||
|
query.phone = currentUser.value.phone
|
||||||
|
}
|
||||||
|
console.log('query', query)
|
||||||
|
router.push({
|
||||||
|
name: 'AdminUsers',
|
||||||
|
query
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查看详情
|
// 查看详情
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<el-icon class="user-icon"><user /></el-icon>
|
<el-icon class="user-icon"><user /></el-icon>
|
||||||
<div class="user-details">
|
<div class="user-details">
|
||||||
<div class="company-name">{{ currentUser?.company_name || '未知公司' }}</div>
|
<div class="company-name">{{ currentUser?.enterprise_info?.company_name || '未知公司' }}</div>
|
||||||
<div class="user-phone">{{ currentUser?.phone || '-' }}</div>
|
<div class="user-phone">{{ currentUser?.phone || '-' }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -727,7 +727,22 @@ const exitSingleUserMode = () => {
|
|||||||
|
|
||||||
// 返回用户管理
|
// 返回用户管理
|
||||||
const goBackToUsers = () => {
|
const goBackToUsers = () => {
|
||||||
router.push({ name: 'AdminUsers' })
|
const query = { user_id: currentUser.value?.id }
|
||||||
|
|
||||||
|
// 如果当前用户有手机号,添加到查询参数
|
||||||
|
if (currentUser.value?.phone) {
|
||||||
|
query.phone = currentUser.value.phone
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果当前用户有企业名称,添加到查询参数
|
||||||
|
if (currentUser.value?.enterprise_info?.company_name) {
|
||||||
|
query.company_name = currentUser.value.enterprise_info.company_name
|
||||||
|
}
|
||||||
|
|
||||||
|
router.push({
|
||||||
|
name: 'AdminUsers',
|
||||||
|
query
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听路由变化
|
// 监听路由变化
|
||||||
|
|||||||
@@ -516,7 +516,23 @@ const exitSingleUserMode = () => {
|
|||||||
|
|
||||||
// 返回用户管理
|
// 返回用户管理
|
||||||
const goBackToUsers = () => {
|
const goBackToUsers = () => {
|
||||||
router.push({ name: 'AdminUsers' })
|
const query = { user_id: currentUser.value?.id }
|
||||||
|
|
||||||
|
// 如果当前用户有手机号,添加到查询参数
|
||||||
|
if (currentUser.value?.phone) {
|
||||||
|
query.phone = currentUser.value.phone
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果当前用户有企业名称,添加到查询参数
|
||||||
|
if (currentUser.value?.enterprise_info?.company_name) {
|
||||||
|
query.company_name = currentUser.value.enterprise_info.company_name
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
router.push({
|
||||||
|
name: 'AdminUsers',
|
||||||
|
query
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查看详情
|
// 查看详情
|
||||||
|
|||||||
666
src/pages/admin/ui-components/index.vue
Normal file
666
src/pages/admin/ui-components/index.vue
Normal file
@@ -0,0 +1,666 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ui-components-page">
|
||||||
|
<el-card class="filter-card">
|
||||||
|
<el-form :model="filterForm" inline>
|
||||||
|
<el-form-item label="关键词">
|
||||||
|
<el-input
|
||||||
|
v-model="filterForm.keyword"
|
||||||
|
placeholder="请输入关键词搜索"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleSearch"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-select v-model="filterForm.is_active" placeholder="请选择状态" clearable>
|
||||||
|
<el-option label="启用" :value="true" />
|
||||||
|
<el-option label="禁用" :value="false" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||||
|
<el-button @click="handleReset">重置</el-button>
|
||||||
|
<el-button type="success" @click="handleCreate">新增UI组件</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card class="table-card">
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="componentList"
|
||||||
|
stripe
|
||||||
|
border
|
||||||
|
>
|
||||||
|
<el-table-column prop="component_code" label="组件编码" width="150" />
|
||||||
|
<el-table-column prop="component_name" label="组件名称" width="200" />
|
||||||
|
<el-table-column prop="description" label="描述" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="version" label="版本" width="100" />
|
||||||
|
<el-table-column label="文件状态" width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag v-if="row.is_extracted" type="success">已解压</el-tag>
|
||||||
|
<el-tag v-else-if="row.file_path" type="warning">已上传</el-tag>
|
||||||
|
<el-tag v-else type="info">未上传</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="文件大小" width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span v-if="row.file_size">{{ formatFileSize(row.file_size) }}</span>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态" width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="row.is_active ? 'success' : 'danger'">
|
||||||
|
{{ row.is_active ? '启用' : '禁用' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="sort_order" label="排序" width="80" />
|
||||||
|
<el-table-column prop="created_at" label="创建时间" width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatDateTime(row.created_at) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="320" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button size="small" @click="handleEdit(row)">编辑</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="!row.file_path"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="handleUpload(row)"
|
||||||
|
>
|
||||||
|
上传文件
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="row.file_path && !row.is_extracted"
|
||||||
|
size="small"
|
||||||
|
type="warning"
|
||||||
|
@click="handleUploadExtract(row)"
|
||||||
|
>
|
||||||
|
上传并解压
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="row.is_extracted"
|
||||||
|
size="small"
|
||||||
|
type="success"
|
||||||
|
@click="handleViewFolder(row)"
|
||||||
|
>
|
||||||
|
查看文件夹
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="row.file_path"
|
||||||
|
size="small"
|
||||||
|
type="info"
|
||||||
|
@click="handleDownload(row)"
|
||||||
|
>
|
||||||
|
下载文件
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="row.is_extracted"
|
||||||
|
size="small"
|
||||||
|
type="danger"
|
||||||
|
@click="handleDeleteFolder(row)"
|
||||||
|
>
|
||||||
|
删除文件夹
|
||||||
|
</el-button>
|
||||||
|
<el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="pagination-container">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="pagination.page"
|
||||||
|
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-card>
|
||||||
|
|
||||||
|
<!-- 创建/编辑对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="dialogTitle"
|
||||||
|
width="600px"
|
||||||
|
@close="handleDialogClose"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
>
|
||||||
|
<el-form-item label="组件编码" prop="component_code">
|
||||||
|
<el-input
|
||||||
|
v-model="form.component_code"
|
||||||
|
:disabled="isEdit"
|
||||||
|
placeholder="请输入组件编码"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="组件名称" prop="component_name">
|
||||||
|
<el-input v-model="form.component_name" placeholder="请输入组件名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="描述">
|
||||||
|
<el-input
|
||||||
|
v-model="form.description"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="请输入组件描述"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="版本">
|
||||||
|
<el-input v-model="form.version" placeholder="请输入版本号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-switch v-model="form.is_active" active-text="启用" inactive-text="禁用" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排序">
|
||||||
|
<el-input-number v-model="form.sort_order" :min="0" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmit" :loading="submitting">
|
||||||
|
确定
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 文件上传对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="uploadDialogVisible"
|
||||||
|
:title="uploadDialogTitle"
|
||||||
|
width="500px"
|
||||||
|
>
|
||||||
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
:auto-upload="false"
|
||||||
|
:limit="1"
|
||||||
|
accept=".zip"
|
||||||
|
:on-change="handleFileChange"
|
||||||
|
:on-remove="handleFileRemove"
|
||||||
|
drag
|
||||||
|
>
|
||||||
|
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||||
|
<div class="el-upload__text">
|
||||||
|
将文件拖到此处,或<em>点击上传</em>
|
||||||
|
</div>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip">
|
||||||
|
只能上传zip文件,且不超过100MB
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="uploadDialogVisible = false">取消</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="handleFileSubmit"
|
||||||
|
:loading="uploading"
|
||||||
|
:disabled="!selectedFile"
|
||||||
|
>
|
||||||
|
上传
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 文件夹内容预览对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="folderDialogVisible"
|
||||||
|
:title="folderDialogTitle"
|
||||||
|
width="800px"
|
||||||
|
>
|
||||||
|
<el-tree
|
||||||
|
:data="folderTree"
|
||||||
|
:props="defaultProps"
|
||||||
|
default-expand-all
|
||||||
|
show-checkbox
|
||||||
|
node-key="path"
|
||||||
|
>
|
||||||
|
<template #default="{ node, data }">
|
||||||
|
<span class="custom-tree-node">
|
||||||
|
<el-icon>
|
||||||
|
<folder v-if="data.type === 'folder'" />
|
||||||
|
<document v-else />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ data.name }}</span>
|
||||||
|
<span class="file-size">({{ formatSize(data.size) }})</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="folderDialogVisible = false">关闭</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { uiComponentApi } from '@/api/ui-component'
|
||||||
|
import { Document, Folder, UploadFilled } from '@element-plus/icons-vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { computed, onMounted, reactive, ref } from 'vue'
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const loading = ref(false)
|
||||||
|
const componentList = ref([])
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const uploadDialogVisible = ref(false)
|
||||||
|
const folderDialogVisible = ref(false)
|
||||||
|
const submitting = ref(false)
|
||||||
|
const uploading = ref(false)
|
||||||
|
const isEdit = ref(false)
|
||||||
|
const currentComponent = ref(null)
|
||||||
|
const selectedFile = ref(null)
|
||||||
|
const formRef = ref(null)
|
||||||
|
const uploadRef = ref(null)
|
||||||
|
const folderTree = ref([])
|
||||||
|
|
||||||
|
// 筛选表单
|
||||||
|
const filterForm = reactive({
|
||||||
|
keyword: '',
|
||||||
|
is_active: null
|
||||||
|
})
|
||||||
|
|
||||||
|
// 分页数据
|
||||||
|
const pagination = reactive({
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const form = reactive({
|
||||||
|
id: '',
|
||||||
|
component_code: '',
|
||||||
|
component_name: '',
|
||||||
|
description: '',
|
||||||
|
version: '',
|
||||||
|
is_active: true,
|
||||||
|
sort_order: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const formRules = {
|
||||||
|
component_code: [
|
||||||
|
{ required: true, message: '请输入组件编码', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
component_name: [
|
||||||
|
{ required: true, message: '请输入组件名称', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 树形组件默认属性
|
||||||
|
const defaultProps = {
|
||||||
|
children: 'children',
|
||||||
|
label: 'name'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算属性
|
||||||
|
const dialogTitle = computed(() => isEdit.value ? '编辑UI组件' : '新增UI组件')
|
||||||
|
const uploadDialogTitle = computed(() => `上传文件 - ${currentComponent.value?.component_name || ''}`)
|
||||||
|
const folderDialogTitle = computed(() => `文件夹内容 - ${currentComponent.value?.component_name || ''}`)
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
const fetchComponentList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
page: pagination.page,
|
||||||
|
page_size: pagination.pageSize,
|
||||||
|
keyword: filterForm.keyword,
|
||||||
|
is_active: filterForm.is_active
|
||||||
|
}
|
||||||
|
const response = await uiComponentApi.getUIComponentList(params)
|
||||||
|
componentList.value = response.data.components
|
||||||
|
pagination.total = response.data.total
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取UI组件列表失败')
|
||||||
|
console.error('获取UI组件列表失败:', error)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
pagination.page = 1
|
||||||
|
fetchComponentList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
filterForm.keyword = ''
|
||||||
|
filterForm.is_active = null
|
||||||
|
pagination.page = 1
|
||||||
|
fetchComponentList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
pagination.pageSize = val
|
||||||
|
pagination.page = 1
|
||||||
|
fetchComponentList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (val) => {
|
||||||
|
pagination.page = val
|
||||||
|
fetchComponentList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCreate = () => {
|
||||||
|
isEdit.value = false
|
||||||
|
resetForm()
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEdit = (row) => {
|
||||||
|
isEdit.value = true
|
||||||
|
currentComponent.value = row
|
||||||
|
Object.assign(form, {
|
||||||
|
id: row.id,
|
||||||
|
component_code: row.component_code,
|
||||||
|
component_name: row.component_name,
|
||||||
|
description: row.description,
|
||||||
|
version: row.version,
|
||||||
|
is_active: row.is_active,
|
||||||
|
sort_order: row.sort_order
|
||||||
|
})
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要删除UI组件"${row.component_name}"吗?`,
|
||||||
|
'删除确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}
|
||||||
|
).then(async () => {
|
||||||
|
try {
|
||||||
|
await uiComponentApi.deleteUIComponent(row.id)
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
fetchComponentList()
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('删除失败')
|
||||||
|
console.error('删除UI组件失败:', error)
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消删除
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!formRef.value) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
await formRef.value.validate()
|
||||||
|
submitting.value = true
|
||||||
|
|
||||||
|
if (isEdit.value) {
|
||||||
|
await uiComponentApi.updateUIComponent(form.id, form)
|
||||||
|
ElMessage.success('更新成功')
|
||||||
|
} else {
|
||||||
|
await uiComponentApi.createUIComponent(form)
|
||||||
|
ElMessage.success('创建成功')
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogVisible.value = false
|
||||||
|
fetchComponentList()
|
||||||
|
} catch (error) {
|
||||||
|
if (error !== false) { // 不是表单验证错误
|
||||||
|
ElMessage.error(isEdit.value ? '更新失败' : '创建失败')
|
||||||
|
console.error('提交UI组件失败:', error)
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDialogClose = () => {
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
Object.assign(form, {
|
||||||
|
id: '',
|
||||||
|
component_code: '',
|
||||||
|
component_name: '',
|
||||||
|
description: '',
|
||||||
|
version: '',
|
||||||
|
is_active: true,
|
||||||
|
sort_order: 0
|
||||||
|
})
|
||||||
|
if (formRef.value) {
|
||||||
|
formRef.value.resetFields()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUpload = (row) => {
|
||||||
|
currentComponent.value = row
|
||||||
|
selectedFile.value = null
|
||||||
|
if (uploadRef.value) {
|
||||||
|
uploadRef.value.clearFiles()
|
||||||
|
}
|
||||||
|
uploadDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUploadExtract = (row) => {
|
||||||
|
currentComponent.value = row
|
||||||
|
selectedFile.value = null
|
||||||
|
if (uploadRef.value) {
|
||||||
|
uploadRef.value.clearFiles()
|
||||||
|
}
|
||||||
|
uploadDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFileChange = (file) => {
|
||||||
|
selectedFile.value = file.raw
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFileRemove = () => {
|
||||||
|
selectedFile.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFileSubmit = async () => {
|
||||||
|
if (!selectedFile.value) {
|
||||||
|
ElMessage.warning('请选择要上传的文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uploading.value = true
|
||||||
|
try {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', selectedFile.value)
|
||||||
|
|
||||||
|
// 根据当前组件是否已解压决定使用哪个接口
|
||||||
|
if (currentComponent.value.is_extracted) {
|
||||||
|
// 已解压,使用普通上传接口
|
||||||
|
await uiComponentApi.uploadUIComponentFile(currentComponent.value.id, formData)
|
||||||
|
ElMessage.success('文件上传成功')
|
||||||
|
} else {
|
||||||
|
// 未解压,使用上传并解压接口
|
||||||
|
await uiComponentApi.uploadAndExtractUIComponentFile(currentComponent.value.id, formData)
|
||||||
|
ElMessage.success('文件上传并解压成功')
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadDialogVisible.value = false
|
||||||
|
fetchComponentList()
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('文件上传失败')
|
||||||
|
console.error('上传UI组件文件失败:', error)
|
||||||
|
} finally {
|
||||||
|
uploading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDownload = async (row) => {
|
||||||
|
try {
|
||||||
|
const response = await uiComponentApi.downloadUIComponentFile(row.id)
|
||||||
|
|
||||||
|
// 创建下载链接
|
||||||
|
const url = window.URL.createObjectURL(new Blob([response.data]))
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = url
|
||||||
|
link.setAttribute('download', `${row.component_name}.zip`)
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('文件下载失败')
|
||||||
|
console.error('下载UI组件文件失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleViewFolder = async (row) => {
|
||||||
|
try {
|
||||||
|
const response = await uiComponentApi.getUIComponentFolderContent(row.id)
|
||||||
|
folderTree.value = buildTree(response.data)
|
||||||
|
currentComponent.value = row
|
||||||
|
folderDialogVisible.value = true
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取文件夹内容失败')
|
||||||
|
console.error('获取UI组件文件夹内容失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeleteFolder = (row) => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要删除UI组件"${row.component_name}"的文件夹吗?`,
|
||||||
|
'删除确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}
|
||||||
|
).then(async () => {
|
||||||
|
try {
|
||||||
|
await uiComponentApi.deleteUIComponentFolder(row.id)
|
||||||
|
ElMessage.success('文件夹删除成功')
|
||||||
|
fetchComponentList()
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('文件夹删除失败')
|
||||||
|
console.error('删除UI组件文件夹失败:', error)
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消删除
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建树形结构
|
||||||
|
const buildTree = (files) => {
|
||||||
|
const tree = []
|
||||||
|
const pathMap = {}
|
||||||
|
|
||||||
|
// 先创建所有节点
|
||||||
|
files.forEach(file => {
|
||||||
|
const parts = file.path.split('/')
|
||||||
|
let currentPath = ''
|
||||||
|
|
||||||
|
parts.forEach((part, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
currentPath = part
|
||||||
|
} else {
|
||||||
|
currentPath = currentPath + '/' + part
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pathMap[currentPath]) {
|
||||||
|
pathMap[currentPath] = {
|
||||||
|
name: part,
|
||||||
|
path: file.path,
|
||||||
|
type: index === parts.length - 1 ? file.type : 'folder',
|
||||||
|
size: index === parts.length - 1 ? file.size : 0,
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 构建树形结构
|
||||||
|
Object.keys(pathMap).forEach(path => {
|
||||||
|
const node = pathMap[path]
|
||||||
|
const parentPath = path.substring(0, path.lastIndexOf('/'))
|
||||||
|
|
||||||
|
if (parentPath && pathMap[parentPath]) {
|
||||||
|
pathMap[parentPath].children.push(node)
|
||||||
|
} else if (!parentPath) {
|
||||||
|
tree.push(node)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return tree
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatFileSize = (bytes) => {
|
||||||
|
if (bytes === 0) return '0 B'
|
||||||
|
const k = 1024
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB']
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||||
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatSize = (size) => {
|
||||||
|
return formatFileSize(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDateTime = (dateTime) => {
|
||||||
|
if (!dateTime) return ''
|
||||||
|
const date = new Date(dateTime)
|
||||||
|
return date.toLocaleString('zh-CN')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生命周期
|
||||||
|
onMounted(() => {
|
||||||
|
fetchComponentList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.ui-components-page {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-card {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-card {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-tree-node {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-size {
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -645,7 +645,7 @@ import ListPageLayout from '@/components/common/ListPageLayout.vue'
|
|||||||
import { useMobileTable } from '@/composables/useMobileTable'
|
import { useMobileTable } from '@/composables/useMobileTable'
|
||||||
import { ArrowDown, Document, Money, Tickets, Wallet, Warning } from '@element-plus/icons-vue'
|
import { ArrowDown, Document, Money, Tickets, Wallet, Warning } from '@element-plus/icons-vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
// 获取路由实例
|
// 获取路由实例
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -723,6 +723,21 @@ let searchTimer = null
|
|||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 检查是否有从交易页面传来的查询参数
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
// 如果有企业名称参数,设置为搜索条件
|
||||||
|
if (route.query.company_name) {
|
||||||
|
filters.company_name = route.query.company_name
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有手机号参数,设置为搜索条件
|
||||||
|
if (route.query.phone) {
|
||||||
|
filters.phone = route.query.phone
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loadUsers()
|
loadUsers()
|
||||||
loadStats()
|
loadStats()
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user