const express = require('express') const cors = require('cors') const bodyParser = require('body-parser') const path = require('path') const fs = require('fs') const multer = require('multer') const XLSX = require('xlsx') const app = express() const port = process.env.PORT || 4000 app.use(cors({ origin: '*', methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization'] })) app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: true })) app.get('/', (req, res) => { const userAgent = req.headers['user-agent'] || '' const isWindows = /Windows/i.test(userAgent) const isMac = /Macintosh/i.test(userAgent) const isDesktop = isWindows || isMac if (isDesktop) { res.redirect('/admin') } else { const h5Index = path.join(__dirname, '../dist/build/h5/index.html') res.sendFile(h5Index) } }) app.use(express.static(path.join(__dirname, '../dist/build/h5'))) app.use('/admin', express.static(path.join(__dirname, '../admin'))) app.use('/wx', express.static(path.join(__dirname, '../dist/build/mp-weixin'))) const iconDir = path.join(__dirname, 'icons') if (!fs.existsSync(iconDir)) { fs.mkdirSync(iconDir, { recursive: true }) } const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, iconDir) }, filename: function (req, file, cb) { const ext = path.extname(file.originalname) const filename = 'icon_' + Date.now() + ext cb(null, filename) } }) const upload = multer({ storage: storage, limits: { fileSize: 5 * 1024 * 1024 }, fileFilter: function (req, file, cb) { const allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'] if (allowedTypes.includes(file.mimetype)) { cb(null, true) } else { cb(new Error('Only PNG, JPG, JPEG, GIF images are allowed')) } } }) app.use('/api/icons', express.static(iconDir)) const dataDir = path.join(__dirname, 'data') if (!fs.existsSync(dataDir)) { fs.mkdirSync(dataDir, { recursive: true }) } const pricesPath = path.join(dataDir, 'prices.json') const ordersPath = path.join(dataDir, 'orders.json') const usersPath = path.join(dataDir, 'users.json') const citiesPath = path.join(dataDir, 'cities.json') const districtsPath = path.join(dataDir, 'districts.json') const stationsPath = path.join(dataDir, 'stations.json') const siteUsersPath = path.join(dataDir, 'site_users.json') const regionsPath = path.join(dataDir, 'regions.json') const adminPath = path.join(dataDir, 'admin.json') const loadData = (filePath, defaultData) => { try { if (fs.existsSync(filePath)) { const content = fs.readFileSync(filePath, 'utf-8') return JSON.parse(content) } } catch (err) { console.error('Failed to load data:', err) } return defaultData } const saveData = (filePath, data) => { try { fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8') } catch (err) { console.error('Failed to save data:', err) } } const defaultPrices = [ { category: '001', name: '纸类', unit: 'kg', price: 1.2, icon: '' }, { category: '002', name: '金属', unit: 'kg', price: 2.5, icon: '' }, { category: '003', name: '易拉罐', unit: 'piece', price: 0.1, icon: '' }, { category: '004', name: '塑料', unit: 'kg', price: 3.0, icon: '' }, { category: '005', name: '织物', unit: 'kg', price: 0.8, icon: '' }, { category: '006', name: '塑料瓶', unit: 'piece', price: 0.05, icon: '' } ] const defaultOrders = [] const defaultUsers = [ { id: '1', name: 'Admin', phone: '18698102228', password: '123456', role: 'admin', createTime: '2024-01-01' }, { id: '2', name: 'Collector Wang', phone: '18698102228', password: '123456', role: 'collector', createTime: '2024-01-15' } ] const defaultCities = [ { id: '1', name: 'Tianjin' }, { id: '2', name: 'Beijing' }, { id: '3', name: 'Shanghai' }, { id: '4', name: 'Guangzhou' } ] const defaultDistricts = [ { id: 'd1', cityId: '1', name: 'Gaoxin' }, { id: 'd2', cityId: '1', name: 'Xiqing' }, { id: 'd3', cityId: '1', name: 'Baoshui' }, { id: 'd4', cityId: '2', name: 'Dongcheng' }, { id: 'd5', cityId: '2', name: 'Xicheng' }, { id: 'd6', cityId: '2', name: 'Chaoyang' }, { id: 'd7', cityId: '2', name: 'Haidian' }, { id: 'd8', cityId: '3', name: 'Huangpu' }, { id: 'd9', cityId: '3', name: 'Xuhui' }, { id: 'd10', cityId: '3', name: 'Pudong' }, { id: 'd11', cityId: '4', name: 'Tianhe' }, { id: 'd12', cityId: '4', name: 'Haizhu' }, { id: 'd13', cityId: '4', name: 'Yuexiu' } ] const defaultStations = [ { id: 's1', cityId: '1', districtId: 'd1', name: '金融街融汇景苑' }, { id: 's2', cityId: '1', districtId: 'd1', name: '金辉江山铭筑' }, { id: 's3', cityId: '1', districtId: 'd2', name: '华兴里' }, { id: 's4', cityId: '1', districtId: 'd2', name: '华兴南里' }, { id: 's5', cityId: '1', districtId: 'd3', name: '意境兰庭' } ] const defaultSiteUsers = [ { id: 'su1', stationId: 's1', name: 'Xiwei Laoshan', type: 'merchant' }, { id: 'su2', stationId: 's1', name: 'New Merchant', type: 'merchant' }, { id: 'su3', stationId: 's1', name: 'New Individual', type: 'individual' }, { id: 'su4', stationId: 's2', name: 'New Merchant', type: 'merchant' }, { id: 'su5', stationId: 's2', name: 'New Individual', type: 'individual' }, { id: 'su6', stationId: 's3', name: 'New Merchant', type: 'merchant' }, { id: 'su7', stationId: 's3', name: 'New Individual', type: 'individual' }, { id: 'su8', stationId: 's4', name: 'New Merchant', type: 'merchant' }, { id: 'su9', stationId: 's4', name: 'New Individual', type: 'individual' }, { id: 'su10', stationId: 's5', name: 'New Merchant', type: 'merchant' }, { id: 'su11', stationId: 's5', name: 'New Individual', type: 'individual' } ] const defaultRegions = [] const defaultAdmin = [ { id: 1, username: 'admin', phone: '18698102228', password: '123456' } ] let prices = loadData(pricesPath, defaultPrices) let orders = loadData(ordersPath, defaultOrders) let users = loadData(usersPath, defaultUsers) let cities = loadData(citiesPath, defaultCities) let districts = loadData(districtsPath, defaultDistricts) let stations = loadData(stationsPath, defaultStations) let siteUsers = loadData(siteUsersPath, defaultSiteUsers) let regions = loadData(regionsPath, defaultRegions) let admin = loadData(adminPath, defaultAdmin) console.log('Database initialized') console.log('Prices:', JSON.stringify(prices, null, 2)) app.get('/api', (req, res) => { res.send(` Yi Fen Bao - Backend Service

Yi Fen Bao

Backend Service Running

Frontend Applications

GET/H5 App
GET/adminAdmin Panel
GET/wxWeChat Mini Program

API Endpoints

GET/api/pricesGet price list
GET/api/ordersGet orders
POST/api/ordersCreate order
PUT/api/orders/:idUpdate order
DELETE/api/orders/:idDelete order
GET/api/usersGet users
POST/api/users/loginUser login
POST/api/usersRegister user
POST/api/admin/loginAdmin login
GET/api/citiesGet cities
GET/api/districts/:cityIdGet districts
GET/api/stations/:cityId/:districtIdGet stations
GET/api/site_users/:stationIdGet site users
`) }) app.get('/api/prices', (req, res) => { res.json({ date: new Date().toISOString().split('T')[0], prices: prices }) }) app.post('/api/prices', (req, res) => { const { category, name, icon, unit, price } = req.body if (!category || !name || !price) { return res.status(400).json({ error: '缺少必要参数' }) } prices.push({ category, name, icon: icon || 'paper', unit: unit || 'kg', price }) fs.writeFileSync(pricesPath, JSON.stringify(prices, null, 2)) res.json({ success: true, prices }) }) app.put('/api/prices', (req, res) => { const { oldName, category, name, icon, unit, price } = req.body const index = prices.findIndex(p => p.name === oldName) if (index === -1) { return res.status(404).json({ error: '品类不存在' }) } prices[index] = { category, name, icon: icon || 'paper', unit: unit || 'kg', price } fs.writeFileSync(pricesPath, JSON.stringify(prices, null, 2)) res.json({ success: true, prices }) }) app.delete('/api/prices', (req, res) => { const { name } = req.body const index = prices.findIndex(p => p.name === name) if (index === -1) { return res.status(404).json({ error: '品类不存在' }) } prices.splice(index, 1) fs.writeFileSync(pricesPath, JSON.stringify(prices, null, 2)) res.json({ success: true, prices }) }) app.get('/api/statistics', (req, res) => { const totalOrders = orders.length const totalAmount = orders.reduce((sum, order) => sum + (order.totalAmount || 0), 0) const totalWeight = orders.reduce((sum, order) => { return sum + order.items.reduce((itemSum, item) => itemSum + (item.weight || 0), 0) }, 0) const avgAmount = totalOrders > 0 ? totalAmount / totalOrders : 0 const statusStats = { pending: orders.filter(o => o.status === 'pending').length, completed: orders.filter(o => o.status === 'completed').length, cancelled: orders.filter(o => o.status === 'cancelled').length } const categoryStats = {} orders.forEach(order => { order.items.forEach(item => { const name = item.name || '其他' if (!categoryStats[name]) { categoryStats[name] = { name, orders: 0, weight: 0, amount: 0 } } categoryStats[name].orders++ categoryStats[name].weight += item.weight || 0 categoryStats[name].amount += item.amount || 0 }) }) const categoryStatsArray = Object.values(categoryStats).map(cat => ({ ...cat, weightPercent: totalWeight > 0 ? (cat.weight / totalWeight * 100) : 0, amountPercent: totalAmount > 0 ? (cat.amount / totalAmount * 100) : 0 })) res.json({ data: { totalOrders, totalAmount, totalWeight, avgAmount, statusStats, categoryStats: categoryStatsArray } }) }) app.get('/api/orders', (req, res) => { const { collector } = req.query console.log('=== 查询订单 ===') console.log('collector参数:', collector) let filteredOrders = orders if (collector) { console.log('开始过滤,原始订单数:', orders.length) filteredOrders = orders.filter(order => order.collectorId === collector) console.log('过滤后订单数:', filteredOrders.length) } const processedOrders = filteredOrders.map(order => { const items = order.items.map(item => { const weight = item.weight || item.count || 0 const price = item.price || 0 return { ...item, amount: item.amount !== undefined ? item.amount : weight * price } }) const totalAmount = order.totalAmount !== undefined ? order.totalAmount : items.reduce((sum, item) => sum + (item.amount || 0), 0) return { ...order, items, totalAmount } }) res.json({ data: processedOrders.sort((a, b) => new Date(b.createTime) - new Date(a.createTime)) }) }) app.get('/api/orders/:id', (req, res) => { const order = orders.find(o => o.id === req.params.id) res.json(order || {}) }) app.post('/api/orders', (req, res) => { const { items, totalWeight, totalPrice, city, district, community, user, phone, address, collector, collectorId } = req.body console.log('=== 创建订单 ===') console.log('collector:', collector) console.log('collectorId:', collectorId) console.log('完整请求体:', JSON.stringify(req.body)) const maxId = orders.length > 0 ? Math.max(...orders.map(o => parseInt(o.id) || 0)) : 0 const id = (maxId + 1).toString() const now = new Date() const offset = 8 * 60 * 60 * 1000 const nowCST = new Date(now.getTime() + offset) const createTime = `${nowCST.getUTCFullYear()}-${String(nowCST.getUTCMonth() + 1).padStart(2, '0')}-${String(nowCST.getUTCDate()).padStart(2, '0')} ${String(nowCST.getUTCHours()).padStart(2, '0')}:${String(nowCST.getUTCMinutes()).padStart(2, '0')}` const processedItems = items.map(item => { const weight = item.weight || item.count || 0 const price = item.price || 0 return { ...item, amount: weight * price } }) const totalAmount = processedItems.reduce((sum, item) => sum + (item.amount || 0), 0) const newOrder = { id, items: processedItems, totalAmount, totalWeight, totalPrice, city, district, community, user, phone, address, collector, collectorId, status: 'pending', createTime } orders.push(newOrder) saveData(ordersPath, orders) res.json({ success: true, order: newOrder }) }) app.put('/api/orders/:id', (req, res) => { const id = req.params.id const index = orders.findIndex(o => o.id === id) if (index === -1) { res.json({ success: false, message: 'Not found' }) return } const { status, items, totalWeight, totalPrice, collectorId, collector } = req.body if (status !== undefined) orders[index].status = status if (items !== undefined) orders[index].items = items if (totalWeight !== undefined) orders[index].totalWeight = totalWeight if (totalPrice !== undefined) orders[index].totalPrice = totalPrice if (collectorId !== undefined) orders[index].collectorId = collectorId if (collector !== undefined) orders[index].collector = collector saveData(ordersPath, orders) res.json({ success: true, message: 'Updated' }) }) app.delete('/api/orders/:id', (req, res) => { const id = req.params.id console.log('=== 删除订单 ===') console.log('删除前订单数:', orders.length) const index = orders.findIndex(o => o.id === id) if (index === -1) { res.json({ success: false, message: 'Not found' }) return } orders.splice(index, 1) orders.forEach((order, idx) => { order.id = (idx + 1).toString() }) console.log('删除后订单数:', orders.length) console.log('重新编号后的订单ID:', orders.map(o => o.id)) saveData(ordersPath, orders) res.json({ success: true, message: 'Deleted' }) }) app.get('/api/users', (req, res) => { res.json({ success: true, data: users.map(u => ({ id: u.id, name: u.name, phone: u.phone, role: u.role, createTime: u.createTime })) }) }) app.post('/api/users/login', (req, res) => { const { phone, password } = req.body const user = users.find(u => u.phone === phone && u.password === password) if (user) { res.json({ success: true, data: { id: user.id, name: user.name, phone: user.phone, role: user.role } }) } else { res.json({ success: false, message: 'Wrong credentials' }) } }) app.post('/api/users', (req, res) => { const { name, phone, password = '123456', role = 'collector' } = req.body const existing = users.find(u => u.phone === phone) if (existing) { res.json({ success: false, message: 'Phone exists' }) return } const maxId = users.length > 0 ? Math.max(...users.map(u => parseInt(u.id) || 0)) : 0 const id = (maxId + 1).toString() const createTime = new Date().toISOString().split('T')[0] const newUser = { id, name, phone, password, role, createTime } users.push(newUser) saveData(usersPath, users) res.json({ success: true, data: newUser }) }) app.put('/api/users/:id', (req, res) => { const { id } = req.params const { name, phone, role } = req.body const index = users.findIndex(u => u.id === id) if (index === -1) { res.json({ success: false, message: '用户不存在' }) return } users[index] = { ...users[index], name, phone, role } saveData(usersPath, users) res.json({ success: true, data: users[index] }) }) app.delete('/api/users/:id', (req, res) => { const { id } = req.params const index = users.findIndex(u => u.id === id) if (index === -1) { res.json({ success: false, message: '用户不存在' }) return } users.splice(index, 1) saveData(usersPath, users) res.json({ success: true }) }) app.post('/api/admin/login', (req, res) => { const { phone, password } = req.body const adminUser = admin.find(a => a.phone === phone && a.password === password) if (adminUser) { res.json({ success: true, data: { id: adminUser.id, username: adminUser.username, phone: adminUser.phone } }) return } const userAdmin = users.find(u => u.role === 'admin' && u.phone === phone && u.password === password) if (userAdmin) { res.json({ success: true, data: { id: userAdmin.id, username: userAdmin.name, phone: userAdmin.phone } }) } else { res.json({ success: false, message: '手机号或密码错误' }) } }) app.get('/api/cities', (req, res) => { res.json(cities) }) app.get('/api/districts/:cityId', (req, res) => { res.json(districts.filter(d => d.cityId === req.params.cityId)) }) app.get('/api/stations/:cityId/:districtId', (req, res) => { res.json(stations.filter(s => s.cityId === req.params.cityId && s.districtId === req.params.districtId)) }) app.get('/api/site_users/:stationId', (req, res) => { res.json(siteUsers.filter(u => u.stationId === req.params.stationId)) }) app.get('/api/regions/cities', (req, res) => { res.json({ success: true, data: cities }) }) app.post('/api/regions/cities', (req, res) => { const { name } = req.body if (!name) { res.json({ success: false, message: '请输入城市名称' }) return } const existing = cities.find(c => c.name === name) if (existing) { res.json({ success: true, data: existing }) return } const newCity = { id: Date.now().toString(36), name } cities.push(newCity) saveData(citiesPath, cities) res.json({ success: true, data: newCity }) }) app.put('/api/regions/cities/:id', (req, res) => { const { id } = req.params const { name } = req.body const index = cities.findIndex(c => c.id === id) if (index === -1) { res.json({ success: false, message: '城市不存在' }) return } cities[index].name = name saveData(citiesPath, cities) res.json({ success: true, data: cities[index] }) }) app.delete('/api/regions/cities/:id', (req, res) => { const { id } = req.params const index = cities.findIndex(c => c.id === id) if (index === -1) { res.json({ success: false, message: '城市不存在' }) return } cities.splice(index, 1) districts = districts.filter(d => d.cityId !== id) stations = stations.filter(s => s.cityId !== id) siteUsers = siteUsers.filter(u => { const station = stations.find(s => s.id === u.stationId) return station !== undefined }) saveData(citiesPath, cities) saveData(districtsPath, districts) saveData(stationsPath, stations) saveData(siteUsersPath, siteUsers) res.json({ success: true }) }) app.get('/api/regions/districts', (req, res) => { const result = districts.map(d => { const city = cities.find(c => c.id === d.cityId) return { ...d, cityName: city ? city.name : '' } }) res.json({ success: true, data: result }) }) app.post('/api/regions/districts', (req, res) => { const { cityId, name } = req.body if (!cityId || !name) { res.json({ success: false, message: '请填写完整信息' }) return } const existing = districts.find(d => d.cityId === cityId && d.name === name) if (existing) { res.json({ success: true, data: existing }) return } const newDistrict = { id: Date.now().toString(36), cityId, name } districts.push(newDistrict) saveData(districtsPath, districts) res.json({ success: true, data: newDistrict }) }) app.put('/api/regions/districts/:id', (req, res) => { const { id } = req.params const { cityId, name } = req.body const index = districts.findIndex(d => d.id === id) if (index === -1) { res.json({ success: false, message: '区域不存在' }) return } districts[index] = { ...districts[index], cityId, name } saveData(districtsPath, districts) res.json({ success: true, data: districts[index] }) }) app.delete('/api/regions/districts/:id', (req, res) => { const { id } = req.params const index = districts.findIndex(d => d.id === id) if (index === -1) { res.json({ success: false, message: '区域不存在' }) return } districts.splice(index, 1) stations = stations.filter(s => s.districtId !== id) siteUsers = siteUsers.filter(u => { const station = stations.find(s => s.id === u.stationId) return station !== undefined }) saveData(districtsPath, districts) saveData(stationsPath, stations) saveData(siteUsersPath, siteUsers) res.json({ success: true }) }) app.get('/api/regions/stations', (req, res) => { const result = stations.map(s => { const city = cities.find(c => c.id === s.cityId) const district = districts.find(d => d.id === s.districtId) return { ...s, cityName: city ? city.name : '', districtName: district ? district.name : '' } }) res.json({ success: true, data: result }) }) app.post('/api/regions/stations', (req, res) => { const { cityId, districtId, name } = req.body if (!cityId || !districtId || !name) { res.json({ success: false, message: '请填写完整信息' }) return } const newStation = { id: Date.now().toString(36), cityId, districtId, name } stations.push(newStation) saveData(stationsPath, stations) res.json({ success: true, data: newStation }) }) app.put('/api/regions/stations/:id', (req, res) => { const { id } = req.params const { cityId, districtId, name } = req.body const index = stations.findIndex(s => s.id === id) if (index === -1) { res.json({ success: false, message: '站点不存在' }) return } stations[index] = { ...stations[index], cityId, districtId, name } saveData(stationsPath, stations) res.json({ success: true, data: stations[index] }) }) app.delete('/api/regions/stations/:id', (req, res) => { const { id } = req.params const index = stations.findIndex(s => s.id === id) if (index === -1) { res.json({ success: false, message: '站点不存在' }) return } stations.splice(index, 1) siteUsers = siteUsers.filter(u => u.stationId !== id) saveData(stationsPath, stations) saveData(siteUsersPath, siteUsers) res.json({ success: true }) }) app.get('/api/regions/site-users', (req, res) => { const result = siteUsers.map(u => { const station = stations.find(s => s.id === u.stationId) return { ...u, stationName: station ? station.name : '' } }) res.json({ success: true, data: result }) }) app.get('/api/regions/station-by-name', (req, res) => { const { name } = req.query const station = stations.find(s => s.name === name) if (station) { res.json({ success: true, data: station }) } else { res.json({ success: false, message: '站点不存在' }) } }) app.post('/api/regions/site-users', (req, res) => { const { stationId, name, type = 'merchant' } = req.body if (!stationId || !name) { res.json({ success: false, message: '请填写完整信息' }) return } const newUser = { id: Date.now().toString(36), stationId, name, type } siteUsers.push(newUser) saveData(siteUsersPath, siteUsers) res.json({ success: true, data: newUser }) }) app.put('/api/regions/site-users/:id', (req, res) => { const { id } = req.params const { stationId, name, type } = req.body const index = siteUsers.findIndex(u => u.id === id) if (index === -1) { res.json({ success: false, message: '用户不存在' }) return } siteUsers[index] = { ...siteUsers[index], stationId, name, type } saveData(siteUsersPath, siteUsers) res.json({ success: true, data: siteUsers[index] }) }) app.delete('/api/regions/site-users/:id', (req, res) => { const { id } = req.params const index = siteUsers.findIndex(u => u.id === id) if (index === -1) { res.json({ success: false, message: '用户不存在' }) return } siteUsers.splice(index, 1) saveData(siteUsersPath, siteUsers) res.json({ success: true }) }) app.get('/api/regions', (req, res) => { res.json(regions) }) app.post('/api/regions', (req, res) => { const { city, district, community } = req.body const existing = regions.find(r => r.city === city && r.district === district && r.community === community) if (existing) { res.json({ success: true, message: 'Exists' }) return } regions.push({ id: regions.length + 1, city, district, community }) saveData(regionsPath, regions) res.json({ success: true, message: 'Added' }) }) app.delete('/api/regions/:id', (req, res) => { const id = parseInt(req.params.id) const index = regions.findIndex(r => r.id === id) if (index === -1) { res.json({ success: false, message: 'Not found' }) return } regions.splice(index, 1) saveData(regionsPath, regions) res.json({ success: true, message: 'Deleted' }) }) const importStorage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, dataDir) }, filename: function (req, file, cb) { const ext = path.extname(file.originalname) const filename = 'import_' + Date.now() + ext cb(null, filename) } }) const importUpload = multer({ storage: importStorage, limits: { fileSize: 10 * 1024 * 1024 }, fileFilter: function (req, file, cb) { const allowedTypes = ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel'] const allowedExtensions = ['.xlsx', '.xls'] const ext = path.extname(file.originalname).toLowerCase() if (allowedTypes.includes(file.mimetype) || allowedExtensions.includes(ext)) { cb(null, true) } else { cb(new Error('只支持 Excel 文件 (.xlsx, .xls)')) } } }) app.post('/api/regions/import', importUpload.single('file'), (req, res) => { try { if (!req.file) { res.json({ success: false, message: '请选择文件' }) return } const filePath = path.join(dataDir, req.file.filename) const workbook = XLSX.readFile(filePath) const sheetName = workbook.SheetNames[0] const worksheet = workbook.Sheets[sheetName] const jsonData = XLSX.utils.sheet_to_json(worksheet) let addedCities = 0 let addedDistricts = 0 let addedStations = 0 let addedSiteUsers = 0 let skippedCities = 0 let skippedDistricts = 0 let skippedStations = 0 let skippedSiteUsers = 0 for (const row of jsonData) { const cityName = row['城市'] || row['city'] || row['City'] || '' const districtName = row['区域'] || row['district'] || row['District'] || row['区'] || '' const stationName = row['站点'] || row['station'] || row['Station'] || row['社区'] || row['community'] || '' const siteUserName = row['站点用户'] || row['site_user'] || row['siteUser'] || row['SiteUser'] || row['用户'] || row['user'] || '' if (!cityName) continue let cityId = cities.find(c => c.name === cityName)?.id if (!cityId) { cityId = Date.now().toString(36) + Math.random().toString(36).substr(2, 5) cities.push({ id: cityId, name: cityName }) addedCities++ } else { skippedCities++ } if (districtName) { let districtId = districts.find(d => d.cityId === cityId && d.name === districtName)?.id if (!districtId) { districtId = Date.now().toString(36) + Math.random().toString(36).substr(2, 5) districts.push({ id: districtId, cityId, name: districtName }) addedDistricts++ } else { skippedDistricts++ } if (stationName) { let station = stations.find(s => s.cityId === cityId && s.districtId === districtId && s.name === stationName) if (!station) { const stationId = Date.now().toString(36) + Math.random().toString(36).substr(2, 5) station = { id: stationId, cityId, districtId, name: stationName } stations.push(station) addedStations++ } else { skippedStations++ } if (siteUserName) { const existsSiteUser = siteUsers.find(u => u.stationId === station.id && u.name === siteUserName) if (!existsSiteUser) { const userId = Date.now().toString(36) + Math.random().toString(36).substr(2, 5) siteUsers.push({ id: userId, stationId: station.id, name: siteUserName }) addedSiteUsers++ } else { skippedSiteUsers++ } } } } } saveData(citiesPath, cities) saveData(districtsPath, districts) saveData(stationsPath, stations) saveData(siteUsersPath, siteUsers) fs.unlinkSync(filePath) res.json({ success: true, message: `导入成功!新增城市:${addedCities}, 新增区域:${addedDistricts}, 新增站点:${addedStations}, 新增站点用户:${addedSiteUsers}`, data: { addedCities, addedDistricts, addedStations, addedSiteUsers, skippedCities, skippedDistricts, skippedStations, skippedSiteUsers } }) } catch (error) { console.error('导入失败:', error) res.json({ success: false, message: '导入失败: ' + error.message }) } }) app.listen(port, '0.0.0.0', () => { console.log(`Server running on http://0.0.0.0:${port}`) })