添加银行政府后端接口
This commit is contained in:
@@ -4,7 +4,7 @@ import axios from 'axios'
|
||||
|
||||
// 创建axios实例
|
||||
const instance = axios.create({
|
||||
baseURL: '/api',
|
||||
baseURL: 'http://localhost:5352/api',
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -43,26 +43,40 @@ instance.interceptors.response.use(
|
||||
const userStore = useUserStore()
|
||||
userStore.logout()
|
||||
window.location.href = '/login'
|
||||
message.error('登录已过期,请重新登录')
|
||||
import('ant-design-vue').then(({ message }) => {
|
||||
message.error('登录已过期,请重新登录')
|
||||
})
|
||||
break
|
||||
case 403:
|
||||
message.error('没有权限执行此操作')
|
||||
import('ant-design-vue').then(({ message }) => {
|
||||
message.error('没有权限执行此操作')
|
||||
})
|
||||
break
|
||||
case 404:
|
||||
message.error('请求的资源不存在')
|
||||
import('ant-design-vue').then(({ message }) => {
|
||||
message.error('请求的资源不存在')
|
||||
})
|
||||
break
|
||||
case 500:
|
||||
message.error('服务器内部错误')
|
||||
import('ant-design-vue').then(({ message }) => {
|
||||
message.error('服务器内部错误')
|
||||
})
|
||||
break
|
||||
default:
|
||||
message.error(error.response.data.message || '请求失败')
|
||||
import('ant-design-vue').then(({ message }) => {
|
||||
message.error(error.response.data.message || '请求失败')
|
||||
})
|
||||
}
|
||||
} else if (error.request) {
|
||||
// 请求发出但没有收到响应
|
||||
message.error('网络错误,请检查网络连接')
|
||||
import('ant-design-vue').then(({ message }) => {
|
||||
message.error('网络错误,请检查网络连接')
|
||||
})
|
||||
} else {
|
||||
// 请求配置出错
|
||||
message.error('请求配置错误')
|
||||
import('ant-design-vue').then(({ message }) => {
|
||||
message.error('请求配置错误')
|
||||
})
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
@@ -217,6 +231,35 @@ const api = {
|
||||
updateSettings: (data) => instance.put('/system/settings', data),
|
||||
// 获取日志列表
|
||||
getLogs: (params) => instance.get('/system/logs', { params })
|
||||
},
|
||||
|
||||
// 政府管理相关API
|
||||
government: {
|
||||
// 行政人员管理
|
||||
adminStaff: {
|
||||
// 获取行政人员列表
|
||||
getList: (params) => instance.get('/government/admin-staff', { params }),
|
||||
// 创建行政人员
|
||||
create: (data) => instance.post('/government/admin-staff', data),
|
||||
// 更新行政人员
|
||||
update: (id, data) => instance.put(`/government/admin-staff/${id}`, data),
|
||||
// 删除行政人员
|
||||
delete: (id) => instance.delete(`/government/admin-staff/${id}`),
|
||||
// 重置行政人员密码
|
||||
resetPassword: (id) => instance.post(`/government/admin-staff/${id}/reset-password`)
|
||||
},
|
||||
|
||||
// 部门管理
|
||||
departments: {
|
||||
// 获取部门列表
|
||||
getList: (params) => instance.get('/government/departments', { params })
|
||||
},
|
||||
|
||||
// 岗位管理
|
||||
positions: {
|
||||
// 获取岗位列表
|
||||
getList: (params) => instance.get('/government/positions', { params })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,130 +1,90 @@
|
||||
<template>
|
||||
<div class="admin-department-container">
|
||||
<div class="header">
|
||||
<div class="title">部门:防疫部门</div>
|
||||
<div class="actions">
|
||||
<a-button type="primary" class="action-btn">删除部门</a-button>
|
||||
<a-button type="primary" class="action-btn">新增岗位</a-button>
|
||||
<template v-for="dept in departments" :key="dept.id">
|
||||
<div class="header">
|
||||
<div class="title">部门:{{ dept.name }}</div>
|
||||
<div class="actions">
|
||||
<a-button type="primary" danger @click="handleDeleteDepartment(dept.id)">删除部门</a-button>
|
||||
<a-button type="primary" @click="showAddPositionModal(dept.id, dept.name)">新增岗位</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-table :columns="columns" :data-source="departmentData" :pagination="false" class="department-table">
|
||||
<template #headerCell="{ column }">
|
||||
<span>{{ column.title }}</span>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'permission'">
|
||||
<a-tag v-if="record.permission === '已设置权限'" color="success">{{ record.permission }}</a-tag>
|
||||
<a-tag v-else color="warning">{{ record.permission }}</a-tag>
|
||||
<a-table :columns="columns" :data-source="formatPositionsData(dept.positions)" :pagination="false" class="department-table">
|
||||
<template #headerCell="{ column }">
|
||||
<span>{{ column.title }}</span>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" @click="editPosition(record)">编辑岗位名称</a-button>
|
||||
<a-button type="link" @click="deletePosition(record)">删除岗位</a-button>
|
||||
<a-button type="link" @click="setPermission(record)">设置权限</a-button>
|
||||
</a-space>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'permission'">
|
||||
<a-tag v-if="record.permission === '已设置权限'" color="success">{{ record.permission }}</a-tag>
|
||||
<a-tag v-else color="warning">{{ record.permission }}</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" @click="showEditPositionModal(record)">编辑岗位名称</a-button>
|
||||
<a-button type="link" danger @click="handleDeletePosition(record.id)">删除岗位</a-button>
|
||||
<a-button type="link" @click="showSetPermissionModal(record)">设置权限</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<div class="header">
|
||||
<div class="title">部门:检疫部门</div>
|
||||
<div class="actions">
|
||||
<a-button type="primary" class="action-btn">删除部门</a-button>
|
||||
<a-button type="primary" class="action-btn">新增岗位</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-table :columns="columns" :data-source="inspectionData" :pagination="false" class="department-table">
|
||||
<template #headerCell="{ column }">
|
||||
<span>{{ column.title }}</span>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'permission'">
|
||||
<a-tag v-if="record.permission === '已设置权限'" color="success">{{ record.permission }}</a-tag>
|
||||
<a-tag v-else color="warning">{{ record.permission }}</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" @click="editPosition(record)">编辑岗位名称</a-button>
|
||||
<a-button type="link" @click="deletePosition(record)">删除岗位</a-button>
|
||||
<a-button type="link" @click="setPermission(record)">设置权限</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<div class="header">
|
||||
<div class="title">部门:冷配管理部门</div>
|
||||
<div class="actions">
|
||||
<a-button type="primary" class="action-btn">删除部门</a-button>
|
||||
<a-button type="primary" class="action-btn">新增岗位</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-table :columns="columns" :data-source="coldChainData" :pagination="false" class="department-table">
|
||||
<template #headerCell="{ column }">
|
||||
<span>{{ column.title }}</span>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'permission'">
|
||||
<a-tag v-if="record.permission === '已设置权限'" color="success">{{ record.permission }}</a-tag>
|
||||
<a-tag v-else color="warning">{{ record.permission }}</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" @click="editPosition(record)">编辑岗位名称</a-button>
|
||||
<a-button type="link" @click="deletePosition(record)">删除岗位</a-button>
|
||||
<a-button type="link" @click="setPermission(record)">设置权限</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<div class="header">
|
||||
<div class="title">部门:测试部门</div>
|
||||
<div class="actions">
|
||||
<a-button type="primary" class="action-btn">删除部门</a-button>
|
||||
<a-button type="primary" class="action-btn">新增岗位</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-table :columns="columns" :data-source="testingData" :pagination="false" class="department-table">
|
||||
<template #headerCell="{ column }">
|
||||
<span>{{ column.title }}</span>
|
||||
</template>
|
||||
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'permission'">
|
||||
<a-tag v-if="record.permission === '已设置权限'" color="success">{{ record.permission }}</a-tag>
|
||||
<a-tag v-else color="warning">{{ record.permission }}</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" @click="editPosition(record)">编辑岗位名称</a-button>
|
||||
<a-button type="link" @click="deletePosition(record)">删除岗位</a-button>
|
||||
<a-button type="link" @click="setPermission(record)">设置权限</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<div class="add-department">
|
||||
<a-button type="primary" @click="showAddDepartmentModal">新增部门</a-button>
|
||||
</div>
|
||||
|
||||
<!-- 新增部门模态框 -->
|
||||
<a-modal v-model:visible="addDepartmentModalVisible" title="新增部门" @ok="handleAddDepartment" @cancel="handleCancel">
|
||||
<a-form-model ref="addDepartmentForm" :model="addDepartmentFormData" :rules="addDepartmentRules">
|
||||
<a-form-model-item label="部门名称" name="name">
|
||||
<a-input v-model="addDepartmentFormData.name" placeholder="请输入部门名称" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="部门描述" name="description">
|
||||
<a-textarea v-model="addDepartmentFormData.description" placeholder="请输入部门描述" :rows="3" />
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</a-modal>
|
||||
|
||||
<!-- 新增岗位模态框 -->
|
||||
<a-modal v-model:visible="addPositionModalVisible" title="新增岗位" @ok="handleAddPosition" @cancel="handleCancel">
|
||||
<a-form-model ref="addPositionForm" :model="addPositionFormData" :rules="addPositionRules">
|
||||
<a-form-model-item label="所属部门" name="department_name">
|
||||
<a-input v-model="addPositionFormData.department_name" disabled />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="岗位名称" name="name">
|
||||
<a-input v-model="addPositionFormData.name" placeholder="请输入岗位名称" />
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</a-modal>
|
||||
|
||||
<!-- 编辑岗位模态框 -->
|
||||
<a-modal v-model:visible="editPositionModalVisible" title="编辑岗位" @ok="handleEditPosition" @cancel="handleCancel">
|
||||
<a-form-model ref="editPositionForm" :model="editPositionFormData" :rules="editPositionRules">
|
||||
<a-form-model-item label="岗位名称" name="name">
|
||||
<a-input v-model="editPositionFormData.name" placeholder="请输入岗位名称" />
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</a-modal>
|
||||
|
||||
<!-- 设置权限模态框 -->
|
||||
<a-modal v-model:visible="setPermissionModalVisible" title="设置权限" @ok="handleSetPermission" @cancel="handleCancel" :width="600">
|
||||
<div>
|
||||
<p>岗位: {{ currentPosition?.name }}</p>
|
||||
<div style="margin-top: 16px;">
|
||||
<p>权限设置示例</p>
|
||||
<a-alert type="info" message="实际项目中,这里应该是具体的权限选择界面" />
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import axios from 'axios'
|
||||
|
||||
// 表格列定义
|
||||
const columns = [
|
||||
@@ -144,66 +104,212 @@ const columns = [
|
||||
}
|
||||
]
|
||||
|
||||
// 防疫部门数据
|
||||
const departmentData = ref([
|
||||
{
|
||||
key: '1',
|
||||
position: '防疫员',
|
||||
permission: '已设置权限',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
position: '防疫管理员',
|
||||
permission: '已设置权限',
|
||||
}
|
||||
])
|
||||
// 部门数据
|
||||
const departments = ref([])
|
||||
|
||||
// 检疫部门数据
|
||||
const inspectionData = ref([
|
||||
{
|
||||
key: '1',
|
||||
position: '检疫员',
|
||||
permission: '未设置权限',
|
||||
}
|
||||
])
|
||||
// 当前选中的岗位
|
||||
const currentPosition = ref(null)
|
||||
|
||||
// 冷配管理部门数据
|
||||
const coldChainData = ref([
|
||||
{
|
||||
key: '1',
|
||||
position: '冷配员',
|
||||
permission: '已设置权限',
|
||||
}
|
||||
])
|
||||
// 模态框控制
|
||||
const addDepartmentModalVisible = ref(false)
|
||||
const addPositionModalVisible = ref(false)
|
||||
const editPositionModalVisible = ref(false)
|
||||
const setPermissionModalVisible = ref(false)
|
||||
|
||||
// 测试部门数据
|
||||
const testingData = ref([
|
||||
{
|
||||
key: '1',
|
||||
position: '内部测试账号',
|
||||
permission: '已设置权限',
|
||||
}
|
||||
])
|
||||
// 表单数据
|
||||
const addDepartmentFormData = reactive({
|
||||
name: '',
|
||||
description: ''
|
||||
})
|
||||
|
||||
// 编辑岗位
|
||||
const editPosition = (record) => {
|
||||
message.info(`编辑岗位:${record.position}`)
|
||||
const addPositionFormData = reactive({
|
||||
department_id: '',
|
||||
department_name: '',
|
||||
name: ''
|
||||
})
|
||||
|
||||
const editPositionFormData = reactive({
|
||||
id: '',
|
||||
name: ''
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const addDepartmentRules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入部门名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 删除岗位
|
||||
const deletePosition = (record) => {
|
||||
message.info(`删除岗位:${record.position}`)
|
||||
const addPositionRules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入岗位名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 设置权限
|
||||
const setPermission = (record) => {
|
||||
message.info(`设置权限:${record.position}`)
|
||||
const editPositionRules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入岗位名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 从API获取部门数据
|
||||
const fetchDepartments = async () => {
|
||||
try {
|
||||
const response = await axios.get('/api/government/departments')
|
||||
departments.value = response.data
|
||||
} catch (error) {
|
||||
message.error('获取部门数据失败:' + error.message)
|
||||
console.error('获取部门数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化岗位数据
|
||||
const formatPositionsData = (positions) => {
|
||||
return positions.map(pos => ({
|
||||
key: pos.id,
|
||||
id: pos.id,
|
||||
position: pos.name,
|
||||
permission: pos.permission
|
||||
}))
|
||||
}
|
||||
|
||||
// 显示新增部门模态框
|
||||
const showAddDepartmentModal = () => {
|
||||
message.info('显示新增部门对话框')
|
||||
// 重置表单
|
||||
Object.keys(addDepartmentFormData).forEach(key => {
|
||||
addDepartmentFormData[key] = ''
|
||||
})
|
||||
addDepartmentModalVisible.value = true
|
||||
}
|
||||
|
||||
// 显示新增岗位模态框
|
||||
const showAddPositionModal = (departmentId, departmentName) => {
|
||||
// 重置表单
|
||||
Object.keys(addPositionFormData).forEach(key => {
|
||||
addPositionFormData[key] = ''
|
||||
})
|
||||
addPositionFormData.department_id = departmentId
|
||||
addPositionFormData.department_name = departmentName
|
||||
addPositionModalVisible.value = true
|
||||
}
|
||||
|
||||
// 显示编辑岗位模态框
|
||||
const showEditPositionModal = (record) => {
|
||||
editPositionFormData.id = record.id
|
||||
editPositionFormData.name = record.position
|
||||
editPositionModalVisible.value = true
|
||||
}
|
||||
|
||||
// 显示设置权限模态框
|
||||
const showSetPermissionModal = (record) => {
|
||||
currentPosition.value = record
|
||||
setPermissionModalVisible.value = true
|
||||
}
|
||||
|
||||
// 新增部门
|
||||
const handleAddDepartment = async () => {
|
||||
try {
|
||||
await axios.post('/api/government/departments', {
|
||||
name: addDepartmentFormData.name,
|
||||
description: addDepartmentFormData.description
|
||||
})
|
||||
message.success('部门创建成功')
|
||||
addDepartmentModalVisible.value = false
|
||||
// 重新获取数据
|
||||
await fetchDepartments()
|
||||
} catch (error) {
|
||||
message.error('创建部门失败:' + error.message)
|
||||
console.error('创建部门失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 新增岗位
|
||||
const handleAddPosition = async () => {
|
||||
try {
|
||||
await axios.post(`/api/government/departments/${addPositionFormData.department_id}/positions`, {
|
||||
department_id: addPositionFormData.department_id,
|
||||
name: addPositionFormData.name
|
||||
})
|
||||
message.success('岗位创建成功')
|
||||
addPositionModalVisible.value = false
|
||||
// 重新获取数据
|
||||
await fetchDepartments()
|
||||
} catch (error) {
|
||||
message.error('创建岗位失败:' + error.message)
|
||||
console.error('创建岗位失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑岗位
|
||||
const handleEditPosition = async () => {
|
||||
try {
|
||||
await axios.put(`/api/government/positions/${editPositionFormData.id}`, {
|
||||
name: editPositionFormData.name
|
||||
})
|
||||
message.success('岗位编辑成功')
|
||||
editPositionModalVisible.value = false
|
||||
// 重新获取数据
|
||||
await fetchDepartments()
|
||||
} catch (error) {
|
||||
message.error('编辑岗位失败:' + error.message)
|
||||
console.error('编辑岗位失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 删除岗位
|
||||
const handleDeletePosition = async (positionId) => {
|
||||
try {
|
||||
await axios.delete(`/api/government/positions/${positionId}`)
|
||||
message.success('岗位删除成功')
|
||||
// 重新获取数据
|
||||
await fetchDepartments()
|
||||
} catch (error) {
|
||||
message.error('删除岗位失败:' + error.message)
|
||||
console.error('删除岗位失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 删除部门
|
||||
const handleDeleteDepartment = async (departmentId) => {
|
||||
try {
|
||||
await axios.delete(`/api/government/departments/${departmentId}`)
|
||||
message.success('部门删除成功')
|
||||
// 重新获取数据
|
||||
await fetchDepartments()
|
||||
} catch (error) {
|
||||
message.error('删除部门失败:' + error.message)
|
||||
console.error('删除部门失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 设置权限
|
||||
const handleSetPermission = async () => {
|
||||
try {
|
||||
await axios.post(`/api/government/positions/${currentPosition.value.id}/permission`, {
|
||||
permission_details: { basic: ['view', 'edit', 'add'], advanced: ['delete'] }
|
||||
})
|
||||
message.success('权限设置成功')
|
||||
setPermissionModalVisible.value = false
|
||||
// 重新获取数据
|
||||
await fetchDepartments()
|
||||
} catch (error) {
|
||||
message.error('设置权限失败:' + error.message)
|
||||
console.error('设置权限失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 取消操作
|
||||
const handleCancel = () => {
|
||||
addDepartmentModalVisible.value = false
|
||||
addPositionModalVisible.value = false
|
||||
editPositionModalVisible.value = false
|
||||
setPermissionModalVisible.value = false
|
||||
}
|
||||
|
||||
// 组件挂载时获取数据
|
||||
onMounted(() => {
|
||||
fetchDepartments()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="admin-staff-container">
|
||||
<div class="header">
|
||||
<a-button type="primary">新增人员</a-button>
|
||||
<a-button type="primary" @click="showCreateModal">新增人员</a-button>
|
||||
<a-input-search
|
||||
v-model:value="searchValue"
|
||||
placeholder="请输入员工姓名"
|
||||
@@ -13,27 +13,106 @@
|
||||
<a-table :columns="columns" :data-source="staffData" :pagination="pagination" class="staff-table">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-switch v-model:checked="record.status" />
|
||||
<a-switch v-model:checked="record.status" @change="updateStaffStatus(record)" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" @click="editStaff(record)">编辑</a-button>
|
||||
<a-button type="link" @click="resetPassword(record)">修改密码</a-button>
|
||||
<a-button type="link" @click="showEditModal(record)">编辑</a-button>
|
||||
<a-button type="link" @click="handleResetPassword(record)">修改密码</a-button>
|
||||
<a-button type="link" danger @click="deleteStaff(record)">删除</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<!-- 新增/编辑模态框 -->
|
||||
<a-modal
|
||||
v-model:open="isModalOpen"
|
||||
:title="modalTitle"
|
||||
@ok="handleModalOk"
|
||||
@cancel="handleModalCancel"
|
||||
>
|
||||
<a-form :model="formData" layout="vertical">
|
||||
<a-form-item label="员工姓名">
|
||||
<a-input v-model:value="formData.name" placeholder="请输入员工姓名" />
|
||||
</a-form-item>
|
||||
<a-form-item label="所属部门">
|
||||
<a-select v-model:value="formData.department_id" placeholder="请选择部门">
|
||||
<a-select-option v-for="dept in departments" :key="dept.id" :value="dept.id">
|
||||
{{ dept.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="任职岗位">
|
||||
<a-select v-model:value="formData.position_id" placeholder="请选择岗位">
|
||||
<a-select-option v-for="pos in positions" :key="pos.id" :value="pos.id">
|
||||
{{ pos.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="联系电话">
|
||||
<a-input v-model:value="formData.phone" placeholder="请输入联系电话" />
|
||||
</a-form-item>
|
||||
<a-form-item label="身份证号码">
|
||||
<a-input v-model:value="formData.id_card" placeholder="请输入身份证号码" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import api from '@/utils/api'
|
||||
|
||||
// 搜索值
|
||||
const searchValue = ref('')
|
||||
|
||||
// 员工数据
|
||||
const staffData = ref([])
|
||||
|
||||
// 部门列表
|
||||
const departments = ref([])
|
||||
|
||||
// 岗位列表
|
||||
const positions = ref([])
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条记录`,
|
||||
onChange: (page, pageSize) => {
|
||||
pagination.current = page
|
||||
pagination.pageSize = pageSize
|
||||
fetchAdminStaffList()
|
||||
},
|
||||
onShowSizeChange: (current, pageSize) => {
|
||||
pagination.current = 1
|
||||
pagination.pageSize = pageSize
|
||||
fetchAdminStaffList()
|
||||
}
|
||||
})
|
||||
|
||||
// 模态框相关
|
||||
const isModalOpen = ref(false)
|
||||
const modalTitle = ref('新增行政人员')
|
||||
const currentStaffId = ref(null)
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
department_id: '',
|
||||
position_id: '',
|
||||
phone: '',
|
||||
id_card: '',
|
||||
status: true
|
||||
})
|
||||
|
||||
// 表格列定义
|
||||
const columns = [
|
||||
{
|
||||
@@ -58,8 +137,8 @@ const columns = [
|
||||
},
|
||||
{
|
||||
title: '身份证号码',
|
||||
dataIndex: 'idCard',
|
||||
key: 'idCard',
|
||||
dataIndex: 'id_card',
|
||||
key: 'id_card',
|
||||
},
|
||||
{
|
||||
title: '账号使用状态',
|
||||
@@ -68,9 +147,9 @@ const columns = [
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createdAt',
|
||||
key: 'createdAt',
|
||||
sorter: (a, b) => new Date(a.createdAt) - new Date(b.createdAt),
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
sorter: (a, b) => new Date(a.created_at) - new Date(b.created_at),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
@@ -78,173 +157,166 @@ const columns = [
|
||||
}
|
||||
]
|
||||
|
||||
// 员工数据
|
||||
const staffData = ref([
|
||||
{
|
||||
key: '1',
|
||||
name: '内部测试账号',
|
||||
department: '测试部门',
|
||||
position: '内部测试账号',
|
||||
phone: '187****4778',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-11-24 17:24:32'
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: '扎拉嘎',
|
||||
department: '冷配管理部门',
|
||||
position: '冷配员',
|
||||
phone: '195****9912',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-10-10 13:59:03'
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: '董立鹏',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '151****7022',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-19 15:47:54'
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
name: '李海涛',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '139****6955',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:29:15'
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
name: '高凤鸣',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '158****4601',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:28:57'
|
||||
},
|
||||
{
|
||||
key: '6',
|
||||
name: '刘全',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '139****6009',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:28:39'
|
||||
},
|
||||
{
|
||||
key: '7',
|
||||
name: '李志伟',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '153****0457',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:28:14'
|
||||
},
|
||||
{
|
||||
key: '8',
|
||||
name: '李景学',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '153****5588',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:27:57'
|
||||
},
|
||||
{
|
||||
key: '9',
|
||||
name: '王海龙',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '150****7222',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:27:39'
|
||||
},
|
||||
{
|
||||
key: '10',
|
||||
name: '德力根',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '150****2938',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:27:22'
|
||||
},
|
||||
{
|
||||
key: '11',
|
||||
name: '巴日斯',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '131****1366',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:27:03'
|
||||
},
|
||||
{
|
||||
key: '12',
|
||||
name: '邵志勇',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '139****0778',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:26:26'
|
||||
},
|
||||
{
|
||||
key: '13',
|
||||
name: '张日林',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '156****6300',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:25:37'
|
||||
},
|
||||
{
|
||||
key: '14',
|
||||
name: '李燕',
|
||||
department: '防疫部',
|
||||
position: '防疫管理员',
|
||||
phone: '151****1613',
|
||||
idCard: '--',
|
||||
status: true,
|
||||
createdAt: '2023-05-09 14:25:12'
|
||||
// 获取行政人员列表
|
||||
const fetchAdminStaffList = async () => {
|
||||
try {
|
||||
const params = {
|
||||
page: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
search: searchValue.value
|
||||
}
|
||||
const response = await api.government.adminStaff.getList(params)
|
||||
staffData.value = response.data.map(item => ({
|
||||
...item,
|
||||
department: departments.value.find(dept => dept.id === item.department_id)?.name || '',
|
||||
position: positions.value.find(pos => pos.id === item.position_id)?.name || '',
|
||||
key: item.id
|
||||
}))
|
||||
pagination.total = response.total
|
||||
} catch (error) {
|
||||
message.error('获取行政人员列表失败')
|
||||
console.error('获取行政人员列表失败:', error)
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: staffData.value.length,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条记录`
|
||||
})
|
||||
// 获取部门列表
|
||||
const fetchDepartments = async () => {
|
||||
try {
|
||||
const response = await api.government.departments.getList()
|
||||
departments.value = response.data
|
||||
} catch (error) {
|
||||
message.error('获取部门列表失败')
|
||||
console.error('获取部门列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取岗位列表
|
||||
const fetchPositions = async () => {
|
||||
try {
|
||||
const response = await api.government.positions.getList()
|
||||
positions.value = response.data
|
||||
} catch (error) {
|
||||
message.error('获取岗位列表失败')
|
||||
console.error('获取岗位列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化数据
|
||||
const initData = async () => {
|
||||
await fetchDepartments()
|
||||
await fetchPositions()
|
||||
await fetchAdminStaffList()
|
||||
}
|
||||
|
||||
// 搜索处理
|
||||
const onSearch = (value) => {
|
||||
message.info(`搜索: ${value}`)
|
||||
searchValue.value = value
|
||||
pagination.current = 1
|
||||
fetchAdminStaffList()
|
||||
}
|
||||
|
||||
// 编辑员工
|
||||
const editStaff = (record) => {
|
||||
message.info(`编辑员工: ${record.name}`)
|
||||
// 显示新增模态框
|
||||
const showCreateModal = () => {
|
||||
currentStaffId.value = null
|
||||
modalTitle.value = '新增行政人员'
|
||||
Object.keys(formData).forEach(key => {
|
||||
formData[key] = ''
|
||||
})
|
||||
formData.status = true
|
||||
isModalOpen.value = true
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
const resetPassword = (record) => {
|
||||
message.info(`重置密码: ${record.name}`)
|
||||
// 显示编辑模态框
|
||||
const showEditModal = (record) => {
|
||||
currentStaffId.value = record.id
|
||||
modalTitle.value = '编辑行政人员'
|
||||
formData.name = record.name
|
||||
formData.department_id = record.department_id
|
||||
formData.position_id = record.position_id
|
||||
formData.phone = record.phone
|
||||
formData.id_card = record.id_card
|
||||
formData.status = record.status
|
||||
isModalOpen.value = true
|
||||
}
|
||||
|
||||
// 处理模态框确认
|
||||
const handleModalOk = async () => {
|
||||
try {
|
||||
if (currentStaffId.value) {
|
||||
// 编辑
|
||||
await api.government.adminStaff.update(currentStaffId.value, formData)
|
||||
message.success('编辑行政人员成功')
|
||||
} else {
|
||||
// 新增
|
||||
await api.government.adminStaff.create(formData)
|
||||
message.success('新增行政人员成功')
|
||||
}
|
||||
isModalOpen.value = false
|
||||
fetchAdminStaffList()
|
||||
} catch (error) {
|
||||
message.error(currentStaffId.value ? '编辑行政人员失败' : '新增行政人员失败')
|
||||
console.error('操作行政人员失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理模态框取消
|
||||
const handleModalCancel = () => {
|
||||
isModalOpen.value = false
|
||||
}
|
||||
|
||||
// 更新员工状态
|
||||
const updateStaffStatus = async (record) => {
|
||||
try {
|
||||
await api.government.adminStaff.update(record.id, {
|
||||
status: record.status
|
||||
})
|
||||
message.success('更新状态成功')
|
||||
} catch (error) {
|
||||
record.status = !record.status // 回滚状态
|
||||
message.error('更新状态失败')
|
||||
console.error('更新状态失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理重置密码
|
||||
const handleResetPassword = (record) => {
|
||||
Modal.confirm({
|
||||
title: '确认重置密码',
|
||||
content: `确定要重置 ${record.name} 的密码吗?重置后密码将变为 123456`,
|
||||
onOk: async () => {
|
||||
try {
|
||||
await api.government.adminStaff.resetPassword(record.id)
|
||||
message.success('重置密码成功')
|
||||
} catch (error) {
|
||||
message.error('重置密码失败')
|
||||
console.error('重置密码失败:', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 删除员工
|
||||
const deleteStaff = (record) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: `确定要删除 ${record.name} 吗?`,
|
||||
onOk: async () => {
|
||||
try {
|
||||
await api.government.adminStaff.delete(record.id)
|
||||
message.success('删除成功')
|
||||
fetchAdminStaffList()
|
||||
} catch (error) {
|
||||
message.error('删除失败')
|
||||
console.error('删除失败:', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 组件挂载时初始化数据
|
||||
onMounted(() => {
|
||||
initData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -110,43 +110,13 @@
|
||||
<div class="update-section">
|
||||
<a-card class="update-card" title="数据更新信息">
|
||||
<a-list>
|
||||
<a-list-item>
|
||||
<a-list-item v-for="(item, index) in updates" :key="index">
|
||||
<div class="update-item">
|
||||
<div class="update-icon blue"></div>
|
||||
<div class="update-content">
|
||||
<div class="update-title">市场行情数据更新</div>
|
||||
<div class="update-time">2024-04-10 15:30:00</div>
|
||||
<div class="update-desc">更新全国主要地区牛肉、牛奶、饲料价格数据</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<div class="update-item">
|
||||
<div class="update-icon green"></div>
|
||||
<div class="update-content">
|
||||
<div class="update-title">养殖户数据同步</div>
|
||||
<div class="update-time">2024-04-10 10:15:00</div>
|
||||
<div class="update-desc">新增56家养殖户信息,更新32家养殖户状态</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<div class="update-item">
|
||||
<div class="update-icon orange"></div>
|
||||
<div class="update-content">
|
||||
<div class="update-title">产品认证数据导入</div>
|
||||
<div class="update-time">2024-04-09 16:45:00</div>
|
||||
<div class="update-desc">导入120条生资产品认证信息</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<div class="update-item">
|
||||
<div class="update-icon red"></div>
|
||||
<div class="update-content">
|
||||
<div class="update-title">疫病监测数据更新</div>
|
||||
<div class="update-time">2024-04-09 09:20:00</div>
|
||||
<div class="update-desc">更新本周疫病监测数据,暂无异常情况</div>
|
||||
<div class="update-title">数据更新</div>
|
||||
<div class="update-time">{{ item.time }}</div>
|
||||
<div class="update-desc">{{ item.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-list-item>
|
||||
@@ -157,14 +127,22 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { ref, onMounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import axios from 'axios';
|
||||
|
||||
// 数据统计
|
||||
const 养殖户总数 = ref('8,256')
|
||||
const 存栏总量 = ref('426,831头')
|
||||
const 交易量 = ref('¥3.26亿')
|
||||
const 活跃用户 = ref('12,548')
|
||||
const 养殖户总数 = ref('0')
|
||||
const 存栏总量 = ref('0头')
|
||||
const 交易量 = ref('¥0')
|
||||
const 活跃用户 = ref('0')
|
||||
const updates = ref([])
|
||||
|
||||
// 图表数据
|
||||
const monthlyTrends = ref([])
|
||||
const categoryDistribution = ref([])
|
||||
const regionDistribution = ref([])
|
||||
const scaleDistribution = ref([])
|
||||
|
||||
// 图表引用
|
||||
const mapChartRef = ref(null)
|
||||
@@ -174,7 +152,7 @@ const categoryChartRef = ref(null)
|
||||
|
||||
// 初始化交易量趋势图表
|
||||
const initTransactionChart = () => {
|
||||
if (!transactionChartRef.value) return
|
||||
if (!transactionChartRef.value || !monthlyTrends.value.length) return
|
||||
|
||||
const chart = echarts.init(transactionChartRef.value)
|
||||
|
||||
@@ -191,7 +169,7 @@ const initTransactionChart = () => {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: ['1月', '2月', '3月', '4月', '5月', '6月']
|
||||
data: monthlyTrends.value.map(item => item.month)
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
@@ -211,7 +189,7 @@ const initTransactionChart = () => {
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [2.8, 3.1, 3.5, 3.26, 3.4, 3.6],
|
||||
data: monthlyTrends.value.map(item => item.value / 10000),
|
||||
itemStyle: {
|
||||
color: '#3a4de9'
|
||||
},
|
||||
@@ -234,7 +212,7 @@ const initTransactionChart = () => {
|
||||
|
||||
// 初始化品类占比图表
|
||||
const initCategoryChart = () => {
|
||||
if (!categoryChartRef.value) return
|
||||
if (!categoryChartRef.value || !categoryDistribution.value.length) return
|
||||
|
||||
const chart = echarts.init(categoryChartRef.value)
|
||||
|
||||
@@ -272,12 +250,7 @@ const initCategoryChart = () => {
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 45, name: '肉牛养殖', itemStyle: { color: '#3a4de9' } },
|
||||
{ value: 30, name: '奶牛养殖', itemStyle: { color: '#4cd137' } },
|
||||
{ value: 15, name: '犊牛养殖', itemStyle: { color: '#e1b12c' } },
|
||||
{ value: 10, name: '其他养殖', itemStyle: { color: '#44bd32' } }
|
||||
]
|
||||
data: categoryDistribution.value
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -291,7 +264,7 @@ const initCategoryChart = () => {
|
||||
|
||||
// 初始化养殖区域分布图表
|
||||
const initMapChart = () => {
|
||||
if (!mapChartRef.value) return
|
||||
if (!mapChartRef.value || !regionDistribution.value.length) return
|
||||
|
||||
const chart = echarts.init(mapChartRef.value)
|
||||
|
||||
@@ -303,7 +276,7 @@ const initMapChart = () => {
|
||||
legend: {
|
||||
bottom: '5%',
|
||||
left: 'center',
|
||||
data: ['东北地区', '华北地区', '华东地区', '华南地区', '西南地区', '西北地区']
|
||||
data: regionDistribution.value.map(item => item.name)
|
||||
},
|
||||
series: [
|
||||
{
|
||||
@@ -330,14 +303,7 @@ const initMapChart = () => {
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 28, name: '东北地区', itemStyle: { color: '#3a4de9' } },
|
||||
{ value: 22, name: '华北地区', itemStyle: { color: '#4cd137' } },
|
||||
{ value: 18, name: '华东地区', itemStyle: { color: '#e1b12c' } },
|
||||
{ value: 12, name: '华南地区', itemStyle: { color: '#44bd32' } },
|
||||
{ value: 15, name: '西南地区', itemStyle: { color: '#0097e6' } },
|
||||
{ value: 5, name: '西北地区', itemStyle: { color: '#8c7ae6' } }
|
||||
]
|
||||
data: regionDistribution.value
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -351,7 +317,7 @@ const initMapChart = () => {
|
||||
|
||||
// 初始化养殖规模分布图表
|
||||
const initScaleChart = () => {
|
||||
if (!scaleChartRef.value) return
|
||||
if (!scaleChartRef.value || !scaleDistribution.value.length) return
|
||||
|
||||
const chart = echarts.init(scaleChartRef.value)
|
||||
|
||||
@@ -370,7 +336,7 @@ const initScaleChart = () => {
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['小型养殖场(<50头)', '中型养殖场(50-200头)', '大型养殖场(>200头)']
|
||||
data: scaleDistribution.value.map(item => item.name)
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
@@ -381,7 +347,7 @@ const initScaleChart = () => {
|
||||
name: '养殖场数量',
|
||||
type: 'bar',
|
||||
barWidth: '60%',
|
||||
data: [6850, 1250, 156],
|
||||
data: scaleDistribution.value.map(item => item.value),
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: '#3a4de9' },
|
||||
@@ -399,15 +365,41 @@ const initScaleChart = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 组件挂载时初始化所有图表
|
||||
// 从API获取数据
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await axios.get('/api/government/data-center');
|
||||
const data = response.data;
|
||||
|
||||
// 更新统计数据
|
||||
养殖户总数.value = data.totalFarmers.toLocaleString();
|
||||
存栏总量.value = `${data.totalAnimals.toLocaleString()}头`;
|
||||
交易量.value = `¥${(data.totalTransactions / 10000).toFixed(2)}亿`;
|
||||
活跃用户.value = data.activeUsers.toLocaleString();
|
||||
|
||||
// 更新图表数据
|
||||
monthlyTrends.value = data.monthlyTrends;
|
||||
categoryDistribution.value = data.categoryDistribution;
|
||||
regionDistribution.value = data.regionDistribution;
|
||||
scaleDistribution.value = data.scaleDistribution;
|
||||
updates.value = data.updates;
|
||||
|
||||
// 初始化所有图表
|
||||
setTimeout(() => {
|
||||
initTransactionChart();
|
||||
initCategoryChart();
|
||||
initMapChart();
|
||||
initScaleChart();
|
||||
}, 100);
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 组件挂载时获取数据并初始化图表
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
initTransactionChart()
|
||||
initCategoryChart()
|
||||
initMapChart()
|
||||
initScaleChart()
|
||||
}, 100)
|
||||
})
|
||||
fetchData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="market-price-container">
|
||||
<!-- 产品类型选项卡 -->
|
||||
<div class="product-tabs">
|
||||
<a-tabs v-model:activeKey="activeProductTab">
|
||||
<a-tabs v-model:activeKey="activeProductTab" @change="handleTabChange">
|
||||
<a-tab-pane key="beef" tab="育肥牛"></a-tab-pane>
|
||||
<a-tab-pane key="dairy" tab="繁殖牛"></a-tab-pane>
|
||||
<a-tab-pane key="milk" tab="奶牛"></a-tab-pane>
|
||||
@@ -17,7 +17,7 @@
|
||||
<template #title>
|
||||
<div class="card-title">
|
||||
<span>本市{{ productTypeText }}价格</span>
|
||||
<span class="price-date">2025-01-01</span>
|
||||
<span class="price-date">{{ priceDate }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="price-info">
|
||||
@@ -26,8 +26,12 @@
|
||||
<span class="price-unit">元/公斤</span>
|
||||
</div>
|
||||
<div class="price-change">
|
||||
<span class="change-value">+0.30</span>
|
||||
<span class="change-percent">+1.32%</span>
|
||||
<span class="change-value" :style="{ color: isPriceIncrease ? '#52c41a' : '#ff4d4f' }">
|
||||
{{ priceChange }}
|
||||
</span>
|
||||
<span class="change-percent" :style="{ color: isPriceIncrease ? '#52c41a' : '#ff4d4f' }">
|
||||
{{ priceChangePercent }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
@@ -50,12 +54,30 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import axios from 'axios'
|
||||
|
||||
// 当前选中的产品类型
|
||||
const activeProductTab = ref('beef')
|
||||
|
||||
// 响应式数据
|
||||
const currentPrice = ref('--')
|
||||
const priceChange = ref('--')
|
||||
const priceChangePercent = ref('--')
|
||||
const priceDate = ref('--')
|
||||
const priceTrendData = ref([])
|
||||
const provincePricesData = ref([])
|
||||
const isPriceIncrease = ref(true)
|
||||
|
||||
// 图表引用
|
||||
const priceChartRef = ref(null)
|
||||
const provinceChartRef = ref(null)
|
||||
|
||||
// 图表实例
|
||||
let priceChart = null
|
||||
let provinceChart = null
|
||||
|
||||
// 产品类型文本映射
|
||||
const productTypeText = computed(() => {
|
||||
const map = {
|
||||
@@ -66,25 +88,57 @@ const productTypeText = computed(() => {
|
||||
return map[activeProductTab.value] || '育肥牛'
|
||||
})
|
||||
|
||||
// 当前价格
|
||||
const currentPrice = ref('--')
|
||||
// 从后端获取市场行情数据
|
||||
const fetchMarketPriceData = async (type = 'beef') => {
|
||||
try {
|
||||
const response = await axios.get('/api/government/market-price', {
|
||||
params: { type }
|
||||
})
|
||||
|
||||
const data = response.data
|
||||
|
||||
// 更新数据
|
||||
currentPrice.value = data.currentPrice
|
||||
priceChange.value = data.priceChange
|
||||
priceChangePercent.value = data.priceChangePercent
|
||||
priceDate.value = data.priceDate
|
||||
priceTrendData.value = data.priceTrend
|
||||
provincePricesData.value = data.provincePrices
|
||||
|
||||
// 判断价格是否上涨
|
||||
isPriceIncrease.value = data.priceChange.startsWith('+')
|
||||
|
||||
// 初始化或更新图表
|
||||
updatePriceChart()
|
||||
updateProvinceChart()
|
||||
} catch (error) {
|
||||
console.error('获取市场行情数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 图表引用
|
||||
const priceChartRef = ref(null)
|
||||
const provinceChartRef = ref(null)
|
||||
|
||||
// 初始化价格走势图表
|
||||
const initPriceChart = () => {
|
||||
// 初始化或更新价格走势图表
|
||||
const updatePriceChart = () => {
|
||||
if (!priceChartRef.value) return
|
||||
|
||||
const chart = echarts.init(priceChartRef.value)
|
||||
// 如果图表实例不存在,则创建
|
||||
if (!priceChart) {
|
||||
priceChart = echarts.init(priceChartRef.value)
|
||||
|
||||
// 添加窗口大小改变时的响应式调整
|
||||
window.addEventListener('resize', () => {
|
||||
if (priceChart) {
|
||||
priceChart.resize()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 模拟历史价格数据
|
||||
const dates = ['2024-12-19', '2024-12-20', '2024-12-21', '2024-12-22', '2024-12-23',
|
||||
'2024-12-24', '2024-12-25', '2024-12-26', '2024-12-27', '2024-12-28',
|
||||
'2024-12-29', '2024-12-30', '2024-12-31', '2025-01-01']
|
||||
// 提取日期和价格数据
|
||||
const dates = priceTrendData.value.map(item => item.date)
|
||||
const prices = priceTrendData.value.map(item => item.price)
|
||||
|
||||
const prices = [23.10, 20.65, 24.90, 21.78, 22.15, 24.30, 23.20, 21.60, 20.35, 24.05, 23.45, 20.95, 22.50, 21.80]
|
||||
// 计算Y轴范围
|
||||
const minPrice = Math.min(...prices) * 0.9
|
||||
const maxPrice = Math.max(...prices) * 1.1
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
@@ -111,9 +165,9 @@ const initPriceChart = () => {
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 25,
|
||||
interval: 5
|
||||
min: Math.floor(minPrice),
|
||||
max: Math.ceil(maxPrice),
|
||||
interval: Math.ceil((maxPrice - minPrice) / 5)
|
||||
},
|
||||
series: [
|
||||
{
|
||||
@@ -136,24 +190,31 @@ const initPriceChart = () => {
|
||||
]
|
||||
}
|
||||
|
||||
chart.setOption(option)
|
||||
|
||||
// 响应式调整
|
||||
window.addEventListener('resize', () => {
|
||||
chart.resize()
|
||||
})
|
||||
priceChart.setOption(option)
|
||||
}
|
||||
|
||||
// 初始化各省价格对比图表
|
||||
const initProvinceChart = () => {
|
||||
// 初始化或更新各省价格对比图表
|
||||
const updateProvinceChart = () => {
|
||||
if (!provinceChartRef.value) return
|
||||
|
||||
const chart = echarts.init(provinceChartRef.value)
|
||||
// 如果图表实例不存在,则创建
|
||||
if (!provinceChart) {
|
||||
provinceChart = echarts.init(provinceChartRef.value)
|
||||
|
||||
// 添加窗口大小改变时的响应式调整
|
||||
window.addEventListener('resize', () => {
|
||||
if (provinceChart) {
|
||||
provinceChart.resize()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 模拟各省价格数据
|
||||
const provinces = ['上海市', '云南省', '内蒙古自治区', '北京市', '吉林省', '四川省', '天津市', '宁夏回族自治区', '安徽省', '山东省', '山西省', '广东省', '广西壮族自治区', '新疆维吾尔自治区', '江苏省', '江西省', '河北省', '河南省', '浙江省', '海南省', '湖北省', '湖南省', '甘肃省', '福建省', '贵州省', '辽宁省', '重庆市', '陕西省', '青海省', '黑龙江省']
|
||||
// 提取省份和价格数据
|
||||
const provinces = provincePricesData.value.map(item => item.province)
|
||||
const prices = provincePricesData.value.map(item => item.price)
|
||||
|
||||
const prices = [36, 34.85, 34.85, 35.7, 33.26, 34.9, 35.4, 36.51, 33.5, 35.4, 35.8, 35.3, 32.6, 35.8, 34.1, 35.2, 33.2, 36, 35, 35.4, 32, 33.2, 34.8, 32.86, 32.7, 33, 32.8, 33.4, 33, 35.4]
|
||||
// 计算X轴范围
|
||||
const maxPrice = Math.max(...prices) * 1.1
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
@@ -172,8 +233,8 @@ const initProvinceChart = () => {
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 40,
|
||||
interval: 10
|
||||
max: Math.ceil(maxPrice),
|
||||
interval: Math.ceil(maxPrice / 5)
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
@@ -198,25 +259,34 @@ const initProvinceChart = () => {
|
||||
]
|
||||
}
|
||||
|
||||
chart.setOption(option)
|
||||
|
||||
// 响应式调整
|
||||
window.addEventListener('resize', () => {
|
||||
chart.resize()
|
||||
})
|
||||
provinceChart.setOption(option)
|
||||
}
|
||||
|
||||
// 组件挂载时初始化图表
|
||||
// 处理选项卡切换
|
||||
const handleTabChange = (key) => {
|
||||
activeProductTab.value = key
|
||||
fetchMarketPriceData(key)
|
||||
}
|
||||
|
||||
// 组件挂载时初始化数据和图表
|
||||
onMounted(() => {
|
||||
// 设置当前价格
|
||||
currentPrice.value = '23.10'
|
||||
|
||||
// 初始化图表
|
||||
// 延迟执行,确保DOM已完全渲染
|
||||
setTimeout(() => {
|
||||
initPriceChart()
|
||||
initProvinceChart()
|
||||
fetchMarketPriceData(activeProductTab.value)
|
||||
}, 100)
|
||||
})
|
||||
|
||||
// 组件卸载时销毁图表实例
|
||||
const onUnmounted = () => {
|
||||
if (priceChart) {
|
||||
priceChart.dispose()
|
||||
priceChart = null
|
||||
}
|
||||
if (provinceChart) {
|
||||
provinceChart.dispose()
|
||||
provinceChart = null
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
52
government-admin/test-api.js
Normal file
52
government-admin/test-api.js
Normal file
@@ -0,0 +1,52 @@
|
||||
// 从前端目录测试API访问
|
||||
const axios = require('axios');
|
||||
|
||||
// 创建axios实例,使用与前端相同的配置
|
||||
const api = axios.create({
|
||||
baseURL: 'http://localhost:5352/api',
|
||||
timeout: 5000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
async function testApi() {
|
||||
try {
|
||||
console.log('开始从前端目录测试API...');
|
||||
|
||||
// 测试行政人员列表API
|
||||
console.log('\n测试行政人员列表API:');
|
||||
const adminStaffResponse = await api.get('/government/admin-staff');
|
||||
console.log(`✅ 行政人员列表API调用成功,返回${adminStaffResponse.data.length}条数据`);
|
||||
|
||||
// 测试部门列表API
|
||||
console.log('\n测试部门列表API:');
|
||||
const departmentResponse = await api.get('/government/departments');
|
||||
console.log(`✅ 部门列表API调用成功,返回${departmentResponse.data.length}条数据`);
|
||||
|
||||
// 测试岗位列表API
|
||||
console.log('\n测试岗位列表API:');
|
||||
const positionResponse = await api.get('/government/positions');
|
||||
console.log(`✅ 岗位列表API调用成功,返回${positionResponse.data.length}条数据`);
|
||||
|
||||
// 测试带有查询参数的API
|
||||
console.log('\n测试带查询参数的API:');
|
||||
const filteredResponse = await api.get('/government/admin-staff?page=1&pageSize=3');
|
||||
console.log(`✅ 带查询参数的API调用成功,返回${filteredResponse.data.length}条数据`);
|
||||
|
||||
console.log('\n✅ 所有API测试成功完成!');
|
||||
} catch (error) {
|
||||
console.error('❌ API测试失败:', error.message);
|
||||
if (error.response) {
|
||||
console.error('错误状态码:', error.response.status);
|
||||
console.error('错误数据:', error.response.data);
|
||||
} else if (error.request) {
|
||||
console.error('没有收到响应:', error.request);
|
||||
} else {
|
||||
console.error('请求配置错误:', error.message);
|
||||
}
|
||||
console.error('错误详情:', error);
|
||||
}
|
||||
}
|
||||
|
||||
testApi();
|
||||
Reference in New Issue
Block a user