From 1a1abf4c2624a19f5404f0b2ef901a003dc2680a Mon Sep 17 00:00:00 2001 From: dengyuxin Date: Thu, 9 Oct 2025 18:01:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=94=BF=E5=BA=9C=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bank_mini_program/pages/business/business.js | 4 +- government-admin/src/layout/Sidebar.vue | 6 +- .../src/utils/approvalProcessApi.js | 62 ++ .../src/utils/cattleAcademyApi.js | 62 ++ .../src/utils/deviceWarningApi.js | 44 + .../src/utils/epidemicActivityApi.js | 73 ++ .../productionMaterialCertificationApi.js | 59 ++ .../src/views/ApprovalProcess.vue | 230 +++-- government-admin/src/views/CattleAcademy.vue | 404 ++++++++- government-admin/src/views/DeviceWarning.vue | 286 +++++- .../EpidemicActivityManagement.vue | 840 +++++++----------- .../ProductionMaterialCertification.vue | 626 +++++++++++++ government-backend/app.js | 5 + .../controllers/approvalProcessController.js | 286 ++++++ .../controllers/cattleAcademyController.js | 298 +++++++ .../controllers/deviceWarningController.js | 177 ++++ .../controllers/epidemicActivityController.js | 242 +++++ ...oductionMaterialCertificationController.js | 280 ++++++ government-backend/models/ApprovalProcess.js | 93 ++ government-backend/models/CattleAcademy.js | 98 ++ government-backend/models/DeviceWarning.js | 107 +++ government-backend/models/EpidemicActivity.js | 63 ++ .../models/ProductionMaterialCertification.js | 103 +++ government-backend/routes/approvalProcess.js | 18 + government-backend/routes/cattleAcademy.js | 18 + government-backend/routes/deviceWarning.js | 17 + government-backend/routes/epidemicActivity.js | 17 + .../routes/productionMaterialCertification.js | 17 + .../sql/create_device_warnings_table.sql | 22 + .../sql/create_epidemic_activities_table.sql | 26 + .../sql/insert_cattle_academy_data.sql | 12 + .../sql/insert_device_warning_data.sql | 16 + government-backend/test-cattle-academy-api.js | 132 +++ government-backend/test-device-warning-api.js | 99 +++ .../test-epidemic-activity-api.js | 124 +++ website/bank-system.html | 4 +- website/farm-system.html | 4 +- website/government-system.html | 4 +- website/insurance-system.html | 4 +- 39 files changed, 4309 insertions(+), 673 deletions(-) create mode 100644 government-admin/src/utils/approvalProcessApi.js create mode 100644 government-admin/src/utils/cattleAcademyApi.js create mode 100644 government-admin/src/utils/deviceWarningApi.js create mode 100644 government-admin/src/utils/epidemicActivityApi.js create mode 100644 government-admin/src/utils/productionMaterialCertificationApi.js create mode 100644 government-admin/src/views/paperless/production-material/ProductionMaterialCertification.vue create mode 100644 government-backend/controllers/approvalProcessController.js create mode 100644 government-backend/controllers/cattleAcademyController.js create mode 100644 government-backend/controllers/deviceWarningController.js create mode 100644 government-backend/controllers/epidemicActivityController.js create mode 100644 government-backend/controllers/productionMaterialCertificationController.js create mode 100644 government-backend/models/ApprovalProcess.js create mode 100644 government-backend/models/CattleAcademy.js create mode 100644 government-backend/models/DeviceWarning.js create mode 100644 government-backend/models/EpidemicActivity.js create mode 100644 government-backend/models/ProductionMaterialCertification.js create mode 100644 government-backend/routes/approvalProcess.js create mode 100644 government-backend/routes/cattleAcademy.js create mode 100644 government-backend/routes/deviceWarning.js create mode 100644 government-backend/routes/epidemicActivity.js create mode 100644 government-backend/routes/productionMaterialCertification.js create mode 100644 government-backend/sql/create_device_warnings_table.sql create mode 100644 government-backend/sql/create_epidemic_activities_table.sql create mode 100644 government-backend/sql/insert_cattle_academy_data.sql create mode 100644 government-backend/sql/insert_device_warning_data.sql create mode 100644 government-backend/test-cattle-academy-api.js create mode 100644 government-backend/test-device-warning-api.js create mode 100644 government-backend/test-epidemic-activity-api.js diff --git a/bank_mini_program/pages/business/business.js b/bank_mini_program/pages/business/business.js index 43decd3..3c4a7b3 100644 --- a/bank_mini_program/pages/business/business.js +++ b/bank_mini_program/pages/business/business.js @@ -42,8 +42,8 @@ Page({ // 并行获取各项统计数据 const [productsRes, applicationsRes, contractsRes, releasesRes] = await Promise.allSettled([ apiService.loanProducts.getStats(), - apiService.loanApplications.getStats(), - apiService.loanContracts.getStats(), + // apiService.loanApplications.getStats(), + // apiService.loanContracts.getStats(), apiService.loanReleases.getStats() ]); diff --git a/government-admin/src/layout/Sidebar.vue b/government-admin/src/layout/Sidebar.vue index b236603..d7204e5 100644 --- a/government-admin/src/layout/Sidebar.vue +++ b/government-admin/src/layout/Sidebar.vue @@ -85,7 +85,7 @@ - + @@ -108,7 +108,7 @@ - + 设备预警 diff --git a/government-admin/src/utils/approvalProcessApi.js b/government-admin/src/utils/approvalProcessApi.js new file mode 100644 index 0000000..c1bdb8f --- /dev/null +++ b/government-admin/src/utils/approvalProcessApi.js @@ -0,0 +1,62 @@ +import axios from 'axios' + +const API_BASE_URL = 'http://localhost:5352/api/approval-process' + +// 创建axios实例 +const api = axios.create({ + baseURL: API_BASE_URL, + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + // 可以在这里添加token等认证信息 + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + return response.data + }, + error => { + console.error('API请求错误:', error) + return Promise.reject(error) + } +) + +// 审批流程管理API +export default { + // 获取审批流程列表 + getApprovalProcesses: (params) => api.get('/', { params }), + + // 获取审批流程详情 + getApprovalProcessById: (id) => api.get(`/${id}`), + + // 创建审批流程 + createApprovalProcess: (data) => api.post('/', data), + + // 更新审批流程 + updateApprovalProcess: (id, data) => api.put(`/${id}`, data), + + // 删除审批流程 + deleteApprovalProcess: (id) => api.delete(`/${id}`), + + // 审批操作(通过/拒绝) + processApproval: (id, data) => api.post(`/${id}/process`, data), + + // 更新审批状态 + updateApprovalStatus: (id, status) => api.patch(`/${id}/status`, { status }) +} diff --git a/government-admin/src/utils/cattleAcademyApi.js b/government-admin/src/utils/cattleAcademyApi.js new file mode 100644 index 0000000..9b26302 --- /dev/null +++ b/government-admin/src/utils/cattleAcademyApi.js @@ -0,0 +1,62 @@ +import axios from 'axios' + +const API_BASE_URL = 'http://localhost:5352/api/cattle-academy' + +// 创建axios实例 +const api = axios.create({ + baseURL: API_BASE_URL, + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + // 可以在这里添加token等认证信息 + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + return response.data + }, + error => { + console.error('API请求错误:', error) + return Promise.reject(error) + } +) + +// 养牛学院资讯管理API +export default { + // 获取养牛学院资讯列表 + getCattleAcademyList: (params) => api.get('/', { params }), + + // 获取养牛学院资讯详情 + getCattleAcademyById: (id) => api.get(`/${id}`), + + // 创建养牛学院资讯 + createCattleAcademy: (data) => api.post('/', data), + + // 更新养牛学院资讯 + updateCattleAcademy: (id, data) => api.put(`/${id}`, data), + + // 删除养牛学院资讯 + deleteCattleAcademy: (id) => api.delete(`/${id}`), + + // 切换资讯状态 + toggleCattleAcademyStatus: (id, status) => api.patch(`/${id}/status`, { status }), + + // 批量更新排序 + updateSort: (items) => api.patch('/sort', { items }) +} diff --git a/government-admin/src/utils/deviceWarningApi.js b/government-admin/src/utils/deviceWarningApi.js new file mode 100644 index 0000000..9e395a7 --- /dev/null +++ b/government-admin/src/utils/deviceWarningApi.js @@ -0,0 +1,44 @@ +import axios from 'axios'; + +const API_BASE_URL = 'http://localhost:5352/api/device-warning'; + +const api = axios.create({ + baseURL: API_BASE_URL, + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}); + +api.interceptors.request.use( + config => { + const token = localStorage.getItem('token'); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + return config; + }, + error => { + return Promise.reject(error); + } +); + +api.interceptors.response.use( + response => { + return response.data; + }, + error => { + console.error('API Error:', error.response ? error.response.data : error.message); + return Promise.reject(error); + } +); + +export default { + getDeviceWarnings: (params) => api.get('/', { params }), + getDeviceWarningById: (id) => api.get(`/${id}`), + createDeviceWarning: (data) => api.post('/', data), + updateDeviceWarning: (id, data) => api.put(`/${id}`, data), + deleteDeviceWarning: (id) => api.delete(`/${id}`), + updateWarningStatus: (id, data) => api.patch(`/${id}/status`, data), + getWarningStats: () => api.get('/stats'), +}; diff --git a/government-admin/src/utils/epidemicActivityApi.js b/government-admin/src/utils/epidemicActivityApi.js new file mode 100644 index 0000000..3121661 --- /dev/null +++ b/government-admin/src/utils/epidemicActivityApi.js @@ -0,0 +1,73 @@ +import axios from 'axios' + +const API_BASE_URL = 'http://localhost:5352/api/epidemic-activity' + +// 创建axios实例 +const api = axios.create({ + baseURL: API_BASE_URL, + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + // 可以在这里添加token等认证信息 + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + return response.data + }, + error => { + console.error('API请求错误:', error) + return Promise.reject(error) + } +) + +// 防疫活动管理API +export const epidemicActivityApi = { + // 获取防疫活动列表 + getActivities(params = {}) { + return api.get('/', { params }) + }, + + // 根据ID获取防疫活动详情 + getActivityById(id) { + return api.get(`/${id}`) + }, + + // 创建防疫活动 + createActivity(data) { + return api.post('/', data) + }, + + // 更新防疫活动 + updateActivity(id, data) { + return api.put(`/${id}`, data) + }, + + // 删除防疫活动 + deleteActivity(id) { + return api.delete(`/${id}`) + }, + + // 切换活动状态 + toggleActivityStatus(id) { + return api.patch(`/${id}/status`) + } +} + +export default epidemicActivityApi diff --git a/government-admin/src/utils/productionMaterialCertificationApi.js b/government-admin/src/utils/productionMaterialCertificationApi.js new file mode 100644 index 0000000..68934b4 --- /dev/null +++ b/government-admin/src/utils/productionMaterialCertificationApi.js @@ -0,0 +1,59 @@ +import axios from 'axios' + +const API_BASE_URL = 'http://localhost:5352/api/production-material-certification' + +// 创建axios实例 +const api = axios.create({ + baseURL: API_BASE_URL, + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 请求拦截器 +api.interceptors.request.use( + config => { + // 可以在这里添加token等认证信息 + const token = localStorage.getItem('token') + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + error => { + return Promise.reject(error) + } +) + +// 响应拦截器 +api.interceptors.response.use( + response => { + return response.data + }, + error => { + console.error('API请求错误:', error) + return Promise.reject(error) + } +) + +// 生资认证管理API +export default { + // 获取生资认证列表 + getCertifications: (params) => api.get('/', { params }), + + // 获取生资认证详情 + getCertificationById: (id) => api.get(`/${id}`), + + // 创建生资认证 + createCertification: (data) => api.post('/', data), + + // 更新生资认证 + updateCertification: (id, data) => api.put(`/${id}`, data), + + // 删除生资认证 + deleteCertification: (id) => api.delete(`/${id}`), + + // 切换认证状态 + toggleCertificationStatus: (id, status) => api.patch(`/${id}/status`, { status }) +} diff --git a/government-admin/src/views/ApprovalProcess.vue b/government-admin/src/views/ApprovalProcess.vue index d6994d6..b7821e6 100644 --- a/government-admin/src/views/ApprovalProcess.vue +++ b/government-admin/src/views/ApprovalProcess.vue @@ -22,7 +22,7 @@ -
+
@@ -32,15 +32,21 @@ {{ getStatusText(item.status) }}
-

认证申请人: {{ item.applicant }}

-

认证类型: {{ item.type }}

-

认证数量: {{ item.quantity }}

-

申请时间: {{ item.create_time }}

-

联系电话: {{ item.phone }}

-

养殖场名称: {{ item.farmName }}

+

审批标题: {{ item.title }}

+

申请人: {{ item.applicant }}

+

审批类型: {{ getTypeText(item.type) }}

+

申请时间: {{ item.create_time }}

+

联系电话: {{ item.phone || '未填写' }}

+

养殖场名称: {{ item.farmName }}

+

认证数量: {{ item.quantity }}

+ + +
+ +
@@ -137,8 +143,8 @@ \ No newline at end of file diff --git a/government-admin/src/views/paperless/production-material/ProductionMaterialCertification.vue b/government-admin/src/views/paperless/production-material/ProductionMaterialCertification.vue new file mode 100644 index 0000000..fbcff9b --- /dev/null +++ b/government-admin/src/views/paperless/production-material/ProductionMaterialCertification.vue @@ -0,0 +1,626 @@ + + + + + diff --git a/government-backend/app.js b/government-backend/app.js index 449bf4a..36edf7d 100644 --- a/government-backend/app.js +++ b/government-backend/app.js @@ -55,6 +55,11 @@ app.use('/api/harmless', require('./routes/harmless')); app.use('/api/harmless-place', require('./routes/harmlessPlace')); app.use('/api/epidemic-record', require('./routes/epidemicRecord')); app.use('/api/vaccine', require('./routes/vaccine')); +app.use('/api/epidemic-activity', require('./routes/epidemicActivity')); +app.use('/api/production-material-certification', require('./routes/productionMaterialCertification')); +app.use('/api/approval-process', require('./routes/approvalProcess')); +app.use('/api/cattle-academy', require('./routes/cattleAcademy')); +app.use('/api/device-warning', require('./routes/deviceWarning')); // 健康检查 app.get('/health', (req, res) => { diff --git a/government-backend/controllers/approvalProcessController.js b/government-backend/controllers/approvalProcessController.js new file mode 100644 index 0000000..63b2205 --- /dev/null +++ b/government-backend/controllers/approvalProcessController.js @@ -0,0 +1,286 @@ +const ApprovalProcess = require('../models/ApprovalProcess'); +const { Op } = require('sequelize'); + +// 获取审批流程列表 +const getApprovalProcesses = async (req, res) => { + try { + const { + page = 1, + pageSize = 9, + status, + applicant, + type + } = req.query; + + const offset = (page - 1) * pageSize; + const where = {}; + + // 构建查询条件 + if (status) { + where.status = status; + } + if (applicant) { + where.applicant = { + [Op.like]: `%${applicant}%` + }; + } + if (type) { + where.type = type; + } + + const { count, rows } = await ApprovalProcess.findAndCountAll({ + where, + limit: parseInt(pageSize), + offset: parseInt(offset), + order: [['createdAt', 'DESC']] + }); + + res.json({ + code: 200, + message: '获取成功', + data: { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) + } + }); + } catch (error) { + console.error('获取审批流程列表失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 根据ID获取审批流程详情 +const getApprovalProcessById = async (req, res) => { + try { + const { id } = req.params; + const approvalProcess = await ApprovalProcess.findByPk(id); + + if (!approvalProcess) { + return res.status(404).json({ + code: 404, + message: '审批流程不存在' + }); + } + + res.json({ + code: 200, + message: '获取成功', + data: approvalProcess + }); + } catch (error) { + console.error('获取审批流程详情失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 创建审批流程 +const createApprovalProcess = async (req, res) => { + try { + const { + title, + type, + applicant, + phone, + farmName, + quantity, + description, + files, + remarks + } = req.body; + + const approvalProcess = await ApprovalProcess.create({ + title, + type, + applicant, + phone, + farmName, + quantity, + description, + files, + remarks, + status: 'pending' + }); + + res.status(201).json({ + code: 201, + message: '创建成功', + data: approvalProcess + }); + } catch (error) { + console.error('创建审批流程失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 更新审批流程 +const updateApprovalProcess = async (req, res) => { + try { + const { id } = req.params; + const { + title, + type, + applicant, + phone, + farmName, + quantity, + description, + files, + remarks + } = req.body; + + const approvalProcess = await ApprovalProcess.findByPk(id); + if (!approvalProcess) { + return res.status(404).json({ + code: 404, + message: '审批流程不存在' + }); + } + + await approvalProcess.update({ + title, + type, + applicant, + phone, + farmName, + quantity, + description, + files, + remarks + }); + + res.json({ + code: 200, + message: '更新成功', + data: approvalProcess + }); + } catch (error) { + console.error('更新审批流程失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 删除审批流程 +const deleteApprovalProcess = async (req, res) => { + try { + const { id } = req.params; + const approvalProcess = await ApprovalProcess.findByPk(id); + + if (!approvalProcess) { + return res.status(404).json({ + code: 404, + message: '审批流程不存在' + }); + } + + await approvalProcess.destroy(); + + res.json({ + code: 200, + message: '删除成功' + }); + } catch (error) { + console.error('删除审批流程失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 审批操作(通过/拒绝) +const processApproval = async (req, res) => { + try { + const { id } = req.params; + const { action, approvalComment, approver } = req.body; + + const approvalProcess = await ApprovalProcess.findByPk(id); + if (!approvalProcess) { + return res.status(404).json({ + code: 404, + message: '审批流程不存在' + }); + } + + const status = action === 'approve' ? 'approved' : 'rejected'; + + await approvalProcess.update({ + status, + approvalComment, + approver, + approvalTime: new Date() + }); + + res.json({ + code: 200, + message: action === 'approve' ? '审批通过' : '审批拒绝', + data: approvalProcess + }); + } catch (error) { + console.error('审批操作失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 更新审批状态 +const updateApprovalStatus = async (req, res) => { + try { + const { id } = req.params; + const { status } = req.body; + + const approvalProcess = await ApprovalProcess.findByPk(id); + if (!approvalProcess) { + return res.status(404).json({ + code: 404, + message: '审批流程不存在' + }); + } + + await approvalProcess.update({ status }); + + res.json({ + code: 200, + message: '状态更新成功', + data: approvalProcess + }); + } catch (error) { + console.error('更新审批状态失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +module.exports = { + getApprovalProcesses, + getApprovalProcessById, + createApprovalProcess, + updateApprovalProcess, + deleteApprovalProcess, + processApproval, + updateApprovalStatus +}; diff --git a/government-backend/controllers/cattleAcademyController.js b/government-backend/controllers/cattleAcademyController.js new file mode 100644 index 0000000..98bd5e3 --- /dev/null +++ b/government-backend/controllers/cattleAcademyController.js @@ -0,0 +1,298 @@ +const CattleAcademy = require('../models/CattleAcademy'); +const { Op } = require('sequelize'); + +// 获取养牛学院资讯列表 +const getCattleAcademyList = async (req, res) => { + try { + const { + page = 1, + pageSize = 10, + title, + category, + status, + author + } = req.query; + + const offset = (page - 1) * pageSize; + const where = {}; + + // 构建查询条件 + if (title) { + where.title = { + [Op.like]: `%${title}%` + }; + } + if (category) { + where.category = category; + } + if (status !== undefined) { + where.status = status === 'true' || status === true; + } + if (author) { + where.author = { + [Op.like]: `%${author}%` + }; + } + + const { count, rows } = await CattleAcademy.findAndCountAll({ + where, + limit: parseInt(pageSize), + offset: parseInt(offset), + order: [['sort', 'DESC'], ['createdAt', 'DESC']] + }); + + res.json({ + code: 200, + message: '获取成功', + data: { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) + } + }); + } catch (error) { + console.error('获取养牛学院资讯列表失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 根据ID获取养牛学院资讯详情 +const getCattleAcademyById = async (req, res) => { + try { + const { id } = req.params; + const cattleAcademy = await CattleAcademy.findByPk(id); + + if (!cattleAcademy) { + return res.status(404).json({ + code: 404, + message: '资讯不存在' + }); + } + + // 增加浏览次数 + await cattleAcademy.increment('viewCount'); + + res.json({ + code: 200, + message: '获取成功', + data: cattleAcademy + }); + } catch (error) { + console.error('获取养牛学院资讯详情失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 创建养牛学院资讯 +const createCattleAcademy = async (req, res) => { + try { + const { + title, + coverImage, + content, + summary, + category, + tags, + sort = 0, + status = true, + author, + publishTime, + isTop = false, + isRecommend = false, + remarks + } = req.body; + + const cattleAcademy = await CattleAcademy.create({ + title, + coverImage, + content, + summary, + category, + tags, + sort, + status, + author, + publishTime: publishTime || new Date(), + isTop, + isRecommend, + remarks + }); + + res.status(201).json({ + code: 201, + message: '创建成功', + data: cattleAcademy + }); + } catch (error) { + console.error('创建养牛学院资讯失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 更新养牛学院资讯 +const updateCattleAcademy = async (req, res) => { + try { + const { id } = req.params; + const { + title, + coverImage, + content, + summary, + category, + tags, + sort, + status, + author, + publishTime, + isTop, + isRecommend, + remarks + } = req.body; + + const cattleAcademy = await CattleAcademy.findByPk(id); + if (!cattleAcademy) { + return res.status(404).json({ + code: 404, + message: '资讯不存在' + }); + } + + await cattleAcademy.update({ + title, + coverImage, + content, + summary, + category, + tags, + sort, + status, + author, + publishTime, + isTop, + isRecommend, + remarks + }); + + res.json({ + code: 200, + message: '更新成功', + data: cattleAcademy + }); + } catch (error) { + console.error('更新养牛学院资讯失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 删除养牛学院资讯 +const deleteCattleAcademy = async (req, res) => { + try { + const { id } = req.params; + const cattleAcademy = await CattleAcademy.findByPk(id); + + if (!cattleAcademy) { + return res.status(404).json({ + code: 404, + message: '资讯不存在' + }); + } + + await cattleAcademy.destroy(); + + res.json({ + code: 200, + message: '删除成功' + }); + } catch (error) { + console.error('删除养牛学院资讯失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 切换资讯状态 +const toggleCattleAcademyStatus = async (req, res) => { + try { + const { id } = req.params; + const { status } = req.body; + + const cattleAcademy = await CattleAcademy.findByPk(id); + if (!cattleAcademy) { + return res.status(404).json({ + code: 404, + message: '资讯不存在' + }); + } + + await cattleAcademy.update({ status }); + + res.json({ + code: 200, + message: '状态更新成功', + data: cattleAcademy + }); + } catch (error) { + console.error('切换资讯状态失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 批量更新排序 +const updateSort = async (req, res) => { + try { + const { items } = req.body; // [{id, sort}, ...] + + for (const item of items) { + await CattleAcademy.update( + { sort: item.sort }, + { where: { id: item.id } } + ); + } + + res.json({ + code: 200, + message: '排序更新成功' + }); + } catch (error) { + console.error('更新排序失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +module.exports = { + getCattleAcademyList, + getCattleAcademyById, + createCattleAcademy, + updateCattleAcademy, + deleteCattleAcademy, + toggleCattleAcademyStatus, + updateSort +}; diff --git a/government-backend/controllers/deviceWarningController.js b/government-backend/controllers/deviceWarningController.js new file mode 100644 index 0000000..6df9e28 --- /dev/null +++ b/government-backend/controllers/deviceWarningController.js @@ -0,0 +1,177 @@ +const DeviceWarning = require('../models/DeviceWarning'); +const { Op, fn, col } = require('sequelize'); +const sequelize = require('../config/database'); + +// 获取设备预警列表 +exports.getDeviceWarnings = async (req, res) => { + try { + const { page = 1, pageSize = 20, deviceType, alertType, status, farmerName } = req.query; + const limit = parseInt(pageSize); + const offset = (parseInt(page) - 1) * limit; + + const where = {}; + if (deviceType) { + where.deviceType = deviceType; + } + if (alertType) { + where.alertType = alertType; + } + if (status) { + where.status = status; + } + if (farmerName) { + where.farmerName = { [Op.like]: `%${farmerName}%` }; + } + + const { count, rows } = await DeviceWarning.findAndCountAll({ + where, + limit, + offset, + order: [['alertTime', 'DESC']], + }); + + res.status(200).json({ + code: 200, + message: '获取成功', + data: { + list: rows, + total: count, + page: parseInt(page), + pageSize: limit, + }, + }); + } catch (error) { + console.error('获取设备预警列表失败:', error); + res.status(500).json({ code: 500, message: '获取设备预警列表失败', error: error.message }); + } +}; + +// 根据ID获取单个设备预警详情 +exports.getDeviceWarningById = async (req, res) => { + try { + const { id } = req.params; + const warning = await DeviceWarning.findByPk(id); + + if (!warning) { + return res.status(404).json({ code: 404, message: '设备预警未找到' }); + } + + res.status(200).json({ code: 200, message: '获取成功', data: warning }); + } catch (error) { + console.error('获取设备预警详情失败:', error); + res.status(500).json({ code: 500, message: '获取设备预警详情失败', error: error.message }); + } +}; + +// 创建新的设备预警 +exports.createDeviceWarning = async (req, res) => { + try { + const newWarning = await DeviceWarning.create(req.body); + res.status(201).json({ code: 201, message: '创建成功', data: newWarning }); + } catch (error) { + console.error('创建设备预警失败:', error); + res.status(500).json({ code: 500, message: '创建设备预警失败', error: error.message }); + } +}; + +// 更新设备预警 +exports.updateDeviceWarning = async (req, res) => { + try { + const { id } = req.params; + const [updatedRows] = await DeviceWarning.update(req.body, { + where: { id }, + }); + + if (updatedRows === 0) { + return res.status(404).json({ code: 404, message: '设备预警未找到或无更新' }); + } + + const updatedWarning = await DeviceWarning.findByPk(id); + res.status(200).json({ code: 200, message: '更新成功', data: updatedWarning }); + } catch (error) { + console.error('更新设备预警失败:', error); + res.status(500).json({ code: 500, message: '更新设备预警失败', error: error.message }); + } +}; + +// 删除设备预警 +exports.deleteDeviceWarning = async (req, res) => { + try { + const { id } = req.params; + const deletedRows = await DeviceWarning.destroy({ + where: { id }, + }); + + if (deletedRows === 0) { + return res.status(404).json({ code: 404, message: '设备预警未找到' }); + } + + res.status(200).json({ code: 200, message: '删除成功' }); + } catch (error) { + console.error('删除设备预警失败:', error); + res.status(500).json({ code: 500, message: '删除设备预警失败', error: error.message }); + } +}; + +// 更新预警状态 +exports.updateWarningStatus = async (req, res) => { + try { + const { id } = req.params; + const { status, resolvedBy } = req.body; + + const warning = await DeviceWarning.findByPk(id); + if (!warning) { + return res.status(404).json({ code: 404, message: '设备预警未找到' }); + } + + warning.status = status; + if (status === 'resolved') { + warning.resolvedBy = resolvedBy; + warning.resolvedAt = new Date(); + } + await warning.save(); + + res.status(200).json({ code: 200, message: '状态更新成功', data: warning }); + } catch (error) { + console.error('更新预警状态失败:', error); + res.status(500).json({ code: 500, message: '更新预警状态失败', error: error.message }); + } +}; + +// 获取预警统计 +exports.getWarningStats = async (req, res) => { + try { + // 分别查询每种设备类型的活跃预警数量 + const earTagCount = await DeviceWarning.count({ + where: { + deviceType: '智能耳标', + status: 'active' + } + }); + + const neckbandCount = await DeviceWarning.count({ + where: { + deviceType: '智能项圈', + status: 'active' + } + }); + + const hostCount = await DeviceWarning.count({ + where: { + deviceType: '智能主机', + status: 'active' + } + }); + + const result = { + earTag: earTagCount, + neckband: neckbandCount, + host: hostCount + }; + + res.status(200).json({ code: 200, message: '获取成功', data: result }); + } catch (error) { + console.error('获取预警统计失败:', error); + res.status(500).json({ code: 500, message: '获取预警统计失败', error: error.message }); + } +}; diff --git a/government-backend/controllers/epidemicActivityController.js b/government-backend/controllers/epidemicActivityController.js new file mode 100644 index 0000000..be0641e --- /dev/null +++ b/government-backend/controllers/epidemicActivityController.js @@ -0,0 +1,242 @@ +const EpidemicActivity = require('../models/EpidemicActivity'); +const { Op } = require('sequelize'); + +// 获取防疫活动列表 +const getEpidemicActivities = async (req, res) => { + try { + const { + page = 1, + pageSize = 20, + activityName, + livestockCategory, + diseaseCategory, + activityStatus + } = req.query; + + const offset = (page - 1) * pageSize; + const where = {}; + + // 构建查询条件 + if (activityName) { + where.activityName = { + [Op.like]: `%${activityName}%` + }; + } + if (livestockCategory) { + where.livestockCategory = livestockCategory; + } + if (diseaseCategory) { + where.diseaseCategory = diseaseCategory; + } + if (activityStatus) { + where.activityStatus = activityStatus; + } + + const { count, rows } = await EpidemicActivity.findAndCountAll({ + where, + limit: parseInt(pageSize), + offset: parseInt(offset), + order: [['updatedAt', 'DESC']] + }); + + res.json({ + code: 200, + message: '获取成功', + data: { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) + } + }); + } catch (error) { + console.error('获取防疫活动列表失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 根据ID获取防疫活动 +const getEpidemicActivityById = async (req, res) => { + try { + const { id } = req.params; + const activity = await EpidemicActivity.findByPk(id); + + if (!activity) { + return res.status(404).json({ + code: 404, + message: '防疫活动不存在' + }); + } + + res.json({ + code: 200, + message: '获取成功', + data: activity + }); + } catch (error) { + console.error('获取防疫活动详情失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 创建防疫活动 +const createEpidemicActivity = async (req, res) => { + try { + const { + activityName, + livestockCategory, + diseaseCategory, + vaccineUsed, + vaccineBatch, + preventionDate, + activityStatus = 'active' + } = req.body; + + const activity = await EpidemicActivity.create({ + activityName, + livestockCategory, + diseaseCategory, + vaccineUsed, + vaccineBatch, + preventionDate, + activityStatus + }); + + res.status(201).json({ + code: 201, + message: '创建成功', + data: activity + }); + } catch (error) { + console.error('创建防疫活动失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 更新防疫活动 +const updateEpidemicActivity = async (req, res) => { + try { + const { id } = req.params; + const { + activityName, + livestockCategory, + diseaseCategory, + vaccineUsed, + vaccineBatch, + preventionDate, + activityStatus + } = req.body; + + const activity = await EpidemicActivity.findByPk(id); + if (!activity) { + return res.status(404).json({ + code: 404, + message: '防疫活动不存在' + }); + } + + await activity.update({ + activityName, + livestockCategory, + diseaseCategory, + vaccineUsed, + vaccineBatch, + preventionDate, + activityStatus + }); + + res.json({ + code: 200, + message: '更新成功', + data: activity + }); + } catch (error) { + console.error('更新防疫活动失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 删除防疫活动 +const deleteEpidemicActivity = async (req, res) => { + try { + const { id } = req.params; + const activity = await EpidemicActivity.findByPk(id); + + if (!activity) { + return res.status(404).json({ + code: 404, + message: '防疫活动不存在' + }); + } + + await activity.destroy(); + + res.json({ + code: 200, + message: '删除成功' + }); + } catch (error) { + console.error('删除防疫活动失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 切换活动状态 +const toggleActivityStatus = async (req, res) => { + try { + const { id } = req.params; + const activity = await EpidemicActivity.findByPk(id); + + if (!activity) { + return res.status(404).json({ + code: 404, + message: '防疫活动不存在' + }); + } + + const newStatus = activity.activityStatus === 'active' ? 'inactive' : 'active'; + await activity.update({ activityStatus: newStatus }); + + res.json({ + code: 200, + message: '状态更新成功', + data: activity + }); + } catch (error) { + console.error('切换活动状态失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +module.exports = { + getEpidemicActivities, + getEpidemicActivityById, + createEpidemicActivity, + updateEpidemicActivity, + deleteEpidemicActivity, + toggleActivityStatus +}; diff --git a/government-backend/controllers/productionMaterialCertificationController.js b/government-backend/controllers/productionMaterialCertificationController.js new file mode 100644 index 0000000..c0e9bb0 --- /dev/null +++ b/government-backend/controllers/productionMaterialCertificationController.js @@ -0,0 +1,280 @@ +const ProductionMaterialCertification = require('../models/ProductionMaterialCertification'); +const { Op } = require('sequelize'); + +// 获取生资认证列表 +const getProductionMaterialCertifications = async (req, res) => { + try { + const { + page = 1, + pageSize = 20, + materialName, + materialType, + manufacturer, + certificationType, + certificationStatus + } = req.query; + + const offset = (page - 1) * pageSize; + const where = {}; + + // 构建查询条件 + if (materialName) { + where.materialName = { + [Op.like]: `%${materialName}%` + }; + } + if (materialType) { + where.materialType = materialType; + } + if (manufacturer) { + where.manufacturer = { + [Op.like]: `%${manufacturer}%` + }; + } + if (certificationType) { + where.certificationType = certificationType; + } + if (certificationStatus) { + where.certificationStatus = certificationStatus; + } + + const { count, rows } = await ProductionMaterialCertification.findAndCountAll({ + where, + limit: parseInt(pageSize), + offset: parseInt(offset), + order: [['updatedAt', 'DESC']] + }); + + res.json({ + code: 200, + message: '获取成功', + data: { + list: rows, + total: count, + page: parseInt(page), + pageSize: parseInt(pageSize) + } + }); + } catch (error) { + console.error('获取生资认证列表失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 根据ID获取生资认证详情 +const getProductionMaterialCertificationById = async (req, res) => { + try { + const { id } = req.params; + const certification = await ProductionMaterialCertification.findByPk(id); + + if (!certification) { + return res.status(404).json({ + code: 404, + message: '生资认证不存在' + }); + } + + res.json({ + code: 200, + message: '获取成功', + data: certification + }); + } catch (error) { + console.error('获取生资认证详情失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 创建生资认证 +const createProductionMaterialCertification = async (req, res) => { + try { + const { + materialName, + materialType, + manufacturer, + certificationNumber, + certificationType, + certificationAuthority, + issueDate, + expiryDate, + certificationStatus = 'valid', + description, + specifications, + applicableScope, + contactPerson, + contactPhone, + remarks + } = req.body; + + const certification = await ProductionMaterialCertification.create({ + materialName, + materialType, + manufacturer, + certificationNumber, + certificationType, + certificationAuthority, + issueDate, + expiryDate, + certificationStatus, + description, + specifications, + applicableScope, + contactPerson, + contactPhone, + remarks + }); + + res.status(201).json({ + code: 201, + message: '创建成功', + data: certification + }); + } catch (error) { + console.error('创建生资认证失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 更新生资认证 +const updateProductionMaterialCertification = async (req, res) => { + try { + const { id } = req.params; + const { + materialName, + materialType, + manufacturer, + certificationNumber, + certificationType, + certificationAuthority, + issueDate, + expiryDate, + certificationStatus, + description, + specifications, + applicableScope, + contactPerson, + contactPhone, + remarks + } = req.body; + + const certification = await ProductionMaterialCertification.findByPk(id); + if (!certification) { + return res.status(404).json({ + code: 404, + message: '生资认证不存在' + }); + } + + await certification.update({ + materialName, + materialType, + manufacturer, + certificationNumber, + certificationType, + certificationAuthority, + issueDate, + expiryDate, + certificationStatus, + description, + specifications, + applicableScope, + contactPerson, + contactPhone, + remarks + }); + + res.json({ + code: 200, + message: '更新成功', + data: certification + }); + } catch (error) { + console.error('更新生资认证失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 删除生资认证 +const deleteProductionMaterialCertification = async (req, res) => { + try { + const { id } = req.params; + const certification = await ProductionMaterialCertification.findByPk(id); + + if (!certification) { + return res.status(404).json({ + code: 404, + message: '生资认证不存在' + }); + } + + await certification.destroy(); + + res.json({ + code: 200, + message: '删除成功' + }); + } catch (error) { + console.error('删除生资认证失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +// 切换认证状态 +const toggleCertificationStatus = async (req, res) => { + try { + const { id } = req.params; + const { status } = req.body; + + const certification = await ProductionMaterialCertification.findByPk(id); + if (!certification) { + return res.status(404).json({ + code: 404, + message: '生资认证不存在' + }); + } + + await certification.update({ certificationStatus: status }); + + res.json({ + code: 200, + message: '状态更新成功', + data: certification + }); + } catch (error) { + console.error('切换认证状态失败:', error); + res.status(500).json({ + code: 500, + message: '服务器内部错误', + error: error.message + }); + } +}; + +module.exports = { + getProductionMaterialCertifications, + getProductionMaterialCertificationById, + createProductionMaterialCertification, + updateProductionMaterialCertification, + deleteProductionMaterialCertification, + toggleCertificationStatus +}; diff --git a/government-backend/models/ApprovalProcess.js b/government-backend/models/ApprovalProcess.js new file mode 100644 index 0000000..8c84aa0 --- /dev/null +++ b/government-backend/models/ApprovalProcess.js @@ -0,0 +1,93 @@ +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/database'); + +const ApprovalProcess = sequelize.define('ApprovalProcess', { + id: { + type: DataTypes.INTEGER, + primaryKey: true, + autoIncrement: true + }, + title: { + type: DataTypes.STRING(255), + allowNull: false, + comment: '审批标题' + }, + type: { + type: DataTypes.ENUM('enterprise', 'license', 'project', 'other'), + allowNull: false, + comment: '审批类型' + }, + applicant: { + type: DataTypes.STRING(100), + allowNull: false, + comment: '申请人' + }, + phone: { + type: DataTypes.STRING(20), + allowNull: true, + comment: '联系电话' + }, + farmName: { + type: DataTypes.STRING(255), + allowNull: true, + comment: '养殖场名称' + }, + quantity: { + type: DataTypes.INTEGER, + allowNull: true, + comment: '认证数量' + }, + description: { + type: DataTypes.TEXT, + allowNull: true, + comment: '审批说明' + }, + status: { + type: DataTypes.ENUM('pending', 'approved', 'rejected', 'processing'), + defaultValue: 'pending', + comment: '审批状态' + }, + approvalComment: { + type: DataTypes.TEXT, + allowNull: true, + comment: '审批意见' + }, + approver: { + type: DataTypes.STRING(100), + allowNull: true, + comment: '审批人' + }, + approvalTime: { + type: DataTypes.DATE, + allowNull: true, + comment: '审批时间' + }, + files: { + type: DataTypes.JSON, + allowNull: true, + comment: '附件文件列表' + }, + remarks: { + type: DataTypes.TEXT, + allowNull: true, + comment: '备注' + }, + createdAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + comment: '创建时间' + }, + updatedAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + comment: '更新时间' + } +}, { + tableName: 'approval_processes', + timestamps: true, + createdAt: 'createdAt', + updatedAt: 'updatedAt', + paranoid: false +}); + +module.exports = ApprovalProcess; diff --git a/government-backend/models/CattleAcademy.js b/government-backend/models/CattleAcademy.js new file mode 100644 index 0000000..4cf05c6 --- /dev/null +++ b/government-backend/models/CattleAcademy.js @@ -0,0 +1,98 @@ +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/database'); + +const CattleAcademy = sequelize.define('CattleAcademy', { + id: { + type: DataTypes.INTEGER, + primaryKey: true, + autoIncrement: true + }, + title: { + type: DataTypes.STRING(255), + allowNull: false, + comment: '标题' + }, + coverImage: { + type: DataTypes.STRING(500), + allowNull: true, + comment: '封面图URL' + }, + content: { + type: DataTypes.TEXT, + allowNull: true, + comment: '内容' + }, + summary: { + type: DataTypes.TEXT, + allowNull: true, + comment: '摘要' + }, + category: { + type: DataTypes.STRING(100), + allowNull: true, + comment: '分类' + }, + tags: { + type: DataTypes.JSON, + allowNull: true, + comment: '标签' + }, + sort: { + type: DataTypes.INTEGER, + defaultValue: 0, + comment: '排序' + }, + status: { + type: DataTypes.BOOLEAN, + defaultValue: true, + comment: '状态' + }, + viewCount: { + type: DataTypes.INTEGER, + defaultValue: 0, + comment: '浏览次数' + }, + author: { + type: DataTypes.STRING(100), + allowNull: true, + comment: '作者' + }, + publishTime: { + type: DataTypes.DATE, + allowNull: true, + comment: '发布时间' + }, + isTop: { + type: DataTypes.BOOLEAN, + defaultValue: false, + comment: '是否置顶' + }, + isRecommend: { + type: DataTypes.BOOLEAN, + defaultValue: false, + comment: '是否推荐' + }, + remarks: { + type: DataTypes.TEXT, + allowNull: true, + comment: '备注' + }, + createdAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + comment: '创建时间' + }, + updatedAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + comment: '更新时间' + } +}, { + tableName: 'cattle_academy', + timestamps: true, + createdAt: 'createdAt', + updatedAt: 'updatedAt', + paranoid: false +}); + +module.exports = CattleAcademy; diff --git a/government-backend/models/DeviceWarning.js b/government-backend/models/DeviceWarning.js new file mode 100644 index 0000000..57802d7 --- /dev/null +++ b/government-backend/models/DeviceWarning.js @@ -0,0 +1,107 @@ +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/database'); + +const DeviceWarning = sequelize.define('DeviceWarning', { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + farmName: { + type: DataTypes.STRING, + allowNull: false, + comment: '养殖场名称', + field: 'farmName' + }, + farmerName: { + type: DataTypes.STRING, + allowNull: false, + comment: '养殖户名称', + field: 'farmerName' + }, + phone: { + type: DataTypes.STRING, + allowNull: false, + comment: '联系电话', + field: 'phone' + }, + deviceType: { + type: DataTypes.ENUM('智能耳标', '智能项圈', '智能主机'), + allowNull: false, + comment: '设备类型', + field: 'deviceType' + }, + deviceNumber: { + type: DataTypes.STRING, + allowNull: false, + comment: '设备编号', + field: 'deviceNumber' + }, + alertType: { + type: DataTypes.ENUM('设备离线', '电量不足', '信号异常', '温度异常', '其他'), + allowNull: false, + comment: '预警类型', + field: 'alertType' + }, + alertLevel: { + type: DataTypes.ENUM('high', 'medium', 'low'), + allowNull: false, + defaultValue: 'medium', + comment: '预警级别 (高, 中, 低)', + field: 'alertLevel' + }, + alertTime: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.NOW, + comment: '预警时间', + field: 'alertTime' + }, + status: { + type: DataTypes.ENUM('active', 'resolved', 'ignored'), + allowNull: false, + defaultValue: 'active', + comment: '预警状态 (活跃, 已解决, 已忽略)', + field: 'status' + }, + description: { + type: DataTypes.TEXT, + comment: '预警描述', + }, + location: { + type: DataTypes.STRING, + comment: '设备位置', + }, + batteryLevel: { + type: DataTypes.INTEGER, + comment: '电池电量百分比', + }, + signalStrength: { + type: DataTypes.INTEGER, + comment: '信号强度', + }, + temperature: { + type: DataTypes.FLOAT, + comment: '温度值', + }, + resolvedBy: { + type: DataTypes.STRING, + comment: '解决人', + }, + resolvedAt: { + type: DataTypes.DATE, + comment: '解决时间', + }, + remarks: { + type: DataTypes.TEXT, + comment: '备注', + }, +}, { + tableName: 'device_warnings', + timestamps: true, + createdAt: 'createdAt', + updatedAt: 'updatedAt', + paranoid: false, +}); + +module.exports = DeviceWarning; diff --git a/government-backend/models/EpidemicActivity.js b/government-backend/models/EpidemicActivity.js new file mode 100644 index 0000000..00a9fb0 --- /dev/null +++ b/government-backend/models/EpidemicActivity.js @@ -0,0 +1,63 @@ +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/database'); + +const EpidemicActivity = sequelize.define('EpidemicActivity', { + id: { + type: DataTypes.INTEGER, + primaryKey: true, + autoIncrement: true + }, + activityName: { + type: DataTypes.STRING(255), + allowNull: false, + comment: '活动名称' + }, + livestockCategory: { + type: DataTypes.STRING(100), + allowNull: true, + comment: '防疫畜别' + }, + diseaseCategory: { + type: DataTypes.STRING(100), + allowNull: true, + comment: '疫病类别' + }, + vaccineUsed: { + type: DataTypes.STRING(255), + allowNull: true, + comment: '使用疫苗' + }, + vaccineBatch: { + type: DataTypes.STRING(100), + allowNull: true, + comment: '疫苗批次' + }, + preventionDate: { + type: DataTypes.STRING(100), + allowNull: true, + comment: '防疫日期' + }, + activityStatus: { + type: DataTypes.ENUM('active', 'inactive'), + defaultValue: 'active', + comment: '活动状态' + }, + updatedAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + comment: '更新时间' + }, + createdAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + comment: '创建时间' + } +}, { + tableName: 'epidemic_activities', + timestamps: true, + createdAt: 'createdAt', + updatedAt: 'updatedAt', + paranoid: false +}); + +module.exports = EpidemicActivity; diff --git a/government-backend/models/ProductionMaterialCertification.js b/government-backend/models/ProductionMaterialCertification.js new file mode 100644 index 0000000..474d872 --- /dev/null +++ b/government-backend/models/ProductionMaterialCertification.js @@ -0,0 +1,103 @@ +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/database'); + +const ProductionMaterialCertification = sequelize.define('ProductionMaterialCertification', { + id: { + type: DataTypes.INTEGER, + primaryKey: true, + autoIncrement: true + }, + materialName: { + type: DataTypes.STRING(255), + allowNull: false, + comment: '生产资料名称' + }, + materialType: { + type: DataTypes.STRING(100), + allowNull: false, + comment: '生产资料类型' + }, + manufacturer: { + type: DataTypes.STRING(255), + allowNull: false, + comment: '生产厂商' + }, + certificationNumber: { + type: DataTypes.STRING(100), + allowNull: false, + comment: '认证编号' + }, + certificationType: { + type: DataTypes.STRING(100), + allowNull: false, + comment: '认证类型' + }, + certificationAuthority: { + type: DataTypes.STRING(255), + allowNull: false, + comment: '认证机构' + }, + issueDate: { + type: DataTypes.DATE, + allowNull: false, + comment: '发证日期' + }, + expiryDate: { + type: DataTypes.DATE, + allowNull: false, + comment: '有效期至' + }, + certificationStatus: { + type: DataTypes.ENUM('valid', 'expired', 'suspended', 'revoked'), + defaultValue: 'valid', + comment: '认证状态' + }, + description: { + type: DataTypes.TEXT, + allowNull: true, + comment: '产品描述' + }, + specifications: { + type: DataTypes.TEXT, + allowNull: true, + comment: '技术规格' + }, + applicableScope: { + type: DataTypes.TEXT, + allowNull: true, + comment: '适用范围' + }, + contactPerson: { + type: DataTypes.STRING(100), + allowNull: true, + comment: '联系人' + }, + contactPhone: { + type: DataTypes.STRING(20), + allowNull: true, + comment: '联系电话' + }, + remarks: { + type: DataTypes.TEXT, + allowNull: true, + comment: '备注' + }, + createdAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + comment: '创建时间' + }, + updatedAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + comment: '更新时间' + } +}, { + tableName: 'production_material_certifications', + timestamps: true, + createdAt: 'createdAt', + updatedAt: 'updatedAt', + paranoid: false +}); + +module.exports = ProductionMaterialCertification; diff --git a/government-backend/routes/approvalProcess.js b/government-backend/routes/approvalProcess.js new file mode 100644 index 0000000..2ac5646 --- /dev/null +++ b/government-backend/routes/approvalProcess.js @@ -0,0 +1,18 @@ +const express = require('express'); +const router = express.Router(); +const approvalProcessController = require('../controllers/approvalProcessController'); +const authMiddleware = require('../middleware/auth'); + +// 暂时注释掉认证中间件用于测试 +// router.use(authMiddleware); + +// 审批流程管理路由 +router.get('/', approvalProcessController.getApprovalProcesses); +router.get('/:id', approvalProcessController.getApprovalProcessById); +router.post('/', approvalProcessController.createApprovalProcess); +router.put('/:id', approvalProcessController.updateApprovalProcess); +router.delete('/:id', approvalProcessController.deleteApprovalProcess); +router.post('/:id/process', approvalProcessController.processApproval); +router.patch('/:id/status', approvalProcessController.updateApprovalStatus); + +module.exports = router; diff --git a/government-backend/routes/cattleAcademy.js b/government-backend/routes/cattleAcademy.js new file mode 100644 index 0000000..8605510 --- /dev/null +++ b/government-backend/routes/cattleAcademy.js @@ -0,0 +1,18 @@ +const express = require('express'); +const router = express.Router(); +const cattleAcademyController = require('../controllers/cattleAcademyController'); +const authMiddleware = require('../middleware/auth'); + +// 暂时注释掉认证中间件用于测试 +// router.use(authMiddleware); + +// 养牛学院资讯管理路由 +router.get('/', cattleAcademyController.getCattleAcademyList); +router.get('/:id', cattleAcademyController.getCattleAcademyById); +router.post('/', cattleAcademyController.createCattleAcademy); +router.put('/:id', cattleAcademyController.updateCattleAcademy); +router.delete('/:id', cattleAcademyController.deleteCattleAcademy); +router.patch('/:id/status', cattleAcademyController.toggleCattleAcademyStatus); +router.patch('/sort', cattleAcademyController.updateSort); + +module.exports = router; diff --git a/government-backend/routes/deviceWarning.js b/government-backend/routes/deviceWarning.js new file mode 100644 index 0000000..c541205 --- /dev/null +++ b/government-backend/routes/deviceWarning.js @@ -0,0 +1,17 @@ +const express = require('express'); +const router = express.Router(); +const deviceWarningController = require('../controllers/deviceWarningController'); +// const authMiddleware = require('../middleware/auth'); // 假设有认证中间件 + +// router.use(authMiddleware); // 暂时注释掉认证中间件用于测试 + +// 设备预警管理路由 +router.get('/', deviceWarningController.getDeviceWarnings); +router.get('/stats', deviceWarningController.getWarningStats); +router.get('/:id', deviceWarningController.getDeviceWarningById); +router.post('/', deviceWarningController.createDeviceWarning); +router.put('/:id', deviceWarningController.updateDeviceWarning); +router.delete('/:id', deviceWarningController.deleteDeviceWarning); +router.patch('/:id/status', deviceWarningController.updateWarningStatus); + +module.exports = router; diff --git a/government-backend/routes/epidemicActivity.js b/government-backend/routes/epidemicActivity.js new file mode 100644 index 0000000..a1401b1 --- /dev/null +++ b/government-backend/routes/epidemicActivity.js @@ -0,0 +1,17 @@ +const express = require('express'); +const router = express.Router(); +const epidemicActivityController = require('../controllers/epidemicActivityController'); +const authMiddleware = require('../middleware/auth'); + +// 暂时注释掉认证中间件用于测试 +// router.use(authMiddleware); + +// 防疫活动管理路由 +router.get('/', epidemicActivityController.getEpidemicActivities); +router.get('/:id', epidemicActivityController.getEpidemicActivityById); +router.post('/', epidemicActivityController.createEpidemicActivity); +router.put('/:id', epidemicActivityController.updateEpidemicActivity); +router.delete('/:id', epidemicActivityController.deleteEpidemicActivity); +router.patch('/:id/status', epidemicActivityController.toggleActivityStatus); + +module.exports = router; diff --git a/government-backend/routes/productionMaterialCertification.js b/government-backend/routes/productionMaterialCertification.js new file mode 100644 index 0000000..9d8a275 --- /dev/null +++ b/government-backend/routes/productionMaterialCertification.js @@ -0,0 +1,17 @@ +const express = require('express'); +const router = express.Router(); +const productionMaterialCertificationController = require('../controllers/productionMaterialCertificationController'); +const authMiddleware = require('../middleware/auth'); + +// 暂时注释掉认证中间件用于测试 +// router.use(authMiddleware); + +// 生资认证管理路由 +router.get('/', productionMaterialCertificationController.getProductionMaterialCertifications); +router.get('/:id', productionMaterialCertificationController.getProductionMaterialCertificationById); +router.post('/', productionMaterialCertificationController.createProductionMaterialCertification); +router.put('/:id', productionMaterialCertificationController.updateProductionMaterialCertification); +router.delete('/:id', productionMaterialCertificationController.deleteProductionMaterialCertification); +router.patch('/:id/status', productionMaterialCertificationController.toggleCertificationStatus); + +module.exports = router; diff --git a/government-backend/sql/create_device_warnings_table.sql b/government-backend/sql/create_device_warnings_table.sql new file mode 100644 index 0000000..3d97756 --- /dev/null +++ b/government-backend/sql/create_device_warnings_table.sql @@ -0,0 +1,22 @@ +CREATE TABLE IF NOT EXISTS `device_warnings` ( + `id` INT AUTO_INCREMENT PRIMARY KEY, + `farmName` VARCHAR(255) NOT NULL COMMENT '养殖场名称', + `farmerName` VARCHAR(255) NOT NULL COMMENT '养殖户名称', + `phone` VARCHAR(255) NOT NULL COMMENT '联系电话', + `deviceType` ENUM('智能耳标', '智能项圈', '智能主机') NOT NULL COMMENT '设备类型', + `deviceNumber` VARCHAR(255) NOT NULL COMMENT '设备编号', + `alertType` ENUM('设备离线', '电量不足', '信号异常', '温度异常', '其他') NOT NULL COMMENT '预警类型', + `alertLevel` ENUM('high', 'medium', 'low') DEFAULT 'medium' NOT NULL COMMENT '预警级别 (高, 中, 低)', + `alertTime` DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '预警时间', + `status` ENUM('active', 'resolved', 'ignored') DEFAULT 'active' NOT NULL COMMENT '预警状态 (活跃, 已解决, 已忽略)', + `description` TEXT COMMENT '预警描述', + `location` VARCHAR(255) COMMENT '设备位置', + `batteryLevel` INT COMMENT '电池电量百分比', + `signalStrength` INT COMMENT '信号强度', + `temperature` FLOAT COMMENT '温度值', + `resolvedBy` VARCHAR(255) COMMENT '解决人', + `resolvedAt` DATETIME COMMENT '解决时间', + `remarks` TEXT COMMENT '备注', + `createdAt` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updatedAt` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) COMMENT='设备预警管理表'; diff --git a/government-backend/sql/create_epidemic_activities_table.sql b/government-backend/sql/create_epidemic_activities_table.sql new file mode 100644 index 0000000..c98cce9 --- /dev/null +++ b/government-backend/sql/create_epidemic_activities_table.sql @@ -0,0 +1,26 @@ +-- 创建防疫活动管理表 +CREATE TABLE IF NOT EXISTS `epidemic_activities` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `activity_name` varchar(255) NOT NULL COMMENT '活动名称', + `livestock_category` varchar(100) DEFAULT NULL COMMENT '防疫畜别', + `disease_category` varchar(100) DEFAULT NULL COMMENT '疫病类别', + `vaccine_used` varchar(255) DEFAULT NULL COMMENT '使用疫苗', + `vaccine_batch` varchar(100) DEFAULT NULL COMMENT '疫苗批次', + `prevention_date` varchar(100) DEFAULT NULL COMMENT '防疫日期', + `activity_status` enum('active','inactive') DEFAULT 'active' COMMENT '活动状态', + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_activity_name` (`activity_name`), + KEY `idx_livestock_category` (`livestock_category`), + KEY `idx_disease_category` (`disease_category`), + KEY `idx_activity_status` (`activity_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='防疫活动管理表'; + +-- 插入测试数据 +INSERT INTO `epidemic_activities` (`activity_name`, `livestock_category`, `disease_category`, `vaccine_used`, `vaccine_batch`, `prevention_date`, `activity_status`) VALUES +('春防', '牛', '口蹄疫', '口蹄疫O型灭活疫苗', '20230401', '2023-04-01至2023-08-01', 'active'), +('秋防', '羊', '布鲁氏菌病', '布鲁氏菌病活疫苗', '20230901', '2023-09-01至2023-12-31', 'active'), +('猪瘟防疫', '猪', '猪瘟', '猪瘟活疫苗', '20230501', '2023-05-01至2023-05-31', 'inactive'), +('禽流感防疫', '鸡', '禽流感', '禽流感H5N1灭活疫苗', '20230601', '2023-06-01至2023-06-30', 'active'), +('狂犬病防疫', '犬', '狂犬病', '狂犬病灭活疫苗', '20230701', '2023-07-01至2023-07-31', 'active'); diff --git a/government-backend/sql/insert_cattle_academy_data.sql b/government-backend/sql/insert_cattle_academy_data.sql new file mode 100644 index 0000000..cb3be3d --- /dev/null +++ b/government-backend/sql/insert_cattle_academy_data.sql @@ -0,0 +1,12 @@ +-- 插入养牛学院测试数据 +INSERT INTO cattle_academy (title, cover_image, content, summary, category, tags, sort, status, view_count, author, publish_time, is_top, is_recommend, remarks) VALUES +('新疆阿克苏地区电信5G数字乡村项目', 'https://via.placeholder.com/100x50', '新疆阿克苏地区电信5G数字乡村项目详细内容...', '新疆阿克苏地区电信5G数字乡村项目介绍', '技术资讯', '["5G", "数字乡村", "电信"]', 100, 1, 156, '张专家', '2022-09-28 11:47:27', 1, 1, '重点项目'), +('共享养牛,开启畜牧业财富之路', 'https://via.placeholder.com/100x50', '共享养牛模式详细介绍...', '共享养牛模式介绍', '养殖技术', '["共享养牛", "畜牧业", "财富"]', 98, 1, 234, '李专家', '2023-08-28 15:38:35', 0, 1, '热门推荐'), +('现代化养牛场建设与管理', 'https://via.placeholder.com/100x50', '现代化养牛场建设与管理详细内容...', '现代化养牛场建设指南', '养殖技术', '["现代化", "养牛场", "管理"]', 95, 1, 189, '王专家', '2023-07-15 09:20:15', 0, 0, '技术指导'), +('牛群健康管理与疾病防控', 'https://via.placeholder.com/100x50', '牛群健康管理与疾病防控详细内容...', '牛群健康管理指南', '健康管理', '["健康管理", "疾病防控", "牛群"]', 90, 1, 312, '赵专家', '2023-06-20 14:30:45', 0, 1, '重要技术'), +('饲料营养配比与成本控制', 'https://via.placeholder.com/100x50', '饲料营养配比与成本控制详细内容...', '饲料营养配比指南', '营养管理', '["饲料", "营养", "成本控制"]', 85, 1, 267, '孙专家', '2023-05-10 16:45:30', 0, 0, '成本优化'), +('智能养殖设备应用案例', 'https://via.placeholder.com/100x50', '智能养殖设备应用案例详细内容...', '智能养殖设备应用', '智能设备', '["智能设备", "养殖", "应用案例"]', 80, 1, 198, '周专家', '2023-04-25 11:15:20', 0, 0, '设备应用'), +('养牛场环保与可持续发展', 'https://via.placeholder.com/100x50', '养牛场环保与可持续发展详细内容...', '环保可持续发展指南', '环保管理', '["环保", "可持续发展", "养牛场"]', 75, 1, 145, '吴专家', '2023-03-18 13:25:10', 0, 0, '环保理念'), +('牛群繁殖技术与选育', 'https://via.placeholder.com/100x50', '牛群繁殖技术与选育详细内容...', '繁殖技术选育指南', '繁殖技术', '["繁殖技术", "选育", "牛群"]', 70, 1, 223, '郑专家', '2023-02-28 10:40:55', 0, 0, '繁殖技术'), +('养牛场财务管理与投资分析', 'https://via.placeholder.com/100x50', '养牛场财务管理与投资分析详细内容...', '财务管理投资分析', '经营管理', '["财务管理", "投资分析", "养牛场"]', 65, 1, 178, '钱专家', '2023-01-15 15:50:25', 0, 0, '经营管理'), +('养牛行业市场趋势分析', 'https://via.placeholder.com/100x50', '养牛行业市场趋势分析详细内容...', '市场趋势分析报告', '市场分析', '["市场趋势", "行业分析", "养牛"]', 60, 1, 201, '刘专家', '2022-12-30 12:35:40', 0, 0, '市场分析'); diff --git a/government-backend/sql/insert_device_warning_data.sql b/government-backend/sql/insert_device_warning_data.sql new file mode 100644 index 0000000..f3303ce --- /dev/null +++ b/government-backend/sql/insert_device_warning_data.sql @@ -0,0 +1,16 @@ +INSERT INTO `device_warnings` (`farmName`, `farmerName`, `phone`, `deviceType`, `deviceNumber`, `alertType`, `alertLevel`, `alertTime`, `status`, `description`, `location`, `batteryLevel`, `signalStrength`, `temperature`, `remarks`) VALUES +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能项圈', '24077000001', '设备离线', 'high', '2024-01-15 10:30:00', 'active', '设备长时间无信号', 'A区1号牛舍', 15, 0, 25.5, '需要检查设备连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能项圈', '24065000947', '设备离线', 'high', '2024-01-15 09:45:00', 'active', '设备长时间无信号', 'A区2号牛舍', 8, 0, 26.2, '需要检查设备连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能耳标', '2407100002', '设备离线', 'high', '2024-01-15 11:20:00', 'active', '设备长时间无信号', 'B区1号牛舍', 22, 0, 24.8, '需要检查设备连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能耳标', '2407100001', '设备离线', 'high', '2024-01-15 10:15:00', 'active', '设备长时间无信号', 'B区2号牛舍', 18, 0, 25.1, '需要检查设备连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能耳标', '2407402678', '设备离线', 'high', '2024-01-15 09:30:00', 'active', '设备长时间无信号', 'C区1号牛舍', 12, 0, 26.5, '需要检查设备连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能耳标', '2407402675', '设备离线', 'high', '2024-01-15 08:45:00', 'active', '设备长时间无信号', 'C区2号牛舍', 25, 0, 24.2, '需要检查设备连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能耳标', '2407402674', '设备离线', 'high', '2024-01-15 08:20:00', 'active', '设备长时间无信号', 'C区3号牛舍', 30, 0, 25.8, '需要检查设备连接'), +('139****8321_养殖场', '杜云鹏', '139****8321', '智能耳标', '2404412397', '设备离线', 'high', '2024-01-15 07:30:00', 'active', '设备长时间无信号', 'D区1号牛舍', 5, 0, 27.1, '需要检查设备连接'), +('139****8321_养殖场', '杜云鹏', '139****8321', '智能耳标', '2404412404', '设备离线', 'high', '2024-01-15 07:15:00', 'active', '设备长时间无信号', 'D区2号牛舍', 8, 0, 26.8, '需要检查设备连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能主机', 'HOST001', '设备离线', 'high', '2024-01-15 12:00:00', 'active', '主机设备离线', '机房A', 0, 0, 28.5, '需要检查主机连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能主机', 'HOST002', '设备离线', 'high', '2024-01-15 11:45:00', 'active', '主机设备离线', '机房B', 0, 0, 29.2, '需要检查主机连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能主机', 'HOST003', '设备离线', 'high', '2024-01-15 11:30:00', 'active', '主机设备离线', '机房C', 0, 0, 27.8, '需要检查主机连接'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能耳标', '2407100003', '电量不足', 'medium', '2024-01-15 13:20:00', 'active', '设备电量低于20%', 'A区3号牛舍', 18, 65, 25.3, '需要更换电池'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能项圈', '24077000002', '信号异常', 'medium', '2024-01-15 13:45:00', 'active', '信号强度不稳定', 'B区3号牛舍', 45, 25, 26.1, '需要检查信号接收'), +('扎旗大数据中心', '扎旗大数据中心', '132****9345', '智能耳标', '2407100004', '温度异常', 'high', '2024-01-15 14:10:00', 'active', '温度超过正常范围', 'C区4号牛舍', 35, 80, 32.5, '需要检查牛只健康状况'); diff --git a/government-backend/test-cattle-academy-api.js b/government-backend/test-cattle-academy-api.js new file mode 100644 index 0000000..e64437e --- /dev/null +++ b/government-backend/test-cattle-academy-api.js @@ -0,0 +1,132 @@ +const axios = require('axios'); + +// 创建axios实例 +const api = axios.create({ + baseURL: 'http://localhost:5352/api/cattle-academy', + timeout: 10000, + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer test-token' + } +}); + +// 测试获取养牛学院资讯列表 +async function testGetCattleAcademyList() { + try { + console.log('测试获取养牛学院资讯列表...'); + const response = await api.get('/'); + console.log('获取列表成功:', response.data); + } catch (error) { + console.error('获取列表失败:', error.response?.data || error.message); + } +} + +// 测试获取单个养牛学院资讯详情 +async function testGetCattleAcademyById() { + try { + console.log('测试获取养牛学院资讯详情...'); + const response = await api.get('/1'); + console.log('获取详情成功:', response.data); + } catch (error) { + console.error('获取详情失败:', error.response?.data || error.message); + } +} + +// 测试创建养牛学院资讯 +async function testCreateCattleAcademy() { + try { + console.log('测试创建养牛学院资讯...'); + const data = { + title: '测试养牛学院资讯', + coverImage: 'https://via.placeholder.com/100x50', + content: '测试内容...', + summary: '测试摘要', + category: '技术资讯', + sort: 50, + status: true, + author: '测试作者', + publishTime: new Date().toISOString(), + isTop: false, + isRecommend: false, + remarks: '测试备注' + }; + const response = await api.post('/', data); + console.log('创建成功:', response.data); + } catch (error) { + console.error('创建失败:', error.response?.data || error.message); + } +} + +// 测试更新养牛学院资讯 +async function testUpdateCattleAcademy() { + try { + console.log('测试更新养牛学院资讯...'); + const data = { + title: '更新测试养牛学院资讯', + coverImage: 'https://via.placeholder.com/100x50', + content: '更新测试内容...', + summary: '更新测试摘要', + category: '养殖技术', + sort: 60, + status: true, + author: '更新测试作者', + publishTime: new Date().toISOString(), + isTop: true, + isRecommend: true, + remarks: '更新测试备注' + }; + const response = await api.put('/1', data); + console.log('更新成功:', response.data); + } catch (error) { + console.error('更新失败:', error.response?.data || error.message); + } +} + +// 测试切换资讯状态 +async function testToggleStatus() { + try { + console.log('测试切换资讯状态...'); + const response = await api.patch('/1/status', { status: false }); + console.log('状态切换成功:', response.data); + } catch (error) { + console.error('状态切换失败:', error.response?.data || error.message); + } +} + +// 测试删除养牛学院资讯 +async function testDeleteCattleAcademy() { + try { + console.log('测试删除养牛学院资讯...'); + const response = await api.delete('/1'); + console.log('删除成功:', response.data); + } catch (error) { + console.error('删除失败:', error.response?.data || error.message); + } +} + +// 运行所有测试 +async function runAllTests() { + console.log('开始测试养牛学院API...\n'); + + await testGetCattleAcademyList(); + console.log('\n'); + + await testGetCattleAcademyById(); + console.log('\n'); + + await testCreateCattleAcademy(); + console.log('\n'); + + await testUpdateCattleAcademy(); + console.log('\n'); + + await testToggleStatus(); + console.log('\n'); + + await testDeleteCattleAcademy(); + console.log('\n'); + + console.log('所有测试完成'); +} + +runAllTests(); diff --git a/government-backend/test-device-warning-api.js b/government-backend/test-device-warning-api.js new file mode 100644 index 0000000..1d8b00c --- /dev/null +++ b/government-backend/test-device-warning-api.js @@ -0,0 +1,99 @@ +const axios = require('axios'); + +const API_BASE_URL = 'http://localhost:5352/api/device-warning'; + +const api = axios.create({ + baseURL: API_BASE_URL, + timeout: 10000, + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer test-token' + } +}); + +async function testDeviceWarningAPI() { + console.log('开始测试设备预警API...\n'); + + try { + // 测试获取预警统计 + console.log('1. 测试获取预警统计...'); + const statsResponse = await api.get('/stats'); + console.log('预警统计:', statsResponse.data); + console.log('✅ 获取预警统计成功\n'); + + // 测试获取设备预警列表 + console.log('2. 测试获取设备预警列表...'); + const listResponse = await api.get('/', { + params: { + page: 1, + pageSize: 10, + deviceType: '智能项圈' + } + }); + console.log('设备预警列表:', listResponse.data); + console.log('✅ 获取设备预警列表成功\n'); + + // 测试根据ID获取详情 + if (listResponse.data.data && listResponse.data.data.list.length > 0) { + const firstWarning = listResponse.data.data.list[0]; + console.log('3. 测试获取设备预警详情...'); + const detailResponse = await api.get(`/${firstWarning.id}`); + console.log('设备预警详情:', detailResponse.data); + console.log('✅ 获取设备预警详情成功\n'); + + // 测试更新预警状态 + console.log('4. 测试更新预警状态...'); + const updateResponse = await api.patch(`/${firstWarning.id}/status`, { + status: 'resolved', + resolvedBy: '测试用户' + }); + console.log('更新预警状态:', updateResponse.data); + console.log('✅ 更新预警状态成功\n'); + } + + // 测试创建新的设备预警 + console.log('5. 测试创建设备预警...'); + const createData = { + farmName: '测试养殖场', + farmerName: '测试养殖户', + phone: '138****8888', + deviceType: '智能耳标', + deviceNumber: 'TEST001', + alertType: '设备离线', + alertLevel: 'high', + description: '测试预警', + location: '测试位置', + batteryLevel: 20, + signalStrength: 30, + temperature: 25.5 + }; + const createResponse = await api.post('/', createData); + console.log('创建设备预警:', createResponse.data); + console.log('✅ 创建设备预警成功\n'); + + // 测试更新设备预警 + if (createResponse.data.data) { + console.log('6. 测试更新设备预警...'); + const updateData = { + description: '更新后的测试预警', + batteryLevel: 15 + }; + const updateResponse = await api.put(`/${createResponse.data.data.id}`, updateData); + console.log('更新设备预警:', updateResponse.data); + console.log('✅ 更新设备预警成功\n'); + + // 测试删除设备预警 + console.log('7. 测试删除设备预警...'); + const deleteResponse = await api.delete(`/${createResponse.data.data.id}`); + console.log('删除设备预警:', deleteResponse.data); + console.log('✅ 删除设备预警成功\n'); + } + + console.log('🎉 所有设备预警API测试通过!'); + + } catch (error) { + console.error('❌ API测试失败:', error.response ? error.response.data : error.message); + } +} + +testDeviceWarningAPI(); diff --git a/government-backend/test-epidemic-activity-api.js b/government-backend/test-epidemic-activity-api.js new file mode 100644 index 0000000..dcc24ef --- /dev/null +++ b/government-backend/test-epidemic-activity-api.js @@ -0,0 +1,124 @@ +const axios = require('axios'); + +const BASE_URL = 'http://localhost:5352/api/epidemic-activity'; + +// 创建axios实例,添加认证头 +const api = axios.create({ + baseURL: BASE_URL, + headers: { + 'Authorization': 'Bearer test-token', // 测试用的token + 'Content-Type': 'application/json' + } +}); + +// 测试获取防疫活动列表 +async function testGetActivities() { + try { + console.log('测试获取防疫活动列表...'); + const response = await api.get('/'); + console.log('获取成功:', response.data); + } catch (error) { + console.error('获取失败:', error.response?.data || error.message); + } +} + +// 测试创建防疫活动 +async function testCreateActivity() { + try { + console.log('测试创建防疫活动...'); + const newActivity = { + activityName: '测试防疫活动', + livestockCategory: '牛', + diseaseCategory: '口蹄疫', + vaccineUsed: '测试疫苗', + vaccineBatch: 'TEST001', + preventionDate: '2023-12-01至2023-12-31', + activityStatus: 'active' + }; + + const response = await api.post('/', newActivity); + console.log('创建成功:', response.data); + return response.data.data.id; + } catch (error) { + console.error('创建失败:', error.response?.data || error.message); + } +} + +// 测试更新防疫活动 +async function testUpdateActivity(id) { + try { + console.log('测试更新防疫活动...'); + const updateData = { + activityName: '更新后的防疫活动', + livestockCategory: '羊', + diseaseCategory: '布鲁氏菌病', + vaccineUsed: '更新疫苗', + vaccineBatch: 'UPDATE001', + preventionDate: '2023-12-15至2024-01-15', + activityStatus: 'inactive' + }; + + const response = await api.put(`/${id}`, updateData); + console.log('更新成功:', response.data); + } catch (error) { + console.error('更新失败:', error.response?.data || error.message); + } +} + +// 测试切换活动状态 +async function testToggleStatus(id) { + try { + console.log('测试切换活动状态...'); + const response = await api.patch(`/${id}/status`); + console.log('状态切换成功:', response.data); + } catch (error) { + console.error('状态切换失败:', error.response?.data || error.message); + } +} + +// 测试删除防疫活动 +async function testDeleteActivity(id) { + try { + console.log('测试删除防疫活动...'); + const response = await api.delete(`/${id}`); + console.log('删除成功:', response.data); + } catch (error) { + console.error('删除失败:', error.response?.data || error.message); + } +} + +// 运行所有测试 +async function runTests() { + console.log('开始测试防疫活动管理API...\n'); + + await testGetActivities(); + console.log('\n' + '='.repeat(50) + '\n'); + + const createdId = await testCreateActivity(); + console.log('\n' + '='.repeat(50) + '\n'); + + if (createdId) { + await testUpdateActivity(createdId); + console.log('\n' + '='.repeat(50) + '\n'); + + await testToggleStatus(createdId); + console.log('\n' + '='.repeat(50) + '\n'); + + await testDeleteActivity(createdId); + } + + console.log('\n测试完成!'); +} + +// 如果直接运行此文件 +if (require.main === module) { + runTests(); +} + +module.exports = { + testGetActivities, + testCreateActivity, + testUpdateActivity, + testToggleStatus, + testDeleteActivity +}; diff --git a/website/bank-system.html b/website/bank-system.html index 65acf0a..b845b97 100644 --- a/website/bank-system.html +++ b/website/bank-system.html @@ -53,7 +53,7 @@ 助力银行降低信贷风险,提高资产质量。