实现国资管理框架,资产清查数据获取
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -166,3 +166,5 @@ coverage
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
/src/components/*
|
||||
@@ -218,35 +218,41 @@ const router = createRouter({
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/admin/business',
|
||||
name: 'admin-business',
|
||||
component: () => import('../views/Admin/BusinessManagementView.vue'),
|
||||
path: '/admin/business/state-assets',
|
||||
name: 'admin-business-state-assets',
|
||||
component: () => import('../views/Admin/Business/StateAssetsView.vue'),
|
||||
meta: { requiresAuth: true }
|
||||
},
|
||||
{
|
||||
path: '/admin/business/state-assets/main',
|
||||
name: 'admin-business-state-assets-main',
|
||||
component: () => import('../views/Admin/Business/StateAssetsMainView.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
redirect: '/admin/business/state-assets'
|
||||
redirect: '/admin/business/state-assets/main/province-check'
|
||||
},
|
||||
{
|
||||
path: 'state-assets',
|
||||
name: 'admin-business-state-assets',
|
||||
component: () => import('../views/Admin/Business/StateAssetsView.vue'),
|
||||
meta: { requiresAuth: true }
|
||||
},
|
||||
{
|
||||
path: 'library',
|
||||
name: 'admin-business-library',
|
||||
component: () => import('../views/Admin/Business/LibraryView.vue'),
|
||||
meta: { requiresAuth: true }
|
||||
},
|
||||
{
|
||||
path: 'laboratory',
|
||||
name: 'admin-business-laboratory',
|
||||
component: () => import('../views/Admin/Business/LaboratoryView.vue'),
|
||||
path: 'province-check',
|
||||
name: 'admin-business-state-assets-province-check',
|
||||
component: () => import('../views/Admin/Business/ProvinceAssetsCheckView.vue'),
|
||||
meta: { requiresAuth: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/admin/business/library',
|
||||
name: 'admin-business-library',
|
||||
component: () => import('../views/Admin/Business/LibraryView.vue'),
|
||||
meta: { requiresAuth: true }
|
||||
},
|
||||
{
|
||||
path: '/admin/business/laboratory',
|
||||
name: 'admin-business-laboratory',
|
||||
component: () => import('../views/Admin/Business/LaboratoryView.vue'),
|
||||
meta: { requiresAuth: true }
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
@@ -275,10 +281,10 @@ const router = createRouter({
|
||||
// 路由守卫
|
||||
router.beforeEach((to, from, next) => {
|
||||
const authStore = useAuthStore()
|
||||
|
||||
|
||||
// 初始化认证状态
|
||||
authStore.initAuth()
|
||||
|
||||
|
||||
// 检查是否需要认证
|
||||
if (to.meta.requiresAuth) {
|
||||
if (authStore.isLoggedIn && authStore.checkToken()) {
|
||||
|
||||
224
src/services/assetsApi.js
Normal file
224
src/services/assetsApi.js
Normal file
@@ -0,0 +1,224 @@
|
||||
/**
|
||||
* 资产清查API服务
|
||||
* 基于参考文件 zcqc2025.js 的API调用逻辑
|
||||
*/
|
||||
|
||||
// API基础配置
|
||||
const API_BASE_URL = 'https://www.tcjwj.com/sz/logintest/jwjDataService.asmx'
|
||||
const TABLE_NAME = 'Zcqc_2025_Zckp'
|
||||
|
||||
/**
|
||||
* 解析API返回的数据
|
||||
* @param {string} data - API返回的原始数据
|
||||
* @returns {Array} 解析后的JSON数组
|
||||
*/
|
||||
function parseApiResponse(data) {
|
||||
try {
|
||||
const startIndex = data.indexOf('[')
|
||||
const endIndex = data.indexOf(']</string>')
|
||||
if (startIndex === -1 || endIndex === -1) {
|
||||
console.error('API响应格式错误:', data)
|
||||
return []
|
||||
}
|
||||
return JSON.parse(data.slice(startIndex, endIndex + 1))
|
||||
} catch (error) {
|
||||
console.error('解析API响应失败:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询条件JSON字符串
|
||||
* @param {string} tabType - 标签类型 (all, uncheck, nochange, profit, loss, adjust, error)
|
||||
* @param {string} quickSearch - 快速搜索关键词
|
||||
* @returns {string} 查询条件JSON字符串
|
||||
*/
|
||||
function buildSearchJson(tabType = 'all', quickSearch = '') {
|
||||
let searchJson = '[{"column":"ID","operator":">=","value":"0"}'
|
||||
|
||||
// 根据标签类型添加过滤条件
|
||||
switch (tabType) {
|
||||
case 'uncheck':
|
||||
searchJson += ',{"column":"PdTypes","operator":"=","value":""}'
|
||||
break
|
||||
case 'nochange':
|
||||
searchJson += ',{"column":"PdTypes","operator":"=","value":"无盈亏"}'
|
||||
break
|
||||
case 'profit':
|
||||
searchJson += ',{"column":"PdTypes","operator":"=","value":"盘盈"}'
|
||||
break
|
||||
case 'loss':
|
||||
searchJson += ',{"column":"PdTypes","operator":"=","value":"损失"}'
|
||||
break
|
||||
case 'adjust':
|
||||
searchJson += ',{"column":"PdTypes","operator":"=","value":"错账调整"}'
|
||||
break
|
||||
case 'error':
|
||||
searchJson += ',{"column":"PdTypes","operator":"=","value":"错误待处理"}'
|
||||
break
|
||||
// 'all' 不需要额外条件
|
||||
}
|
||||
|
||||
// 添加快速搜索条件
|
||||
if (quickSearch && quickSearch.trim()) {
|
||||
searchJson += `,{"column":"Fixtureno","operator":"like","value":"${quickSearch.trim()}"}`
|
||||
}
|
||||
|
||||
searchJson += ']'
|
||||
return searchJson
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录状态
|
||||
* @returns {string|null} 登录代码
|
||||
*/
|
||||
function getLoginCode() {
|
||||
return localStorage.getItem('loginState') || localStorage.getItem('loginCode')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取资产清查数据
|
||||
* @param {Object} params - 查询参数
|
||||
* @param {string} params.tabType - 标签类型
|
||||
* @param {number} params.pageIndex - 页码 (从1开始)
|
||||
* @param {string} params.quickSearch - 快速搜索关键词
|
||||
* @returns {Promise<Array>} 资产数据数组
|
||||
*/
|
||||
export async function getAssetsData(params = {}) {
|
||||
const {
|
||||
tabType = 'all',
|
||||
pageIndex = 1,
|
||||
quickSearch = ''
|
||||
} = params
|
||||
|
||||
const loginCode = getLoginCode()
|
||||
if (!loginCode) {
|
||||
throw new Error('未找到登录状态,请先登录')
|
||||
}
|
||||
|
||||
const searchJson = buildSearchJson(tabType, quickSearch)
|
||||
|
||||
const formData = new URLSearchParams()
|
||||
formData.append('tablename', TABLE_NAME)
|
||||
formData.append('loginCode', loginCode)
|
||||
formData.append('nowpageindex', pageIndex.toString())
|
||||
formData.append('serializeJson', searchJson)
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/ReTurnZcpdMain`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: formData.toString()
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP错误: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.text()
|
||||
return parseApiResponse(data)
|
||||
} catch (error) {
|
||||
console.error('获取资产数据失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个资产详情
|
||||
* @param {string|number} assetId - 资产ID
|
||||
* @returns {Promise<Object|null>} 资产详情对象
|
||||
*/
|
||||
export async function getAssetDetail(assetId) {
|
||||
const loginCode = getLoginCode()
|
||||
if (!loginCode) {
|
||||
throw new Error('未找到登录状态,请先登录')
|
||||
}
|
||||
|
||||
const searchJson = `[{"column":"ID","operator":"=","value":"${assetId}"}]`
|
||||
|
||||
const formData = new URLSearchParams()
|
||||
formData.append('tablename', TABLE_NAME)
|
||||
formData.append('loginCode', loginCode)
|
||||
formData.append('nowpageindex', '1')
|
||||
formData.append('serializeJson', searchJson)
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/ReTurnZcpdMain`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: formData.toString()
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP错误: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.text()
|
||||
const assets = parseApiResponse(data)
|
||||
return assets.length > 0 ? assets[0] : null
|
||||
} catch (error) {
|
||||
console.error('获取资产详情失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 资产数据字段映射
|
||||
* 将API返回的字段映射为更友好的显示名称
|
||||
*/
|
||||
export const ASSET_FIELD_MAP = {
|
||||
ID: 'id',
|
||||
Classifyno: 'classification',
|
||||
Fixtureno: 'internalNumber',
|
||||
Code: 'externalNumber',
|
||||
Name: 'name',
|
||||
Specify: 'specification',
|
||||
Src: 'acquisitionMethod',
|
||||
Buydate: 'acquisitionDate',
|
||||
ZcType: 'assetType',
|
||||
Office: 'department',
|
||||
UserName: 'user',
|
||||
Field2: 'location',
|
||||
State: 'status',
|
||||
IsOutZc: 'isOffBook',
|
||||
Num: 'bookQuantity',
|
||||
Price: 'bookOriginalValue',
|
||||
Ljzj: 'bookAccumulatedDepreciation',
|
||||
PriceJz: 'bookNetValue',
|
||||
QcNum: 'checkQuantity',
|
||||
QcPrice: 'checkOriginalValue',
|
||||
QcLjzj: 'checkAccumulatedDepreciation',
|
||||
QcPriceJz: 'checkNetValue',
|
||||
PdTypes: 'changeReason',
|
||||
BdkRemarks: 'specificReason',
|
||||
Remarks: 'remarks'
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换资产数据格式
|
||||
* @param {Object} rawAsset - 原始资产数据
|
||||
* @returns {Object} 转换后的资产数据
|
||||
*/
|
||||
export function transformAssetData(rawAsset) {
|
||||
const transformed = {}
|
||||
|
||||
Object.keys(ASSET_FIELD_MAP).forEach(key => {
|
||||
const mappedKey = ASSET_FIELD_MAP[key]
|
||||
transformed[mappedKey] = rawAsset[key] || ''
|
||||
})
|
||||
|
||||
return transformed
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量转换资产数据
|
||||
* @param {Array} rawAssets - 原始资产数据数组
|
||||
* @returns {Array} 转换后的资产数据数组
|
||||
*/
|
||||
export function transformAssetsData(rawAssets) {
|
||||
return rawAssets.map(transformAssetData)
|
||||
}
|
||||
@@ -1,39 +1,89 @@
|
||||
<template>
|
||||
<div class="laboratory-content">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon>
|
||||
<Operation />
|
||||
</el-icon>
|
||||
实验室管理
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="laboratory-page">
|
||||
<!-- 页面头部 -->
|
||||
<div class="page-header">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/admin/dashboard' }">后台首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>业务后台</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>实验室管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="header-actions">
|
||||
<el-button @click="goBackToDashboard">
|
||||
<el-icon>
|
||||
<ArrowLeft />
|
||||
</el-icon>
|
||||
返回后台首页
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-empty description="实验室管理功能开发中..." :image-size="200">
|
||||
<el-descriptions title="功能说明" :column="1" border>
|
||||
<el-descriptions-item label="功能模块">实验室管理</el-descriptions-item>
|
||||
<el-descriptions-item label="主要功能">
|
||||
实验室信息管理、实验设备管理、实验项目管理、实验预约系统、安全管理记录、耗材库存管理等
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="开发状态">
|
||||
<el-tag type="warning">待开发</el-tag>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-empty>
|
||||
</el-card>
|
||||
<!-- 页面内容 -->
|
||||
<div class="page-content">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon>
|
||||
<Operation />
|
||||
</el-icon>
|
||||
实验室管理
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-empty description="实验室管理功能开发中..." :image-size="200">
|
||||
<el-descriptions title="功能说明" :column="1" border>
|
||||
<el-descriptions-item label="功能模块">实验室管理</el-descriptions-item>
|
||||
<el-descriptions-item label="主要功能">
|
||||
实验室信息管理、实验设备管理、实验项目管理、实验预约系统、安全管理记录、耗材库存管理等
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="开发状态">
|
||||
<el-tag type="warning">待开发</el-tag>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-empty>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Operation } from '@element-plus/icons-vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Operation, ArrowLeft } from '@element-plus/icons-vue'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 返回后台首页
|
||||
const goBackToDashboard = () => {
|
||||
router.push('/admin/dashboard')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.laboratory-content {
|
||||
padding: 0;
|
||||
.laboratory-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f0f2f5;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 16px 20px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
@@ -48,5 +98,24 @@ import { Operation } from '@element-plus/icons-vue'
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.laboratory-page {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,39 +1,89 @@
|
||||
<template>
|
||||
<div class="library-content">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon>
|
||||
<Reading />
|
||||
</el-icon>
|
||||
图情管理
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="library-page">
|
||||
<!-- 页面头部 -->
|
||||
<div class="page-header">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/admin/dashboard' }">后台首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>业务后台</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>图情管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="header-actions">
|
||||
<el-button @click="goBackToDashboard">
|
||||
<el-icon>
|
||||
<ArrowLeft />
|
||||
</el-icon>
|
||||
返回后台首页
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-empty description="图情管理功能开发中..." :image-size="200">
|
||||
<el-descriptions title="功能说明" :column="1" border>
|
||||
<el-descriptions-item label="功能模块">图情管理</el-descriptions-item>
|
||||
<el-descriptions-item label="主要功能">
|
||||
图书资料管理、期刊订阅管理、电子资源管理、借阅记录管理、读者信息管理、馆藏统计分析等
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="开发状态">
|
||||
<el-tag type="warning">待开发</el-tag>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-empty>
|
||||
</el-card>
|
||||
<!-- 页面内容 -->
|
||||
<div class="page-content">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon>
|
||||
<Reading />
|
||||
</el-icon>
|
||||
图情管理
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-empty description="图情管理功能开发中..." :image-size="200">
|
||||
<el-descriptions title="功能说明" :column="1" border>
|
||||
<el-descriptions-item label="功能模块">图情管理</el-descriptions-item>
|
||||
<el-descriptions-item label="主要功能">
|
||||
图书资料管理、期刊订阅管理、电子资源管理、借阅记录管理、读者信息管理、馆藏统计分析等
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="开发状态">
|
||||
<el-tag type="warning">待开发</el-tag>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-empty>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Reading } from '@element-plus/icons-vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Reading, ArrowLeft } from '@element-plus/icons-vue'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 返回后台首页
|
||||
const goBackToDashboard = () => {
|
||||
router.push('/admin/dashboard')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.library-content {
|
||||
padding: 0;
|
||||
.library-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f0f2f5;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 16px 20px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
@@ -48,5 +98,24 @@ import { Reading } from '@element-plus/icons-vue'
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #303133;
|
||||
}
|
||||
</style>
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.library-page {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
422
src/views/Admin/Business/ProvinceAssetsCheckView.vue
Normal file
422
src/views/Admin/Business/ProvinceAssetsCheckView.vue
Normal file
@@ -0,0 +1,422 @@
|
||||
<template>
|
||||
<div class="province-assets-check">
|
||||
<!-- 主要内容区域 -->
|
||||
<div class="main-content">
|
||||
<!-- 主内容区域 -->
|
||||
<div class="content-area" :class="{ 'full-width': !showDepartmentPanel }">
|
||||
<!-- 状态标签栏 -->
|
||||
<div class="status-tabs">
|
||||
<el-tabs v-model="activeTab" @tab-click="handleTabClick" class="custom-tabs">
|
||||
<el-tab-pane label="全部" name="all" />
|
||||
<el-tab-pane label="未盘点" name="unchecked" />
|
||||
<el-tab-pane label="无盈亏" name="no-change" />
|
||||
<el-tab-pane label="盘盈" name="surplus" />
|
||||
<el-tab-pane label="损失" name="loss" />
|
||||
<el-tab-pane label="错账调整" name="adjustment" />
|
||||
<el-tab-pane label="错误待处理" name="error-pending" />
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
<div class="action-bar">
|
||||
<div class="action-left">
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">查询</el-button>
|
||||
<el-button type="success" :icon="Plus" @click="handleAddSurplus">增加盘盈</el-button>
|
||||
<el-button type="warning" :icon="Document" @click="handleInventoryCheck">资产盘点</el-button>
|
||||
</div>
|
||||
<div class="action-right">
|
||||
<div class="quick-search">
|
||||
<el-input v-model="quickSearch" placeholder="输入资产编号快速查询" style="width: 200px; margin-right: 10px;"
|
||||
@keyup.enter="handleQuickSearch" clearable>
|
||||
<template #append>
|
||||
<el-button :icon="Search" @click="handleQuickSearch" />
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<div class="table-container">
|
||||
<el-table :data="tableData" v-loading="loading" stripe border class="assets-table" height="calc(100vh - 320px)"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" fixed="left" />
|
||||
<el-table-column prop="serialNumber" label="序号" width="80" fixed="left" />
|
||||
<el-table-column prop="assetCategory" label="资产分类" width="120" show-overflow-tooltip fixed="left" />
|
||||
<el-table-column prop="internalNumber" label="内部编号" width="150" show-overflow-tooltip fixed="left" />
|
||||
<el-table-column prop="assetName" label="资产名称" width="200" show-overflow-tooltip fixed="left" />
|
||||
<el-table-column prop="acquisitionMethod" label="取得方式" width="120" />
|
||||
<el-table-column prop="acquisitionDate" label="取得日期" width="120" />
|
||||
<el-table-column prop="assetType" label="归口类别" width="120" />
|
||||
<el-table-column prop="usingDepartment" label="使用部门" width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="user" label="使用人" width="100" />
|
||||
<el-table-column prop="storageLocation" label="存放地点" width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="usageStatus" label="使用状况" width="100" />
|
||||
<el-table-column prop="isOffBook" label="是否账外" width="100" />
|
||||
|
||||
<!-- 账面价值组 -->
|
||||
<el-table-column label="账面价值" align="center">
|
||||
<el-table-column prop="bookQuantity" label="数量" width="80" />
|
||||
<el-table-column prop="bookOriginalValue" label="原值" width="120" />
|
||||
<el-table-column prop="bookAccumulatedDepreciation" label="累计折旧" width="120" />
|
||||
<el-table-column prop="bookNetValue" label="净值" width="120" />
|
||||
</el-table-column>
|
||||
|
||||
<!-- 盘点价值组 -->
|
||||
<el-table-column label="盘点价值" align="center">
|
||||
<el-table-column prop="checkQuantity" label="数量" width="80" />
|
||||
<el-table-column prop="checkOriginalValue" label="原值" width="120" />
|
||||
<el-table-column prop="checkAccumulatedDepreciation" label="累计折旧" width="120" />
|
||||
<el-table-column prop="checkNetValue" label="净值" width="120" />
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="changeReason" label="变动原因" width="120" />
|
||||
<el-table-column prop="specificReason" label="具体原因" width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="remarks" label="备注" width="200" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="80" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 50, 100]"
|
||||
:total="totalCount" layout="total, prev, pager, next, jumper" @size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange" class="custom-pagination" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getAssetsData, transformAssetsData } from '@/services/assetsApi'
|
||||
import {
|
||||
Document,
|
||||
Plus,
|
||||
Search
|
||||
} from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
|
||||
// 响应式数据
|
||||
const showDepartmentPanel = ref(true)
|
||||
const activeTab = ref('all')
|
||||
const loading = ref(false)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(50)
|
||||
const totalCount = ref(1000)
|
||||
const selectedRows = ref([])
|
||||
const quickSearch = ref('')
|
||||
// 表格数据
|
||||
const tableData = ref([])
|
||||
|
||||
// 加载函数
|
||||
const loadTableData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const rawData = await getAssetsData({
|
||||
tabType: activeTab.value,
|
||||
pageIndex: currentPage.value,
|
||||
quickSearch: quickSearch.value
|
||||
})
|
||||
|
||||
// 转换数据格式
|
||||
const transformedData = transformAssetsData(rawData)
|
||||
|
||||
// 映射到表格显示格式
|
||||
tableData.value = transformedData.map((item, index) => ({
|
||||
id: item.id,
|
||||
serialNumber: (currentPage.value - 1) * pageSize.value + index + 1,
|
||||
assetCategory: item.classification || '',
|
||||
internalNumber: item.internalNumber || '',
|
||||
assetName: item.name || '',
|
||||
acquisitionMethod: item.acquisitionMethod || '',
|
||||
acquisitionDate: item.acquisitionDate || '',
|
||||
assetType: item.assetType || '',
|
||||
usingDepartment: item.department || '',
|
||||
user: item.user || '',
|
||||
storageLocation: item.location || '',
|
||||
usageStatus: item.status || '',
|
||||
isOffBook: item.isOffBook || '否',
|
||||
bookQuantity: item.bookQuantity || 0,
|
||||
bookOriginalValue: item.bookOriginalValue || 0,
|
||||
bookAccumulatedDepreciation: item.bookAccumulatedDepreciation || 0,
|
||||
bookNetValue: item.bookNetValue || 0,
|
||||
checkQuantity: item.checkQuantity || 0,
|
||||
checkOriginalValue: item.checkOriginalValue || 0,
|
||||
checkAccumulatedDepreciation: item.checkAccumulatedDepreciation || 0,
|
||||
checkNetValue: item.checkNetValue || 0,
|
||||
changeReason: item.changeReason || '',
|
||||
specificReason: item.specificReason || '',
|
||||
remarks: item.remarks || ''
|
||||
}))
|
||||
ElMessage.success(`成功加载 ${rawData.length} 条数据`)
|
||||
} catch (error) {
|
||||
console.error('加载数据失败:', error)
|
||||
ElMessage.error(`加载数据失败: ${error.message}`)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleTabClick = (tab) => {
|
||||
activeTab.value = tab.name
|
||||
currentPage.value = 1 // 重置到第一页
|
||||
loadTableData()
|
||||
}
|
||||
|
||||
|
||||
const handleQuickSearch = () => {
|
||||
currentPage.value = 1 // 重置到第一页
|
||||
loadTableData()
|
||||
}
|
||||
|
||||
const handleAddSurplus = () => {
|
||||
ElMessage.info('打开增加盘盈对话框')
|
||||
}
|
||||
|
||||
const handleInventoryCheck = () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
ElMessage.warning('请先选择要盘点的资产')
|
||||
return
|
||||
}
|
||||
ElMessage.info(`对 ${selectedRows.value.length} 项资产进行盘点`)
|
||||
}
|
||||
|
||||
const handleSelectionChange = (selection) => {
|
||||
selectedRows.value = selection
|
||||
}
|
||||
|
||||
const handleEdit = (row) => {
|
||||
ElMessage.info(`编辑资产: ${row.assetName}`)
|
||||
}
|
||||
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
pageSize.value = val
|
||||
currentPage.value = 1 // 重置到第一页
|
||||
loadTableData()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
currentPage.value = val
|
||||
loadTableData()
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
loadTableData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.province-assets-check {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 主内容区域样式 */
|
||||
.content-area {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: white;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.content-area.full-width {
|
||||
margin-left: 70px;
|
||||
}
|
||||
|
||||
.status-tabs {
|
||||
padding: 20px 20px 0;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.custom-tabs :deep(.el-tabs__header) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.custom-tabs :deep(.el-tabs__item) {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.custom-tabs :deep(.el-tabs__item.is-active) {
|
||||
color: #4682b4;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.custom-tabs :deep(.el-tabs__active-bar) {
|
||||
background: linear-gradient(135deg, #87ceeb 0%, #4682b4 100%);
|
||||
}
|
||||
|
||||
.action-bar {
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
background: #fafbfc;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action-left {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.action-right .total-count {
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 表格样式 */
|
||||
.table-container {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.assets-table {
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.assets-table :deep(.el-table__header) {
|
||||
background: #f8fafc;
|
||||
}
|
||||
|
||||
.assets-table :deep(.el-table__header th) {
|
||||
background: #f8fafc;
|
||||
color: #374151;
|
||||
font-weight: 600;
|
||||
border-bottom: 2px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.assets-table :deep(.el-table__row:hover) {
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
.assets-table :deep(.el-table__row td) {
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
}
|
||||
|
||||
/* 分页样式 */
|
||||
.pagination-container {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
background: #fafbfc;
|
||||
}
|
||||
|
||||
.custom-pagination :deep(.el-pagination__total) {
|
||||
color: #606266;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.custom-pagination :deep(.btn-next),
|
||||
.custom-pagination :deep(.btn-prev) {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.custom-pagination :deep(.el-pager li) {
|
||||
border-radius: 6px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.custom-pagination :deep(.el-pager li.is-active) {
|
||||
background: linear-gradient(135deg, #87ceeb 0%, #4682b4 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 1400px) {
|
||||
.department-panel {
|
||||
width: 280px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.department-panel {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.content-area {
|
||||
margin: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.main-content {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.department-panel {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.department-panel.panel-collapsed {
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.content-area {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.content-area.full-width {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.action-bar {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.action-left {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.action-right {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.action-left {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.assets-table {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
381
src/views/Admin/Business/StateAssetsMainView.vue
Normal file
381
src/views/Admin/Business/StateAssetsMainView.vue
Normal file
@@ -0,0 +1,381 @@
|
||||
<template>
|
||||
<div class="state-assets-main-container">
|
||||
<el-container>
|
||||
<!-- 侧边栏 -->
|
||||
<el-aside :width="isCollapse ? '75px' : '250px'" class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<span v-if="!isCollapse" class="sidebar-title">国资管理系统</span>
|
||||
<el-button :icon="isCollapse ? Expand : Fold"
|
||||
@click="toggleCollapse" text class="collapse-btn" />
|
||||
</div>
|
||||
<el-menu :default-active="activeMenu" :collapse="isCollapse" :collapse-transition="false" class="sidebar-menu">
|
||||
<el-menu-item index="in-use-assets" @click="handleMenuClick('in-use-assets')">
|
||||
<el-icon>
|
||||
<Search />
|
||||
</el-icon>
|
||||
<template #title>在用资产查询</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="book-assets" @click="handleMenuClick('book-assets')">
|
||||
<el-icon>
|
||||
<Document />
|
||||
</el-icon>
|
||||
<template #title>账上资产盘点</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/admin/business/state-assets/province-check" @click="handleMenuClick('province-check')">
|
||||
<el-icon>
|
||||
<DataAnalysis />
|
||||
</el-icon>
|
||||
<template #title>全省资产清查</template>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<el-container class="main-container">
|
||||
<!-- 顶部导航 -->
|
||||
<el-header class="header">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/admin/dashboard' }">后台首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>业务后台</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>国资管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{ currentModuleName }}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="header-actions">
|
||||
<el-button type="info" @click="goBackToLogin">
|
||||
<el-icon>
|
||||
<Back />
|
||||
</el-icon>
|
||||
返回登录
|
||||
</el-button>
|
||||
<el-button type="primary" @click="goBackHome">
|
||||
<el-icon>
|
||||
<HomeFilled />
|
||||
</el-icon>
|
||||
返回首页
|
||||
</el-button>
|
||||
</div>
|
||||
</el-header>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<el-main class="content" style="border-radius: 8px;">
|
||||
<router-view />
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { Fold, Expand, HomeFilled } from '@element-plus/icons-vue'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
// 侧边栏折叠状态
|
||||
const isCollapse = ref(false)
|
||||
|
||||
// 用户信息
|
||||
const userInfo = ref({
|
||||
name: '',
|
||||
loginTime: '',
|
||||
userType: '',
|
||||
dwname: ''
|
||||
})
|
||||
|
||||
const moduleNames = {
|
||||
'in-use-assets': '在用资产查询',
|
||||
'book-assets': '账上资产盘点',
|
||||
'province-assets': '全省资产清查'
|
||||
}
|
||||
|
||||
// 当前激活的菜单项
|
||||
const activeMenu = computed(() => {
|
||||
const path = route.path
|
||||
if (path.includes('/in-use-assets')) return 'in-use-assets'
|
||||
if (path.includes('/book-assets')) return 'book-assets'
|
||||
if (path.includes('/province-check')) return '/admin/business/state-assets/province-check'
|
||||
return 'in-use-assets'
|
||||
})
|
||||
|
||||
const currentModuleName = computed(() => {
|
||||
return moduleNames[activeMenu.value] || '国资管理系统'
|
||||
})
|
||||
|
||||
// 切换侧边栏折叠状态
|
||||
const toggleCollapse = () => {
|
||||
isCollapse.value = !isCollapse.value
|
||||
}
|
||||
|
||||
// 菜单点击处理
|
||||
const handleMenuClick = (index) => {
|
||||
if (index === 'province-check') {
|
||||
router.push('/admin/business/state-assets/province-check')
|
||||
} else {
|
||||
router.push(`/admin/business/state-assets/${index}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 返回登录页面
|
||||
const goBackToLogin = () => {
|
||||
router.push('/admin/business/state-assets')
|
||||
}
|
||||
|
||||
// 返回首页
|
||||
const goBackHome = () => {
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
// 加载用户信息
|
||||
const loadUserInfo = () => {
|
||||
userInfo.value = {
|
||||
name: localStorage.getItem('Name') || '管理员',
|
||||
loginTime: localStorage.getItem('logindate') ?
|
||||
new Date(localStorage.getItem('logindate')).toLocaleString() :
|
||||
new Date().toLocaleString(),
|
||||
userType: localStorage.getItem('userType') || '系统管理员',
|
||||
dwname: localStorage.getItem('dwname') || '未设置'
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadUserInfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.state-assets-main-container {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 侧边栏样式 */
|
||||
.sidebar {
|
||||
background: white;
|
||||
box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
|
||||
transition: width 0.3s ease;
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #c1c1c1 transparent;
|
||||
}
|
||||
|
||||
.sidebar::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.sidebar::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.sidebar::-webkit-scrollbar-thumb {
|
||||
background-color: #c1c1c1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.sidebar::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #a8a8a8;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
transition: opacity 0.3s ease;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.collapse-btn {
|
||||
color: #fff !important;
|
||||
font-size: 18px;
|
||||
padding: 0;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.collapse-btn:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1) !important;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
border: none;
|
||||
padding: 10px 0;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.sidebar-menu .el-menu-item {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
margin: 2px 10px;
|
||||
border-radius: 6px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.sidebar-menu .el-menu-item:hover {
|
||||
background-color: #e3f2fd;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
.sidebar-menu .el-menu-item.is-active {
|
||||
background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-menu .el-menu-item .el-icon {
|
||||
margin-right: 8px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 主容器样式 */
|
||||
.main-container {
|
||||
background-color: #f0f2f5;
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
.header {
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* 内容区域样式 */
|
||||
.content {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.welcome-card {
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
font-size: 24px;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
.welcome-info {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.quick-actions {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.quick-actions h3 {
|
||||
color: #1976d2;
|
||||
margin-bottom: 20px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.action-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.action-card {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 12px;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.action-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px rgba(25, 118, 210, 0.2);
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
font-size: 48px;
|
||||
color: #1976d2;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.action-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #1976d2;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.action-desc {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 0 10px;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: auto;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.action-cards {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,52 +1,365 @@
|
||||
<template>
|
||||
<div class="state-assets-content">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon>
|
||||
<Shop />
|
||||
</el-icon>
|
||||
国资管理
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="state-assets-login-container">
|
||||
<!-- 顶栏 -->
|
||||
<el-header class="header">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/admin/dashboard' }">后台首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>业务后台</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>国资管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>系统登录</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<el-button type="primary" @click="goBackHome" style="width: 100px;">
|
||||
<el-icon>
|
||||
<HomeFilled />
|
||||
</el-icon>
|
||||
返回首页
|
||||
</el-button>
|
||||
</el-header>
|
||||
|
||||
<el-empty description="国资管理功能开发中..." :image-size="200">
|
||||
<el-descriptions title="功能说明" :column="1" border>
|
||||
<el-descriptions-item label="功能模块">国资管理</el-descriptions-item>
|
||||
<el-descriptions-item label="主要功能">
|
||||
国有资产登记管理、资产分类统计、资产调拨审批、资产盘点管理、资产折旧计算、资产报废处置等
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="开发状态">
|
||||
<el-tag type="warning">待开发</el-tag>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-empty>
|
||||
</el-card>
|
||||
<!-- 登录表单 -->
|
||||
<el-main class="login-main">
|
||||
<div class="logo-box">
|
||||
<el-image src="http://szzc.tcjwj.com/res/images/login/jwjlogo.png" alt="LOGO" class="logo-img" fit="contain"
|
||||
:hide-on-click-modal="true">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<el-icon>
|
||||
<Picture />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<div class="logo-text">国资管理系统</div>
|
||||
</div>
|
||||
|
||||
<el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form"
|
||||
@submit.prevent="handleLogin">
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="loginForm.username" placeholder="请输入用户名" size="large" clearable :prefix-icon="User" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="password">
|
||||
<el-input v-model="loginForm.password" type="password" placeholder="请输入密码" size="large" clearable
|
||||
show-password :prefix-icon="Lock" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="large" class="login-btn" :loading="isLoading" @click="handleLogin">
|
||||
<el-icon v-if="!isLoading">
|
||||
<Check />
|
||||
</el-icon>
|
||||
{{ isLoading ? '登录中...' : '登录' }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-main>
|
||||
|
||||
<!-- 底部联系方式 -->
|
||||
<el-footer class="footer-bar">
|
||||
<el-text type="info">联系方式: 0591-87273300</el-text>
|
||||
</el-footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Shop } from '@element-plus/icons-vue'
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {
|
||||
HomeFilled,
|
||||
User,
|
||||
Lock,
|
||||
Check,
|
||||
Picture
|
||||
} from '@element-plus/icons-vue'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 表单引用
|
||||
const loginFormRef = ref()
|
||||
|
||||
// 表单数据
|
||||
const loginForm = reactive({
|
||||
username: '',
|
||||
password: ''
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const loginRules = {
|
||||
username: [
|
||||
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||
{ min: 2, max: 20, message: '用户名长度在 2 到 20 个字符', trigger: 'blur' }
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: '请输入密码', trigger: 'blur' },
|
||||
{ min: 6, max: 20, message: '密码长度在 6 到 20 个字符', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 加载状态
|
||||
const isLoading = ref(false)
|
||||
|
||||
// 返回首页
|
||||
const goBackHome = () => {
|
||||
router.push('/admin/dashboard')
|
||||
}
|
||||
|
||||
// 登录处理函数的逻辑
|
||||
const handleLogin = async () => {
|
||||
if (!loginFormRef.value) return
|
||||
|
||||
try {
|
||||
// 表单验证
|
||||
await loginFormRef.value.validate()
|
||||
} catch (error) {
|
||||
ElMessage.warning('请正确填写表单信息')
|
||||
return
|
||||
}
|
||||
|
||||
isLoading.value = true
|
||||
|
||||
try {
|
||||
const url = "https://www.tcjwj.com/sz/logintest/jwjDataService.asmx/Login"
|
||||
const params = new URLSearchParams()
|
||||
params.append("loginCode", `${loginForm.username.trim()},${loginForm.password.trim()}`)
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: params.toString(),
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
// 兼容返回格式
|
||||
let res = data
|
||||
if (typeof res === "string") {
|
||||
try {
|
||||
res = JSON.parse(res)
|
||||
} catch { }
|
||||
}
|
||||
|
||||
if (
|
||||
Array.isArray(res) &&
|
||||
res[0] &&
|
||||
(res[0].state === "-1" || res[0].state === "-2")
|
||||
) {
|
||||
ElMessage.error('用户名或密码有误')
|
||||
} else if (Array.isArray(res) && res[0] && res[0].state) {
|
||||
// 保存字段
|
||||
localStorage.setItem("loginState", res[0].state)
|
||||
localStorage.setItem("Name", res[0].chinesename || "")
|
||||
localStorage.setItem("Dwbm", res[0].dwdm || "")
|
||||
localStorage.setItem("dwname", res[0].dwname || "")
|
||||
localStorage.setItem("radioCheckVal", "1")
|
||||
localStorage.setItem("logindate", new Date().toISOString())
|
||||
localStorage.setItem("state", res[0].state)
|
||||
localStorage.setItem("NameCode", loginForm.username.trim())
|
||||
localStorage.setItem("userType", "管理员")
|
||||
|
||||
ElMessage.success('登录成功')
|
||||
// 跳转到国资管理系统主页
|
||||
router.push('/admin/business/state-assets/main')
|
||||
} else {
|
||||
ElMessage.error('登录失败,服务器返回异常')
|
||||
}
|
||||
} catch (err) {
|
||||
ElMessage.error('网络错误或服务器无响应')
|
||||
console.error(err)
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.state-assets-content {
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
.state-assets-login-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
"Helvetica Neue", Arial, sans-serif;
|
||||
background: linear-gradient(135deg, #f5f8fa 0%, #e8f4f8 100%);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
.header {
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 2px;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
.login-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.logo-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.logo-img {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin-bottom: 12px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.image-slot {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
background: #f5f7fa;
|
||||
color: #909399;
|
||||
font-size: 30px;
|
||||
border-radius: 12px;
|
||||
border: 2px dashed #d3d4d6;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: #43a047;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 2px;
|
||||
text-shadow: 0 2px 4px rgba(67, 160, 71, 0.2);
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: 100%;
|
||||
max-width: 380px;
|
||||
}
|
||||
|
||||
.login-form :deep(.el-form-item) {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.login-form :deep(.el-input__wrapper) {
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.login-form :deep(.el-input__wrapper:hover) {
|
||||
box-shadow: 0 4px 12px rgba(25, 118, 210, 0.15);
|
||||
}
|
||||
|
||||
.login-form :deep(.el-input.is-focus .el-input__wrapper) {
|
||||
box-shadow: 0 4px 16px rgba(25, 118, 210, 0.25);
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 1px;
|
||||
box-shadow: 0 4px 16px rgba(25, 118, 210, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.login-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(25, 118, 210, 0.4);
|
||||
}
|
||||
|
||||
.login-btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.footer-bar {
|
||||
background: linear-gradient(135deg, #e3f0fc 0%, #d1e7f7 100%);
|
||||
height: 50px !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
border-top: 1px solid #e0e6ed;
|
||||
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.footer-bar :deep(.el-text) {
|
||||
font-size: 15px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.header {
|
||||
padding: 0 16px;
|
||||
flex-direction: column;
|
||||
height: auto !important;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.login-main {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.logo-img,
|
||||
.image-slot {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.header-title {
|
||||
font-size: 18px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
height: 44px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
<template>
|
||||
<div class="business-management-container">
|
||||
<el-container>
|
||||
<!-- 侧边栏 -->
|
||||
<el-aside :width="isCollapse ? '75px' : '250px'" class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<span v-if="!isCollapse" class="sidebar-title">业务后台</span>
|
||||
<el-button :style="isCollapse ? 'transform: translateX(10px)' : ''" :icon="isCollapse ? Expand : Fold"
|
||||
@click="toggleCollapse" text class="collapse-btn" />
|
||||
</div>
|
||||
<el-menu :default-active="activeMenu" :collapse="isCollapse" :collapse-transition="false" class="sidebar-menu">
|
||||
<el-menu-item index="/admin/business/state-assets" @click="handleMenuClick('/admin/business/state-assets')">
|
||||
<el-icon>
|
||||
<Shop />
|
||||
</el-icon>
|
||||
<template #title>国资管理</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/admin/business/library" @click="handleMenuClick('/admin/business/library')">
|
||||
<el-icon>
|
||||
<Reading />
|
||||
</el-icon>
|
||||
<template #title>图情管理</template>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/admin/business/laboratory" @click="handleMenuClick('/admin/business/laboratory')">
|
||||
<el-icon>
|
||||
<Operation />
|
||||
</el-icon>
|
||||
<template #title>实验室管理</template>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<el-container class="main-container">
|
||||
<!-- 顶部导航 -->
|
||||
<el-header class="header">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/admin/dashboard' }">后台首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>业务后台</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{ currentPageName }}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<el-button type="primary" @click="goBackHome">
|
||||
<el-icon>
|
||||
<HomeFilled />
|
||||
</el-icon>
|
||||
返回首页
|
||||
</el-button>
|
||||
</el-header>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<el-main class="content">
|
||||
<router-view />
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import {
|
||||
Shop,
|
||||
Reading,
|
||||
Operation,
|
||||
Fold,
|
||||
Expand,
|
||||
HomeFilled
|
||||
} from '@element-plus/icons-vue'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
// 侧边栏折叠状态
|
||||
const isCollapse = ref(false)
|
||||
|
||||
// 当前激活的菜单
|
||||
const activeMenu = computed(() => route.path)
|
||||
|
||||
// 当前页面名称
|
||||
const currentPageName = computed(() => {
|
||||
const menuMap = {
|
||||
'/admin/business/state-assets': '国资管理',
|
||||
'/admin/business/library': '图情管理',
|
||||
'/admin/business/laboratory': '实验室管理'
|
||||
}
|
||||
return menuMap[route.path] || '业务后台'
|
||||
})
|
||||
|
||||
// 切换侧边栏折叠状态
|
||||
const toggleCollapse = () => {
|
||||
isCollapse.value = !isCollapse.value
|
||||
}
|
||||
|
||||
// 菜单点击处理
|
||||
const handleMenuClick = (path) => {
|
||||
router.push(path)
|
||||
}
|
||||
|
||||
// 返回首页
|
||||
const goBackHome = () => {
|
||||
router.push('/admin/dashboard')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.business-management-container {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 侧边栏样式 */
|
||||
.sidebar {
|
||||
background: white;
|
||||
box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
|
||||
transition: width 0.3s ease;
|
||||
overflow-x: hidden;
|
||||
/* 优化滚动条样式 */
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #c1c1c1 transparent;
|
||||
}
|
||||
|
||||
.sidebar::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.sidebar::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.sidebar::-webkit-scrollbar-thumb {
|
||||
background-color: #c1c1c1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.sidebar::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #a8a8a8;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
transition: opacity 0.3s ease;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.collapse-btn {
|
||||
color: #fff !important;
|
||||
font-size: 18px;
|
||||
padding: 0;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.collapse-btn:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1) !important;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
border: none;
|
||||
padding: 10px 0;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.sidebar-menu .el-menu-item {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
margin: 2px 10px;
|
||||
border-radius: 6px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.sidebar-menu .el-menu-item:hover {
|
||||
background-color: #f0f2ff;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.sidebar-menu .el-menu-item.is-active {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-menu .el-menu-item .el-icon {
|
||||
margin-right: 8px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 主容器样式 */
|
||||
.main-container {
|
||||
background-color: #f0f2f5;
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
.header {
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
}
|
||||
|
||||
/* 内容区域样式 */
|
||||
.content {
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -394,7 +394,7 @@
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
|
||||
<div class="module-card" @click="navigateTo('/admin/business')" @mouseenter="showSubModules('business')"
|
||||
<div class="module-card" @mouseenter="showSubModules('business')"
|
||||
@mouseleave="hideSubModules('business')">
|
||||
<div class="module-header">
|
||||
<div class="module-icon business-icon">
|
||||
@@ -833,7 +833,7 @@ const hideSubModules = (module) => {
|
||||
}
|
||||
|
||||
.sub-modules.show {
|
||||
max-height: 340px;
|
||||
max-height: 335px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user