From 745dce8f11021cc43fb562f0cc2cae39273d6ca4 Mon Sep 17 00:00:00 2001 From: afc163 Date: Wed, 8 Apr 2026 20:02:43 +0800 Subject: [PATCH] feat: add missing API routes for Cloudflare Worker (#11659) Co-authored-by: Claude Opus 4.6 --- cloudflare-worker/src/index.ts | 20 ++ cloudflare-worker/src/routes/geographic.ts | 100 +++++++++ cloudflare-worker/src/routes/list.ts | 244 +++++++++++++++++++++ cloudflare-worker/src/routes/monitor.ts | 90 ++++++++ cloudflare-worker/src/routes/profile.ts | 169 ++++++++++++++ cloudflare-worker/src/routes/settings.ts | 38 ++++ 6 files changed, 661 insertions(+) create mode 100644 cloudflare-worker/src/routes/geographic.ts create mode 100644 cloudflare-worker/src/routes/list.ts create mode 100644 cloudflare-worker/src/routes/profile.ts create mode 100644 cloudflare-worker/src/routes/settings.ts diff --git a/cloudflare-worker/src/index.ts b/cloudflare-worker/src/index.ts index 3f3a3915..a22e4303 100644 --- a/cloudflare-worker/src/index.ts +++ b/cloudflare-worker/src/index.ts @@ -2,8 +2,12 @@ import { Hono } from 'hono'; import { cors } from 'hono/cors'; import dashboardRoutes from './routes/dashboard'; import errorRoutes from './routes/errors'; +import geographicRoutes from './routes/geographic'; +import listRoutes from './routes/list'; import monitorRoutes from './routes/monitor'; import noticesRoutes from './routes/notices'; +import profileRoutes from './routes/profile'; +import settingsRoutes from './routes/settings'; import tableRoutes from './routes/table'; import userRoutes from './routes/user'; import { corsOrigin } from './utils/cors'; @@ -35,5 +39,21 @@ app.route('/api', tableRoutes); app.route('/api', noticesRoutes); app.route('/api/monitor', monitorRoutes); app.route('/api', errorRoutes); +app.route('/api/geographic', geographicRoutes); +app.route('/api', listRoutes); +app.route('/api/profile', profileRoutes); +app.route('/api', settingsRoutes); + +// 404 handler with URL in message +app.notFound((c) => { + const url = c.req.url; + return c.json( + { + message: `Response status: 404, URL: ${url}`, + success: false, + }, + 404, + ); +}); export default app; diff --git a/cloudflare-worker/src/routes/geographic.ts b/cloudflare-worker/src/routes/geographic.ts new file mode 100644 index 00000000..d94ee3fd --- /dev/null +++ b/cloudflare-worker/src/routes/geographic.ts @@ -0,0 +1,100 @@ +import { Hono } from 'hono'; + +const app = new Hono(); + +// Province data - simplified with key/label format +const provinceData = [ + { label: '北京市', key: '110000' }, + { label: '天津市', key: '120000' }, + { label: '河北省', key: '130000' }, + { label: '山西省', key: '140000' }, + { label: '内蒙古自治区', key: '150000' }, + { label: '辽宁省', key: '210000' }, + { label: '吉林省', key: '220000' }, + { label: '黑龙江省', key: '230000' }, + { label: '上海市', key: '310000' }, + { label: '江苏省', key: '320000' }, + { label: '浙江省', key: '330000' }, + { label: '安徽省', key: '340000' }, + { label: '福建省', key: '350000' }, + { label: '江西省', key: '360000' }, + { label: '山东省', key: '370000' }, + { label: '河南省', key: '410000' }, + { label: '湖北省', key: '420000' }, + { label: '湖南省', key: '430000' }, + { label: '广东省', key: '440000' }, + { label: '广西壮族自治区', key: '450000' }, + { label: '海南省', key: '460000' }, + { label: '重庆市', key: '500000' }, + { label: '四川省', key: '510000' }, + { label: '贵州省', key: '520000' }, + { label: '云南省', key: '530000' }, + { label: '西藏自治区', key: '540000' }, + { label: '陕西省', key: '610000' }, + { label: '甘肃省', key: '620000' }, + { label: '青海省', key: '630000' }, + { label: '宁夏回族自治区', key: '640000' }, + { label: '新疆维吾尔自治区', key: '650000' }, + { label: '台湾省', key: '710000' }, + { label: '香港特别行政区', key: '810000' }, + { label: '澳门特别行政区', key: '820000' }, +]; + +// City data - moved outside handler for performance +const cityData: Record = { + '110000': [{ label: '市辖区', key: '110100' }], + '120000': [{ label: '市辖区', key: '120100' }], + '310000': [{ label: '市辖区', key: '310100' }], + '330000': [ + { label: '杭州市', key: '330100' }, + { label: '宁波市', key: '330200' }, + { label: '温州市', key: '330300' }, + { label: '嘉兴市', key: '330400' }, + { label: '湖州市', key: '330500' }, + { label: '绍兴市', key: '330600' }, + { label: '金华市', key: '330700' }, + { label: '衢州市', key: '330800' }, + { label: '舟山市', key: '330900' }, + { label: '台州市', key: '331000' }, + { label: '丽水市', key: '331100' }, + ], + '440000': [ + { label: '广州市', key: '440100' }, + { label: '韶关市', key: '440200' }, + { label: '深圳市', key: '440300' }, + { label: '珠海市', key: '440400' }, + { label: '汕头市', key: '440500' }, + { label: '佛山市', key: '440600' }, + { label: '江门市', key: '440700' }, + { label: '湛江市', key: '440800' }, + { label: '茂名市', key: '440900' }, + { label: '肇庆市', key: '441200' }, + { label: '惠州市', key: '441300' }, + { label: '梅州市', key: '441400' }, + { label: '汕尾市', key: '441500' }, + { label: '河源市', key: '441600' }, + { label: '阳江市', key: '441700' }, + { label: '清远市', key: '441800' }, + { label: '东莞市', key: '441900' }, + { label: '中山市', key: '442000' }, + ], +}; + +// GET /api/geographic/province +app.get('/province', (c) => { + return c.json({ + data: provinceData, + }); +}); + +// GET /api/geographic/city/:province +app.get('/city/:province', (c) => { + const province = c.req.param('province'); + + // Return data for the province, or empty array if not found + return c.json({ + data: cityData[province] || [], + }); +}); + +export default app; diff --git a/cloudflare-worker/src/routes/list.ts b/cloudflare-worker/src/routes/list.ts new file mode 100644 index 00000000..b9536914 --- /dev/null +++ b/cloudflare-worker/src/routes/list.ts @@ -0,0 +1,244 @@ +import { Hono } from 'hono'; + +const titles = [ + 'Alipay', + 'Angular', + 'Ant Design', + 'Ant Design Pro', + 'Bootstrap', + 'React', + 'Vue', + 'Webpack', +]; + +const avatars = [ + 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', + 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', + 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', + 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', + 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', + 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', + 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', + 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', +]; + +const covers = [ + 'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png', + 'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png', +]; + +const desc = [ + '那是一种内在的东西, 他们到达不了,也无法触及的', + '希望是一个好东西,也许是最好的,好东西是不会消亡的', + '生命就像一盒巧克力,结果往往出人意料', + '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + '那时候我只会想自己想要什么,从不想自己拥有什么', +]; + +const user = [ + '付小小', + '曲丽丽', + '林东东', + '周星星', + '吴加好', + '朱偏右', + '鱼酱', + '乐哥', + '谭小仪', + '仲尼', +]; + +// Count bounds to prevent memory exhaustion +const COUNT_MIN = 1; +const COUNT_MAX = 100; +const DEFAULT_COUNT = 20; +const DEFAULT_COUNT_SMALL = 5; + +function parseCount(value: string | undefined, defaultVal: number): number { + const parsed = Number(value); + if (Number.isNaN(parsed)) { + return defaultVal; + } + return Math.max(COUNT_MIN, Math.min(parsed, COUNT_MAX)); +} + +function fakeList(count: number) { + const list = []; + for (let i = 0; i < count; i += 1) { + list.push({ + id: `fake-list-${i}`, + owner: user[i % 10], + title: titles[i % 8], + avatar: avatars[i % 8], + cover: + parseInt(`${i / 4}`, 10) % 2 === 0 + ? covers[i % 4] + : covers[3 - (i % 4)], + status: ['active', 'exception', 'normal'][i % 3] as + | 'normal' + | 'exception' + | 'active' + | 'success', + percent: Math.ceil(Math.random() * 50) + 50, + logo: avatars[i % 8], + href: 'https://ant.design', + updatedAt: new Date().getTime() - Math.floor(Math.random() * 1000000000), + createdAt: new Date().getTime() - Math.floor(Math.random() * 1000000000), + subDescription: desc[i % 5], + description: + '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的共通点和组成部分,该专案即是致力于归纳和吸收各种产品的各自优势,致力于打造成中后台产品的根底', + activeUser: Math.floor(Math.random() * 10000) + 1000, + newUser: Math.floor(Math.random() * 1000) + 100, + star: Math.floor(Math.random() * 100) + 10, + like: Math.floor(Math.random() * 100) + 10, + message: Math.floor(Math.random() * 100) + 10, + content: + '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。', + members: [ + { + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png', + name: '曲丽丽', + id: 'member1', + }, + { + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png', + name: '王昭君', + id: 'member2', + }, + { + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png', + name: '董娜娜', + id: 'member3', + }, + ], + }); + } + return list; +} + +let sourceData: ReturnType = []; + +const app = new Hono(); + +// GET /api/get_list +app.get('/get_list', (c) => { + const count = parseCount(c.req.query('count'), DEFAULT_COUNT); + const result = fakeList(count); + sourceData = result; + return c.json({ + data: { + list: result, + }, + }); +}); + +// POST /api/post_fake_list +app.post('/post_fake_list', async (c) => { + const body = await c.req.json(); + const { method, id } = body; + let result = sourceData || []; + + switch (method) { + case 'delete': + result = result.filter((item: (typeof result)[0]) => item.id !== id); + break; + case 'update': + result = result.map((item: (typeof result)[0]) => + item.id === id ? { ...item, ...body } : item, + ); + break; + case 'post': + result.unshift({ + ...body, + id: `fake-list-${result.length}`, + createdAt: Date.now(), + }); + break; + default: + break; + } + + return c.json({ + data: { + list: result, + }, + }); +}); + +// GET /api/card_fake_list +app.get('/card_fake_list', (c) => { + const count = parseCount(c.req.query('count'), DEFAULT_COUNT); + const result = fakeList(count); + return c.json({ + data: { + list: result, + }, + }); +}); + +// GET /api/tags +app.get('/tags', (c) => { + const list = []; + for (let i = 0; i < 100; i++) { + list.push({ + name: ['城市', '省份', '区划'][Math.floor(Math.random() * 3)] + i, + value: Math.floor(Math.random() * 100) + 1, + type: Math.floor(Math.random() * 3), + }); + } + return c.json({ + data: { list }, + }); +}); + +// GET /api/fake_list_Detail +app.get('/fake_list_Detail', (c) => { + const count = parseCount(c.req.query('count'), DEFAULT_COUNT_SMALL); + const result = fakeList(count); + return c.json({ + data: { + list: result, + }, + }); +}); + +// GET /api/currentUserDetail +app.get('/currentUserDetail', (c) => { + return c.json({ + data: { + name: 'Serati Ma', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', + userid: '00000001', + email: 'antdesign@alipay.com', + signature: '海纳百川,有容乃大', + title: '交互专家', + group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', + tags: [ + { key: '0', label: '很有想法的' }, + { key: '1', label: '专注设计' }, + { key: '2', label: '辣~' }, + { key: '3', label: '大长腿' }, + { key: '4', label: '川妹子' }, + { key: '5', label: '海纳百川' }, + ], + notifyCount: 12, + unreadCount: 11, + notice: [], + country: 'China', + geographic: { + province: { label: '浙江省', key: '330000' }, + city: { label: '杭州市', key: '330100' }, + }, + address: '西湖区工专路 77 号', + phone: '0752-268888888', + }, + }); +}); + +export default app; diff --git a/cloudflare-worker/src/routes/monitor.ts b/cloudflare-worker/src/routes/monitor.ts index b34d0322..168bd755 100644 --- a/cloudflare-worker/src/routes/monitor.ts +++ b/cloudflare-worker/src/routes/monitor.ts @@ -15,4 +15,94 @@ app.get('/tags', (c) => { }); }); +// Simplified map-geo data (GeoJSON FeatureCollection) +app.get('/map-geo', (c) => { + return c.json({ + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + id: 1, + geometry: { + type: 'Point', + coordinates: [116.4074, 39.9042], + }, + properties: { + name: '北京', + value: 100, + }, + }, + { + type: 'Feature', + id: 2, + geometry: { + type: 'Point', + coordinates: [121.4737, 31.2304], + }, + properties: { + name: '上海', + value: 80, + }, + }, + { + type: 'Feature', + id: 3, + geometry: { + type: 'Point', + coordinates: [113.2644, 23.1291], + }, + properties: { + name: '广州', + value: 70, + }, + }, + { + type: 'Feature', + id: 4, + geometry: { + type: 'Point', + coordinates: [114.0579, 22.5431], + }, + properties: { + name: '深圳', + value: 65, + }, + }, + { + type: 'Feature', + id: 5, + geometry: { + type: 'Point', + coordinates: [120.1551, 30.2741], + }, + properties: { + name: '杭州', + value: 50, + }, + }, + ], + }); +}); + +// Simplified map-grid data +app.get('/map-grid', (c) => { + const features = []; + for (let i = 0; i < 50; i++) { + features.push({ + type: 'Feature', + properties: { + value: Math.floor(Math.random() * 100), + }, + geometry: { + type: 'Point', + coordinates: [-180 + (i % 10) * 36, 90 - Math.floor(i / 10) * 18], + }, + }); + } + return c.json({ + type: 'FeatureCollection', + features, + }); +}); + export default app; diff --git a/cloudflare-worker/src/routes/profile.ts b/cloudflare-worker/src/routes/profile.ts new file mode 100644 index 00000000..008e4158 --- /dev/null +++ b/cloudflare-worker/src/routes/profile.ts @@ -0,0 +1,169 @@ +import { Hono } from 'hono'; + +const basicGoods = [ + { + id: '1234561', + name: '矿泉水 550ml', + barcode: '12421432143214321', + price: '2.00', + num: '1', + amount: '2.00', + }, + { + id: '1234562', + name: '凉茶 300ml', + barcode: '12421432143214322', + price: '3.00', + num: '2', + amount: '6.00', + }, + { + id: '1234563', + name: '好吃的薯片', + barcode: '12421432143214323', + price: '7.00', + num: '4', + amount: '28.00', + }, + { + id: '1234564', + name: '特别好吃的蛋卷', + barcode: '12421432143214324', + price: '8.50', + num: '3', + amount: '25.50', + }, +]; + +const basicProgress = [ + { + key: '1', + time: '2017-10-01 14:10', + rate: '联系客户', + status: 'processing', + operator: '取货员 ID1234', + cost: '5mins', + }, + { + key: '2', + time: '2017-10-01 14:05', + rate: '取货员出发', + status: 'success', + operator: '取货员 ID1234', + cost: '1h', + }, + { + key: '3', + time: '2017-10-01 13:05', + rate: '取货员接单', + status: 'success', + operator: '取货员 ID1234', + cost: '5mins', + }, + { + key: '4', + time: '2017-10-01 13:00', + rate: '申请审批通过', + status: 'success', + operator: '系统', + cost: '1h', + }, + { + key: '5', + time: '2017-10-01 12:00', + rate: '发起退货申请', + status: 'success', + operator: '用户', + cost: '5mins', + }, +]; + +const advancedOperation1 = [ + { + key: 'op1', + type: '订购关系生效', + name: '曲丽丽', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, + { + key: 'op2', + type: '财务复审', + name: '付小小', + status: 'reject', + updatedAt: '2017-10-03 19:23:12', + memo: '不通过原因', + }, + { + key: 'op3', + type: '部门初审', + name: '周毛毛', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, + { + key: 'op4', + type: '提交订单', + name: '林东东', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '很棒', + }, + { + key: 'op5', + type: '创建订单', + name: '汗牙牙', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, +]; + +const advancedOperation2 = [ + { + key: 'op1', + type: '订购关系生效', + name: '曲丽丽', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, +]; + +const advancedOperation3 = [ + { + key: 'op1', + type: '创建订单', + name: '汗牙牙', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, +]; + +const app = new Hono(); + +// GET /api/profile/basic +app.get('/basic', (c) => { + return c.json({ + data: { + basicProgress, + basicGoods, + }, + }); +}); + +// GET /api/profile/advanced +app.get('/advanced', (c) => { + return c.json({ + data: { + advancedOperation1, + advancedOperation2, + advancedOperation3, + }, + }); +}); + +export default app; diff --git a/cloudflare-worker/src/routes/settings.ts b/cloudflare-worker/src/routes/settings.ts new file mode 100644 index 00000000..dd26622f --- /dev/null +++ b/cloudflare-worker/src/routes/settings.ts @@ -0,0 +1,38 @@ +import { Hono } from 'hono'; + +const app = new Hono(); + +// GET /api/accountSettingCurrentUser +app.get('/accountSettingCurrentUser', (c) => { + return c.json({ + data: { + name: 'Serati Ma', + avatar: + 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', + userid: '00000001', + email: 'antdesign@alipay.com', + signature: '海纳百川,有容乃大', + title: '交互专家', + group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', + tags: [ + { key: '0', label: '很有想法的' }, + { key: '1', label: '专注设计' }, + { key: '2', label: '辣~' }, + { key: '3', label: '大长腿' }, + { key: '4', label: '川妹子' }, + { key: '5', label: '海纳百川' }, + ], + notifyCount: 12, + unreadCount: 11, + country: 'China', + geographic: { + province: { label: '浙江省', key: '330000' }, + city: { label: '杭州市', key: '330100' }, + }, + address: '西湖区工专路 77 号', + phone: '0752-268888888', + }, + }); +}); + +export default app;