= ({ overlayClassName: cls, ...restProps }) => {
23 | const { styles } = useStyles();
24 | return ;
25 | };
26 |
27 | export default HeaderDropdown;
28 |
--------------------------------------------------------------------------------
/ant-react/src/components/RightContent/index.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionCircleOutlined } from '@ant-design/icons';
2 | import { SelectLang as UmiSelectLang } from '@umijs/max';
3 | import React from 'react';
4 |
5 | export type SiderTheme = 'light' | 'dark';
6 |
7 | export const SelectLang = () => {
8 | return (
9 |
14 | );
15 | };
16 |
17 | export const Question = () => {
18 | return (
19 | {
25 | window.open('https://pro.ant.design/docs/getting-started');
26 | }}
27 | >
28 |
29 |
30 | );
31 | };
32 |
--------------------------------------------------------------------------------
/ant-react/src/components/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 这个文件作为组件的目录
3 | * 目的是统一管理对外输出的组件,方便分类
4 | */
5 | /**
6 | * 布局组件
7 | */
8 | import Footer from './Footer';
9 | import { Question, SelectLang } from './RightContent';
10 | import { AvatarDropdown, AvatarName } from './RightContent/AvatarDropdown';
11 |
12 | export { Footer, Question, SelectLang, AvatarDropdown, AvatarName };
13 |
--------------------------------------------------------------------------------
/ant-react/src/locales/bn-BD.ts:
--------------------------------------------------------------------------------
1 | import component from './bn-BD/component';
2 | import globalHeader from './bn-BD/globalHeader';
3 | import menu from './bn-BD/menu';
4 | import pages from './bn-BD/pages';
5 | import pwa from './bn-BD/pwa';
6 | import settingDrawer from './bn-BD/settingDrawer';
7 | import settings from './bn-BD/settings';
8 |
9 | export default {
10 | 'navBar.lang': 'ভাষা',
11 | 'layout.user.link.help': 'সহায়তা',
12 | 'layout.user.link.privacy': 'গোপনীয়তা',
13 | 'layout.user.link.terms': 'শর্তাদি',
14 | 'app.preview.down.block': 'আপনার স্থানীয় প্রকল্পে এই পৃষ্ঠাটি ডাউনলোড করুন',
15 | 'app.welcome.link.fetch-blocks': 'সমস্ত ব্লক পান',
16 | 'app.welcome.link.block-list':
17 | '`block` ডেভেলপমেন্ট এর উপর ভিত্তি করে দ্রুত স্ট্যান্ডার্ড, পৃষ্ঠাসমূহ তৈরি করুন।',
18 | ...globalHeader,
19 | ...menu,
20 | ...settingDrawer,
21 | ...settings,
22 | ...pwa,
23 | ...component,
24 | ...pages,
25 | };
26 |
--------------------------------------------------------------------------------
/ant-react/src/locales/bn-BD/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': 'বিস্তৃত',
3 | 'component.tagSelect.collapse': 'সঙ্কুচিত',
4 | 'component.tagSelect.all': 'সব',
5 | };
6 |
--------------------------------------------------------------------------------
/ant-react/src/locales/bn-BD/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': 'অনুসন্ধান করুন',
3 | 'component.globalHeader.search.example1': 'অনুসন্ধান উদাহরণ ১',
4 | 'component.globalHeader.search.example2': 'অনুসন্ধান উদাহরণ ২',
5 | 'component.globalHeader.search.example3': 'অনুসন্ধান উদাহরণ ৩',
6 | 'component.globalHeader.help': 'সহায়তা',
7 | 'component.globalHeader.notification': 'বিজ্ঞপ্তি',
8 | 'component.globalHeader.notification.empty': 'আপনি সমস্ত বিজ্ঞপ্তি দেখেছেন।',
9 | 'component.globalHeader.message': 'বার্তা',
10 | 'component.globalHeader.message.empty': 'আপনি সমস্ত বার্তা দেখেছেন।',
11 | 'component.globalHeader.event': 'ঘটনা',
12 | 'component.globalHeader.event.empty': 'আপনি সমস্ত ইভেন্ট দেখেছেন।',
13 | 'component.noticeIcon.clear': 'সাফ',
14 | 'component.noticeIcon.cleared': 'সাফ করা হয়েছে',
15 | 'component.noticeIcon.empty': 'বিজ্ঞপ্তি নেই',
16 | 'component.noticeIcon.view-more': 'আরো দেখুন',
17 | };
18 |
--------------------------------------------------------------------------------
/ant-react/src/locales/bn-BD/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'আপনি এখন অফলাইন',
3 | 'app.pwa.serviceworker.updated': 'নতুন সামগ্রী উপলব্ধ',
4 | 'app.pwa.serviceworker.updated.hint':
5 | 'বর্তমান পৃষ্ঠাটি পুনরায় লোড করতে দয়া করে "রিফ্রেশ" বোতাম টিপুন',
6 | 'app.pwa.serviceworker.updated.ok': 'রিফ্রেশ',
7 | };
8 |
--------------------------------------------------------------------------------
/ant-react/src/locales/en-US.ts:
--------------------------------------------------------------------------------
1 | import component from './en-US/component';
2 | import globalHeader from './en-US/globalHeader';
3 | import menu from './en-US/menu';
4 | import pages from './en-US/pages';
5 | import pwa from './en-US/pwa';
6 | import settingDrawer from './en-US/settingDrawer';
7 | import settings from './en-US/settings';
8 |
9 | export default {
10 | 'navBar.lang': 'Languages',
11 | 'layout.user.link.help': 'Help',
12 | 'layout.user.link.privacy': 'Privacy',
13 | 'layout.user.link.terms': 'Terms',
14 | 'app.preview.down.block': 'Download this page to your local project',
15 | 'app.welcome.link.fetch-blocks': 'Get all block',
16 | 'app.welcome.link.block-list': 'Quickly build standard, pages based on `block` development',
17 | ...globalHeader,
18 | ...menu,
19 | ...settingDrawer,
20 | ...settings,
21 | ...pwa,
22 | ...component,
23 | ...pages,
24 | };
25 |
--------------------------------------------------------------------------------
/ant-react/src/locales/en-US/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': 'Expand',
3 | 'component.tagSelect.collapse': 'Collapse',
4 | 'component.tagSelect.all': 'All',
5 | };
6 |
--------------------------------------------------------------------------------
/ant-react/src/locales/en-US/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': 'Search',
3 | 'component.globalHeader.search.example1': 'Search example 1',
4 | 'component.globalHeader.search.example2': 'Search example 2',
5 | 'component.globalHeader.search.example3': 'Search example 3',
6 | 'component.globalHeader.help': 'Help',
7 | 'component.globalHeader.notification': 'Notification',
8 | 'component.globalHeader.notification.empty': 'You have viewed all notifications.',
9 | 'component.globalHeader.message': 'Message',
10 | 'component.globalHeader.message.empty': 'You have viewed all messsages.',
11 | 'component.globalHeader.event': 'Event',
12 | 'component.globalHeader.event.empty': 'You have viewed all events.',
13 | 'component.noticeIcon.clear': 'Clear',
14 | 'component.noticeIcon.cleared': 'Cleared',
15 | 'component.noticeIcon.empty': 'No notifications',
16 | 'component.noticeIcon.view-more': 'View more',
17 | };
18 |
--------------------------------------------------------------------------------
/ant-react/src/locales/en-US/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'You are offline now',
3 | 'app.pwa.serviceworker.updated': 'New content is available',
4 | 'app.pwa.serviceworker.updated.hint': 'Please press the "Refresh" button to reload current page',
5 | 'app.pwa.serviceworker.updated.ok': 'Refresh',
6 | };
7 |
--------------------------------------------------------------------------------
/ant-react/src/locales/fa-IR.ts:
--------------------------------------------------------------------------------
1 | import component from './fa-IR/component';
2 | import globalHeader from './fa-IR/globalHeader';
3 | import menu from './fa-IR/menu';
4 | import pages from './fa-IR/pages';
5 | import pwa from './fa-IR/pwa';
6 | import settingDrawer from './fa-IR/settingDrawer';
7 | import settings from './fa-IR/settings';
8 |
9 | export default {
10 | 'navBar.lang': 'زبان ها ',
11 | 'layout.user.link.help': 'کمک',
12 | 'layout.user.link.privacy': 'حریم خصوصی',
13 | 'layout.user.link.terms': 'مقررات',
14 | 'app.preview.down.block': 'این صفحه را در پروژه محلی خود بارگیری کنید',
15 | 'app.welcome.link.fetch-blocks': 'دریافت تمام بلوک',
16 | 'app.welcome.link.block-list': 'به سرعت صفحات استاندارد مبتنی بر توسعه "بلوک" را بسازید',
17 | ...globalHeader,
18 | ...menu,
19 | ...settingDrawer,
20 | ...settings,
21 | ...pwa,
22 | ...component,
23 | ...pages,
24 | };
25 |
--------------------------------------------------------------------------------
/ant-react/src/locales/fa-IR/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': 'باز',
3 | 'component.tagSelect.collapse': 'بسته ',
4 | 'component.tagSelect.all': 'همه',
5 | };
6 |
--------------------------------------------------------------------------------
/ant-react/src/locales/fa-IR/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': 'جستجو ',
3 | 'component.globalHeader.search.example1': 'مثال 1 را جستجو کنید',
4 | 'component.globalHeader.search.example2': 'مثال 2 را جستجو کنید',
5 | 'component.globalHeader.search.example3': 'مثال 3 را جستجو کنید',
6 | 'component.globalHeader.help': 'کمک',
7 | 'component.globalHeader.notification': 'اعلان',
8 | 'component.globalHeader.notification.empty': 'شما همه اعلان ها را مشاهده کرده اید.',
9 | 'component.globalHeader.message': 'پیام',
10 | 'component.globalHeader.message.empty': 'شما همه پیام ها را مشاهده کرده اید.',
11 | 'component.globalHeader.event': 'رویداد',
12 | 'component.globalHeader.event.empty': 'شما همه رویدادها را مشاهده کرده اید.',
13 | 'component.noticeIcon.clear': 'پاک کردن',
14 | 'component.noticeIcon.cleared': 'پاک شد',
15 | 'component.noticeIcon.empty': 'بدون اعلان',
16 | 'component.noticeIcon.view-more': 'نمایش بیشتر',
17 | };
18 |
--------------------------------------------------------------------------------
/ant-react/src/locales/fa-IR/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'شما اکنون آفلاین هستید',
3 | 'app.pwa.serviceworker.updated': 'مطالب جدید در دسترس است',
4 | 'app.pwa.serviceworker.updated.hint':
5 | 'لطفاً برای بارگیری مجدد صفحه فعلی ، دکمه "تازه سازی" را فشار دهید',
6 | 'app.pwa.serviceworker.updated.ok': 'تازه سازی',
7 | };
8 |
--------------------------------------------------------------------------------
/ant-react/src/locales/id-ID.ts:
--------------------------------------------------------------------------------
1 | import component from './id-ID/component';
2 | import globalHeader from './id-ID/globalHeader';
3 | import menu from './id-ID/menu';
4 | import pages from './id-ID/pages';
5 | import pwa from './id-ID/pwa';
6 | import settingDrawer from './id-ID/settingDrawer';
7 | import settings from './id-ID/settings';
8 |
9 | export default {
10 | 'navbar.lang': 'Bahasa',
11 | 'layout.user.link.help': 'Bantuan',
12 | 'layout.user.link.privacy': 'Privasi',
13 | 'layout.user.link.terms': 'Ketentuan',
14 | 'app.preview.down.block': 'Unduh halaman ini dalam projek lokal anda',
15 | 'app.welcome.link.fetch-blocks': 'Dapatkan semua blok',
16 | 'app.welcome.link.block-list':
17 | 'Buat standar dengan cepat, halaman-halaman berdasarkan pengembangan `block`',
18 | ...globalHeader,
19 | ...menu,
20 | ...settingDrawer,
21 | ...settings,
22 | ...pwa,
23 | ...component,
24 | ...pages,
25 | };
26 |
--------------------------------------------------------------------------------
/ant-react/src/locales/id-ID/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': 'Perluas',
3 | 'component.tagSelect.collapse': 'Lipat',
4 | 'component.tagSelect.all': 'Semua',
5 | };
6 |
--------------------------------------------------------------------------------
/ant-react/src/locales/id-ID/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': 'Pencarian',
3 | 'component.globalHeader.search.example1': 'Contoh 1 Pencarian',
4 | 'component.globalHeader.search.example2': 'Contoh 2 Pencarian',
5 | 'component.globalHeader.search.example3': 'Contoh 3 Pencarian',
6 | 'component.globalHeader.help': 'Bantuan',
7 | 'component.globalHeader.notification': 'Notifikasi',
8 | 'component.globalHeader.notification.empty': 'Anda telah membaca semua notifikasi',
9 | 'component.globalHeader.message': 'Pesan',
10 | 'component.globalHeader.message.empty': 'Anda telah membaca semua pesan.',
11 | 'component.globalHeader.event': 'Acara',
12 | 'component.globalHeader.event.empty': 'Anda telah melihat semua acara.',
13 | 'component.noticeIcon.clear': 'Kosongkan',
14 | 'component.noticeIcon.cleared': 'Berhasil dikosongkan',
15 | 'component.noticeIcon.empty': 'Tidak ada pemberitahuan',
16 | 'component.noticeIcon.view-more': 'Melihat lebih',
17 | };
18 |
--------------------------------------------------------------------------------
/ant-react/src/locales/id-ID/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'Koneksi anda terputus',
3 | 'app.pwa.serviceworker.updated': 'Konten baru sudah tersedia',
4 | 'app.pwa.serviceworker.updated.hint':
5 | 'Silahkan klik tombol "Refresh" untuk memuat ulang halaman ini',
6 | 'app.pwa.serviceworker.updated.ok': 'Memuat ulang',
7 | };
8 |
--------------------------------------------------------------------------------
/ant-react/src/locales/ja-JP.ts:
--------------------------------------------------------------------------------
1 | import component from './ja-JP/component';
2 | import globalHeader from './ja-JP/globalHeader';
3 | import menu from './ja-JP/menu';
4 | import pages from './ja-JP/pages';
5 | import pwa from './ja-JP/pwa';
6 | import settingDrawer from './ja-JP/settingDrawer';
7 | import settings from './ja-JP/settings';
8 |
9 | export default {
10 | 'navBar.lang': '言語',
11 | 'layout.user.link.help': 'ヘルプ',
12 | 'layout.user.link.privacy': 'プライバシー',
13 | 'layout.user.link.terms': '利用規約',
14 | 'app.preview.down.block': 'このページをローカルプロジェクトにダウンロードしてください',
15 | 'app.welcome.link.fetch-blocks': '',
16 | 'app.welcome.link.block-list': '',
17 | ...globalHeader,
18 | ...menu,
19 | ...settingDrawer,
20 | ...settings,
21 | ...pwa,
22 | ...component,
23 | ...pages,
24 | };
25 |
--------------------------------------------------------------------------------
/ant-react/src/locales/ja-JP/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': '展開',
3 | 'component.tagSelect.collapse': '折りたたむ',
4 | 'component.tagSelect.all': 'すべて',
5 | };
6 |
--------------------------------------------------------------------------------
/ant-react/src/locales/ja-JP/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': '検索',
3 | 'component.globalHeader.search.example1': '検索例1',
4 | 'component.globalHeader.search.example2': '検索例2',
5 | 'component.globalHeader.search.example3': '検索例3',
6 | 'component.globalHeader.help': 'ヘルプ',
7 | 'component.globalHeader.notification': '通知',
8 | 'component.globalHeader.notification.empty': 'すべての通知を表示しました。',
9 | 'component.globalHeader.message': 'メッセージ',
10 | 'component.globalHeader.message.empty': 'すべてのメッセージを表示しました。',
11 | 'component.globalHeader.event': 'イベント',
12 | 'component.globalHeader.event.empty': 'すべてのイベントを表示しました。',
13 | 'component.noticeIcon.clear': 'クリア',
14 | 'component.noticeIcon.cleared': 'クリア済み',
15 | 'component.noticeIcon.empty': '通知なし',
16 | 'component.noticeIcon.view-more': 'もっと見る',
17 | };
18 |
--------------------------------------------------------------------------------
/ant-react/src/locales/ja-JP/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'あなたは今オフラインです',
3 | 'app.pwa.serviceworker.updated': '新しいコンテンツが利用可能です',
4 | 'app.pwa.serviceworker.updated.hint':
5 | '現在のページをリロードするには、「更新」ボタンを押してください',
6 | 'app.pwa.serviceworker.updated.ok': 'リフレッシュ',
7 | };
8 |
--------------------------------------------------------------------------------
/ant-react/src/locales/pt-BR.ts:
--------------------------------------------------------------------------------
1 | import component from './pt-BR/component';
2 | import globalHeader from './pt-BR/globalHeader';
3 | import menu from './pt-BR/menu';
4 | import pages from './pt-BR/pages';
5 | import pwa from './pt-BR/pwa';
6 | import settingDrawer from './pt-BR/settingDrawer';
7 | import settings from './pt-BR/settings';
8 |
9 | export default {
10 | 'navBar.lang': 'Idiomas',
11 | 'layout.user.link.help': 'ajuda',
12 | 'layout.user.link.privacy': 'política de privacidade',
13 | 'layout.user.link.terms': 'termos de serviços',
14 | 'app.preview.down.block': 'Download this page to your local project',
15 | ...globalHeader,
16 | ...menu,
17 | ...settingDrawer,
18 | ...settings,
19 | ...pwa,
20 | ...component,
21 | ...pages,
22 | };
23 |
--------------------------------------------------------------------------------
/ant-react/src/locales/pt-BR/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': 'Expandir',
3 | 'component.tagSelect.collapse': 'Diminuir',
4 | 'component.tagSelect.all': 'Todas',
5 | };
6 |
--------------------------------------------------------------------------------
/ant-react/src/locales/pt-BR/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': 'Busca',
3 | 'component.globalHeader.search.example1': 'Exemplo de busca 1',
4 | 'component.globalHeader.search.example2': 'Exemplo de busca 2',
5 | 'component.globalHeader.search.example3': 'Exemplo de busca 3',
6 | 'component.globalHeader.help': 'Ajuda',
7 | 'component.globalHeader.notification': 'Notificação',
8 | 'component.globalHeader.notification.empty': 'Você visualizou todas as notificações.',
9 | 'component.globalHeader.message': 'Mensagem',
10 | 'component.globalHeader.message.empty': 'Você visualizou todas as mensagens.',
11 | 'component.globalHeader.event': 'Evento',
12 | 'component.globalHeader.event.empty': 'Você visualizou todos os eventos.',
13 | 'component.noticeIcon.clear': 'Limpar',
14 | 'component.noticeIcon.cleared': 'Limpo',
15 | 'component.noticeIcon.empty': 'Sem notificações',
16 | 'component.noticeIcon.view-more': 'Veja mais',
17 | };
18 |
--------------------------------------------------------------------------------
/ant-react/src/locales/pt-BR/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': 'Você está offline agora',
3 | 'app.pwa.serviceworker.updated': 'Novo conteúdo está disponível',
4 | 'app.pwa.serviceworker.updated.hint':
5 | 'Por favor, pressione o botão "Atualizar" para recarregar a página atual',
6 | 'app.pwa.serviceworker.updated.ok': 'Atualizar',
7 | };
8 |
--------------------------------------------------------------------------------
/ant-react/src/locales/zh-CN.ts:
--------------------------------------------------------------------------------
1 | import component from './zh-CN/component';
2 | import globalHeader from './zh-CN/globalHeader';
3 | import menu from './zh-CN/menu';
4 | import pages from './zh-CN/pages';
5 | import pwa from './zh-CN/pwa';
6 | import settingDrawer from './zh-CN/settingDrawer';
7 | import settings from './zh-CN/settings';
8 |
9 | export default {
10 | 'navBar.lang': '语言',
11 | 'layout.user.link.help': '帮助',
12 | 'layout.user.link.privacy': '隐私',
13 | 'layout.user.link.terms': '条款',
14 | 'app.preview.down.block': '下载此页面到本地项目',
15 | 'app.welcome.link.fetch-blocks': '获取全部区块',
16 | 'app.welcome.link.block-list': '基于 block 开发,快速构建标准页面',
17 | ...pages,
18 | ...globalHeader,
19 | ...menu,
20 | ...settingDrawer,
21 | ...settings,
22 | ...pwa,
23 | ...component,
24 | };
25 |
--------------------------------------------------------------------------------
/ant-react/src/locales/zh-CN/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': '展开',
3 | 'component.tagSelect.collapse': '收起',
4 | 'component.tagSelect.all': '全部',
5 | };
6 |
--------------------------------------------------------------------------------
/ant-react/src/locales/zh-CN/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': '站内搜索',
3 | 'component.globalHeader.search.example1': '搜索提示一',
4 | 'component.globalHeader.search.example2': '搜索提示二',
5 | 'component.globalHeader.search.example3': '搜索提示三',
6 | 'component.globalHeader.help': '使用文档',
7 | 'component.globalHeader.notification': '通知',
8 | 'component.globalHeader.notification.empty': '你已查看所有通知',
9 | 'component.globalHeader.message': '消息',
10 | 'component.globalHeader.message.empty': '您已读完所有消息',
11 | 'component.globalHeader.event': '待办',
12 | 'component.globalHeader.event.empty': '你已完成所有待办',
13 | 'component.noticeIcon.clear': '清空',
14 | 'component.noticeIcon.cleared': '清空了',
15 | 'component.noticeIcon.empty': '暂无数据',
16 | 'component.noticeIcon.view-more': '查看更多',
17 | };
18 |
--------------------------------------------------------------------------------
/ant-react/src/locales/zh-CN/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': '当前处于离线状态',
3 | 'app.pwa.serviceworker.updated': '有新内容',
4 | 'app.pwa.serviceworker.updated.hint': '请点击“刷新”按钮或者手动刷新页面',
5 | 'app.pwa.serviceworker.updated.ok': '刷新',
6 | };
7 |
--------------------------------------------------------------------------------
/ant-react/src/locales/zh-TW.ts:
--------------------------------------------------------------------------------
1 | import component from './zh-TW/component';
2 | import globalHeader from './zh-TW/globalHeader';
3 | import menu from './zh-TW/menu';
4 | import pages from './zh-TW/pages';
5 | import pwa from './zh-TW/pwa';
6 | import settingDrawer from './zh-TW/settingDrawer';
7 | import settings from './zh-TW/settings';
8 |
9 | export default {
10 | 'navBar.lang': '語言',
11 | 'layout.user.link.help': '幫助',
12 | 'layout.user.link.privacy': '隱私',
13 | 'layout.user.link.terms': '條款',
14 | 'app.preview.down.block': '下載此頁面到本地項目',
15 | ...pages,
16 | ...globalHeader,
17 | ...menu,
18 | ...settingDrawer,
19 | ...settings,
20 | ...pwa,
21 | ...component,
22 | };
23 |
--------------------------------------------------------------------------------
/ant-react/src/locales/zh-TW/component.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.tagSelect.expand': '展開',
3 | 'component.tagSelect.collapse': '收起',
4 | 'component.tagSelect.all': '全部',
5 | };
6 |
--------------------------------------------------------------------------------
/ant-react/src/locales/zh-TW/globalHeader.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'component.globalHeader.search': '站內搜索',
3 | 'component.globalHeader.search.example1': '搜索提示壹',
4 | 'component.globalHeader.search.example2': '搜索提示二',
5 | 'component.globalHeader.search.example3': '搜索提示三',
6 | 'component.globalHeader.help': '使用手冊',
7 | 'component.globalHeader.notification': '通知',
8 | 'component.globalHeader.notification.empty': '妳已查看所有通知',
9 | 'component.globalHeader.message': '消息',
10 | 'component.globalHeader.message.empty': '您已讀完所有消息',
11 | 'component.globalHeader.event': '待辦',
12 | 'component.globalHeader.event.empty': '妳已完成所有待辦',
13 | 'component.noticeIcon.clear': '清空',
14 | 'component.noticeIcon.cleared': '清空了',
15 | 'component.noticeIcon.empty': '暫無資料',
16 | 'component.noticeIcon.view-more': '查看更多',
17 | };
18 |
--------------------------------------------------------------------------------
/ant-react/src/locales/zh-TW/pwa.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | 'app.pwa.offline': '當前處於離線狀態',
3 | 'app.pwa.serviceworker.updated': '有新內容',
4 | 'app.pwa.serviceworker.updated.hint': '請點擊“刷新”按鈕或者手動刷新頁面',
5 | 'app.pwa.serviceworker.updated.ok': '刷新',
6 | };
7 |
--------------------------------------------------------------------------------
/ant-react/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Ant Design Pro",
3 | "short_name": "Ant Design Pro",
4 | "display": "standalone",
5 | "start_url": "./?utm_source=homescreen",
6 | "theme_color": "#002140",
7 | "background_color": "#001529",
8 | "icons": [
9 | {
10 | "src": "icons/icon-192x192.png",
11 | "sizes": "192x192"
12 | },
13 | {
14 | "src": "icons/icon-128x128.png",
15 | "sizes": "128x128"
16 | },
17 | {
18 | "src": "icons/icon-512x512.png",
19 | "sizes": "512x512"
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/ant-react/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import { history, useIntl } from '@umijs/max';
2 | import { Button, Result } from 'antd';
3 | import React from 'react';
4 |
5 | const NoFoundPage: React.FC = () => (
6 | history.push('/')}>
12 | {useIntl().formatMessage({ id: 'pages.404.buttonText' })}
13 |
14 | }
15 | />
16 | );
17 |
18 | export default NoFoundPage;
19 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Data/ScriptParam/ScriptNameShow.tsx:
--------------------------------------------------------------------------------
1 | import { scriptWaringById } from '@/services/ant-design-pro/api';
2 | import React, { useEffect, useState } from 'react';
3 |
4 | export type Props = {
5 | id: string;
6 | };
7 |
8 | const ScriptNameShow: React.FC = (props) => {
9 | const [data, setData] = useState('');
10 | useEffect(() => {
11 | const fetchData = async () => {
12 | const response = await scriptWaringById(props.id);
13 | setData(response.data.name);
14 | };
15 |
16 | fetchData();
17 |
18 | // 清理函数,用于取消异步操作或清理副作用
19 | return () => {
20 | // 如果有需要取消请求的逻辑,可以在这里实现
21 | };
22 | }, [props.id]);
23 |
24 | return (
25 | <>
26 | {data || '-'}
27 | >
28 | );
29 | };
30 |
31 | export default ScriptNameShow;
32 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Data/Signal/SignalNameShow.tsx:
--------------------------------------------------------------------------------
1 | import { signalById } from '@/services/ant-design-pro/api';
2 | import React, { useEffect, useState } from 'react';
3 |
4 | export type Props = {
5 | id: string;
6 | };
7 |
8 | const SignalNameShow: React.FC = (props) => {
9 | const [data, setData] = useState('');
10 | useEffect(() => {
11 | const fetchData = async () => {
12 | const response = await signalById(props.id);
13 | setData(response.data.name + ' (' + response.data.alias + ') ');
14 | };
15 |
16 | fetchData();
17 |
18 | // 清理函数,用于取消异步操作或清理副作用
19 | return () => {
20 | // 如果有需要取消请求的逻辑,可以在这里实现
21 | };
22 | }, [props.id]);
23 |
24 | return (
25 | <>
26 | {data || '-'}
27 | >
28 | );
29 | };
30 |
31 | export default SignalNameShow;
32 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Data/SignalVis/index.tsx:
--------------------------------------------------------------------------------
1 | import {PageContainer} from '@ant-design/pro-components';
2 | import React from 'react';
3 | import {Card} from 'antd';
4 | import {useIntl} from '@umijs/max';
5 |
6 |
7 | const Admin: React.FC = () => {
8 | const intl = useIntl();
9 | return (
12 |
13 |
14 | );
15 | };
16 |
17 | export default Admin;
18 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Lifecycle/OperationList/OperationList.tsx:
--------------------------------------------------------------------------------
1 | import {PageContainer} from '@ant-design/pro-components';
2 | import React from 'react';
3 | import {Card} from 'antd';
4 | import {useIntl} from '@umijs/max';
5 |
6 |
7 | const Admin: React.FC = () => {
8 | const intl = useIntl();
9 | return (
12 |
13 |
14 | );
15 | };
16 |
17 | export default Admin;
18 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Lifecycle/ProduceList/ProduceList.tsx:
--------------------------------------------------------------------------------
1 | import {PageContainer} from '@ant-design/pro-components';
2 | import React from 'react';
3 | import {Card} from 'antd';
4 | import {useIntl} from '@umijs/max';
5 |
6 |
7 | const Admin: React.FC = () => {
8 | const intl = useIntl();
9 | return (
12 |
13 |
14 | );
15 | };
16 |
17 | export default Admin;
18 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Protocol/coap/nodes/index.tsx:
--------------------------------------------------------------------------------
1 | import {PageContainer} from '@ant-design/pro-components';
2 | import React from 'react';
3 | import {Card} from 'antd';
4 | import {useIntl} from '@umijs/max';
5 |
6 |
7 | const Admin: React.FC = () => {
8 | const intl = useIntl();
9 | return (
12 |
13 |
14 | );
15 | };
16 |
17 | export default Admin;
18 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Protocol/http/nodes/index.tsx:
--------------------------------------------------------------------------------
1 | import {PageContainer} from '@ant-design/pro-components';
2 | import React from 'react';
3 | import {Card} from 'antd';
4 | import {useIntl} from '@umijs/max';
5 |
6 |
7 | const Admin: React.FC = () => {
8 | const intl = useIntl();
9 | return (
12 |
13 |
14 | );
15 | };
16 |
17 | export default Admin;
18 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Protocol/mqtt/nodes/index.tsx:
--------------------------------------------------------------------------------
1 | import {PageContainer} from '@ant-design/pro-components';
2 | import React from 'react';
3 | import {Card} from 'antd';
4 | import {useIntl} from '@umijs/max';
5 |
6 |
7 | const Admin: React.FC = () => {
8 | const intl = useIntl();
9 | return (
12 |
13 |
14 | );
15 | };
16 |
17 | export default Admin;
18 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Protocol/tcp/nodes/index.tsx:
--------------------------------------------------------------------------------
1 | import {PageContainer} from '@ant-design/pro-components';
2 | import React from 'react';
3 | import {Card} from 'antd';
4 | import {useIntl} from '@umijs/max';
5 |
6 |
7 | const Admin: React.FC = () => {
8 | const intl = useIntl();
9 | return (
12 |
13 |
14 | );
15 | };
16 |
17 | export default Admin;
18 |
--------------------------------------------------------------------------------
/ant-react/src/pages/Protocol/ws/nodes/index.tsx:
--------------------------------------------------------------------------------
1 | import {PageContainer} from '@ant-design/pro-components';
2 | import React from 'react';
3 | import {Card} from 'antd';
4 | import {useIntl} from '@umijs/max';
5 |
6 |
7 | const Admin: React.FC = () => {
8 | const intl = useIntl();
9 | return (
12 |
13 |
14 | );
15 | };
16 |
17 | export default Admin;
18 |
--------------------------------------------------------------------------------
/ant-react/src/pages/dashboard/index.tsx:
--------------------------------------------------------------------------------
1 | import AlarmStatistics from '@/pages/dashboard/AlarmStatistics';
2 | import DeviceMap from '@/pages/dashboard/DeviceMap';
3 | import MessageList from '@/pages/dashboard/MessageList';
4 | import ProtocolStatsCards from '@/pages/dashboard/ProtocolStatsTable';
5 | import { Col, Row } from 'antd';
6 |
7 | const Dashboard = () => {
8 | return (
9 | <>
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | >
21 | );
22 | };
23 |
24 | export default Dashboard;
25 |
--------------------------------------------------------------------------------
/ant-react/src/services/ant-design-pro/common.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/ant-react/src/services/ant-design-pro/common.ts
--------------------------------------------------------------------------------
/ant-react/src/services/ant-design-pro/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 | // API 更新时间:
4 | // API 唯一标识:
5 | import * as api from './api';
6 | import * as login from './login';
7 | export default {
8 | api,
9 | login,
10 | };
11 |
--------------------------------------------------------------------------------
/ant-react/src/services/ant-design-pro/login.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 | import { request } from '@umijs/max';
4 |
5 | /** 发送验证码 POST /api/login/captcha */
6 | export async function getFakeCaptcha(
7 | params: {
8 | // query
9 | /** 手机号 */
10 | phone?: string;
11 | },
12 | options?: { [key: string]: any },
13 | ) {
14 | return request('/api/login/captcha', {
15 | method: 'GET',
16 | params: {
17 | ...params,
18 | },
19 | ...(options || {}),
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/ant-react/src/services/swagger/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | /* eslint-disable */
3 | // API 更新时间:
4 | // API 唯一标识:
5 | import * as pet from './pet';
6 | import * as store from './store';
7 | import * as user from './user';
8 | export default {
9 | pet,
10 | store,
11 | user,
12 | };
13 |
--------------------------------------------------------------------------------
/ant-react/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'slash2';
2 | declare module '*.css';
3 | declare module '*.less';
4 | declare module '*.scss';
5 | declare module '*.sass';
6 | declare module '*.svg';
7 | declare module '*.png';
8 | declare module '*.jpg';
9 | declare module '*.jpeg';
10 | declare module '*.gif';
11 | declare module '*.bmp';
12 | declare module '*.tiff';
13 | declare module 'omit.js';
14 | declare module 'numeral';
15 | declare module '@antv/data-set';
16 | declare module 'react-fittext';
17 | declare module 'bizcharts-plugin-slider';
18 | declare const APP_ENV: string;
19 |
20 | declare const REACT_APP_ENV: 'test' | 'dev' | 'pre' | false;
21 |
--------------------------------------------------------------------------------
/ant-react/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "esnext",
5 | "moduleResolution": "node",
6 | "importHelpers": true,
7 | "jsx": "preserve",
8 | "esModuleInterop": true,
9 | "sourceMap": true,
10 | "baseUrl": "./",
11 | "skipLibCheck": true,
12 | "experimentalDecorators": true,
13 | "strict": true,
14 | "resolveJsonModule": true,
15 | "allowSyntheticDefaultImports": true,
16 | "paths": {
17 | "@/*": ["./src/*"],
18 | "@@/*": ["./src/.umi/*"],
19 | "@@test/*": ["./src/.umi-test/*"]
20 | }
21 | },
22 | "include": ["./**/*.d.ts", "./**/*.ts", "./**/*.tsx"]
23 | }
24 |
--------------------------------------------------------------------------------
/ant-react/types/cache/cache.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/ant-react/types/cache/mock/mock.cache.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/ant-react/types/cache/mock/mock.cache.js
--------------------------------------------------------------------------------
/ant-vue/.commitlintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@commitlint/config-conventional"]
3 | }
--------------------------------------------------------------------------------
/ant-vue/.env.development:
--------------------------------------------------------------------------------
1 | NODE_ENV=development
2 | VITE_APP_ENV_NAME=开发环境
3 | # 静态文件路径
4 | VITE_BASE_URL=/iot
5 |
6 | VITE_APP_API_URL=http://localhost:8080
--------------------------------------------------------------------------------
/ant-vue/.env.docker:
--------------------------------------------------------------------------------
1 | NODE_ENV=docker
2 | # 静态文件路径
3 | VITE_BASE_URL=/
4 | VITE_APP_ENV_NAME=docker环境
5 | VITE_APP_API_URL=http://192.168.3.101:8005
6 | VITE_LOGIN=some
7 |
--------------------------------------------------------------------------------
/ant-vue/.env.production:
--------------------------------------------------------------------------------
1 | NODE_ENV=production
2 | # 静态文件路径
3 | VITE_BASE_URL=/iot
4 | VITE_APP_ENV_NAME=线上环境
5 | VITE_APP_API_URL=http://192.168.3.110:8080
6 | VITE_LOGIN=some
7 |
--------------------------------------------------------------------------------
/ant-vue/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | components.d.ts
4 | docs/.vitepress/cache
--------------------------------------------------------------------------------
/ant-vue/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "tabWidth": 2,
4 | "printWidth": 200,
5 | "singleQuote": false,
6 | "endOfLine": "auto"
7 | }
--------------------------------------------------------------------------------
/ant-vue/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "simple-import-sort/imports": "off"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/ant-vue/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": false,
3 | "editor.defaultFormatter": "esbenp.prettier-vscode",
4 | "editor.codeActionsOnSave": {
5 | "source.fixAll": "explicit"
6 | },
7 | "svg.preview.background": "transparent"
8 | }
9 |
--------------------------------------------------------------------------------
/ant-vue/env.d.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | ///
3 |
4 | declare interface Window {
5 | [propName: string]: any
6 | }
7 |
8 | declare module "vue-grid-layout";
--------------------------------------------------------------------------------
/ant-vue/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Go物联网
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ant-vue/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
41 |
--------------------------------------------------------------------------------
/ant-vue/src/components/echarts/index.d.ts:
--------------------------------------------------------------------------------
1 | export { default } from './index.vue';
2 |
--------------------------------------------------------------------------------
/ant-vue/src/components/index.ts:
--------------------------------------------------------------------------------
1 | // 统一echarts图表
2 | export { default as YcECharts } from "./echarts/index.vue";
3 | export { default as CalculateSelect } from "./select/CalculateSelect.vue";
4 | export { default as MqttModSelect } from "./select/MqttModSelect.vue";
5 | export { default as MqttSelect } from "./select/MqttSelect.vue";
6 | export { default as SignalModeSelect } from "./select/SignalModeSelect.vue";
7 | export { default as SignalSelect } from "./select/SignalSelect.vue";
8 | export { default as SignalDelayWaring } from "./select/SignalDelayWaring.vue";
--------------------------------------------------------------------------------
/ant-vue/src/directives/copy.ts:
--------------------------------------------------------------------------------
1 | import type { DirectiveBinding } from "vue";
2 | import { message } from "ant-design-vue";
3 | import { useClipboard } from "@vueuse/core";
4 |
5 | interface CopyEl extends HTMLElement {
6 | copyStr: string;
7 | copyHandler: () => void;
8 | }
9 |
10 | export default {
11 | mounted(el: CopyEl, binding: DirectiveBinding) {
12 | el.copyStr = binding.value;
13 | el.copyHandler = () => {
14 | const { copy } = useClipboard({ legacy: true });
15 | copy(el.copyStr)
16 | .then(() => {
17 | message.success("复制成功");
18 | })
19 | .catch((error) => {
20 | message.error("复制失败");
21 | console.log("复制失败原因", error);
22 | });
23 | };
24 | el.addEventListener("click", el.copyHandler);
25 | },
26 | updated(el: CopyEl, binding: DirectiveBinding) {
27 | el.copyStr = binding.value;
28 | },
29 | unmounted(el: CopyEl) {
30 | el.removeEventListener("click", el.copyHandler);
31 | },
32 | };
33 |
--------------------------------------------------------------------------------
/ant-vue/src/directives/index.ts:
--------------------------------------------------------------------------------
1 | import type { App } from "vue";
2 |
3 | const directives = import.meta.glob("./*.ts");
4 |
5 | const install = (app: App): void => {
6 | for (const [key, value] of Object.entries(directives)) {
7 | const name = key.slice(key.lastIndexOf("/") + 1, key.lastIndexOf("."));
8 | value()
9 | .then((res: any) => {
10 | app.directive(name, res.default || res[name]);
11 | })
12 | .catch((err) => {
13 | console.log(err);
14 | });
15 | }
16 | };
17 |
18 | export default install;
19 |
--------------------------------------------------------------------------------
/ant-vue/src/directives/permission.ts:
--------------------------------------------------------------------------------
1 | import type { DirectiveBinding } from "vue";
2 |
3 | import { hasPermission } from "@/utils/permission";
4 |
5 | export default {
6 | mounted(el: HTMLElement, binding: DirectiveBinding) {
7 | const id = binding.value as string;
8 | const flag = hasPermission(id);
9 | if (!flag) {
10 | el.parentElement?.removeChild(el);
11 | }
12 | },
13 | };
14 |
--------------------------------------------------------------------------------
/ant-vue/src/directives/resize.ts:
--------------------------------------------------------------------------------
1 | import type { DirectiveBinding } from "vue";
2 |
3 | interface ResizeEl extends HTMLElement {
4 | _observer: InstanceType;
5 | }
6 |
7 | export default {
8 | mounted(el: ResizeEl, binding: DirectiveBinding) {
9 | let width = el.clientWidth;
10 | let height = el.clientHeight;
11 |
12 | el._observer = new ResizeObserver(() => {
13 | if (el.clientWidth !== width || el.clientHeight !== height) {
14 | width = el.clientWidth;
15 | height = el.clientHeight;
16 | binding.value(width, height);
17 | }
18 | });
19 | el._observer.observe(el);
20 | },
21 | unmounted(el: ResizeEl) {
22 | el._observer?.disconnect();
23 | },
24 | };
25 |
--------------------------------------------------------------------------------
/ant-vue/src/hooks/useDeletePage.ts:
--------------------------------------------------------------------------------
1 | import { getAxiosUrl } from "@/utils/setAxiosConfig";
2 | import { message } from "ant-design-vue";
3 |
4 | /**
5 | * 用于处理删除数据的功能。
6 | *
7 | * @param apiInfo - 用于指定 API 请求的配置信息。
8 | * @param callback - 请求成功后执行的回调函数,可以用于刷新数据或执行其他操作。
9 | *
10 | * @returns 一个对象,包含以下一个方法:
11 | * - deleteById: 处理数据删除操作。
12 | */
13 |
14 | export const useDeletePage = (apiInfo: any, callback: () => any) => {
15 | const deleteById = async (id: string) => {
16 | try {
17 | const { data } = await getAxiosUrl(apiInfo, id);
18 | if (data.code === 20000) {
19 | message.success(data.message);
20 | await callback();
21 | } else {
22 | message.success(data.message);
23 | }
24 | } catch (error) {
25 | console.log(error);
26 | }
27 | };
28 | return {
29 | deleteById,
30 | };
31 | };
32 |
--------------------------------------------------------------------------------
/ant-vue/src/hooks/useEditableData.ts:
--------------------------------------------------------------------------------
1 | import { cloneDeep } from "lodash-es";
2 | import { reactive, UnwrapRef } from "vue";
3 |
4 | /**
5 | * 自定义组合式函数,用于管理可编辑数据项。
6 | *
7 | * @param list - 包含数据项的响应式引用列表,每个数据项应有一个唯一标识符(如 `key`)。
8 | *
9 | * @returns 一个对象,包含以下属性:
10 | * - `editableData`: 一个响应式对象,用于存储当前正在编辑的数据项。每个数据项以 `key` 为属性存储。
11 | * - `edit`: 一个函数,用于启动对指定 `key` 对应的数据项的编辑。将数据项的深拷贝存储在 `editableData` 中。
12 | * - `cancel`: 一个函数,用于取消对指定 `key` 对应的数据项的编辑。将 `editableData` 中的相关条目删除。
13 | */
14 |
15 | export const useEditableData = (list: any) => {
16 | const editableData: UnwrapRef> = reactive({});
17 | const edit = (key: string) => {
18 | editableData[key] = cloneDeep(list.value.filter((item) => key === item.key)[0]);
19 | };
20 | const cancel = (key: string) => {
21 | delete editableData[key];
22 | };
23 | return {
24 | editableData,
25 | edit,
26 | cancel,
27 | };
28 | };
29 |
--------------------------------------------------------------------------------
/ant-vue/src/hooks/usePagination.ts:
--------------------------------------------------------------------------------
1 | import { reactive } from "vue";
2 |
3 | export const usePagination = () => {
4 | const pagination = reactive({
5 | total: 0,
6 | current: 1,
7 | pageSize: 10,
8 | showSizeChanger: true, // 显示每页显示条目数选择器
9 | });
10 |
11 | return {
12 | pagination,
13 | };
14 | };
15 |
--------------------------------------------------------------------------------
/ant-vue/src/hooks/useQueryPage.ts:
--------------------------------------------------------------------------------
1 | import { getAxiosUrl } from "@/utils/setAxiosConfig";
2 |
3 | /**
4 | * 用于处理查询数据的功能。
5 | *
6 | * @param apiInfo - 用于指定 API 请求的配置信息。
7 | * @param pagination - 分页数据
8 | * @param list - 数据列表。
9 | *
10 | * @returns 一个对象,包含以下一个方法:
11 | * - pageList: 处理数据查询操作。
12 | */
13 |
14 | export const useQueryPage = (apiInfo: any, pagination: any, list: any) => {
15 | const pageList = async () => {
16 | const { data } = await getAxiosUrl(apiInfo, { page: pagination.current, page_size: pagination.pageSize });
17 | pagination.total = data.data?.total || 0;
18 | list.value = data.data.data?.map((item: any, index: number) => ({
19 | key: index,
20 | ...item,
21 | }));
22 | };
23 |
24 | return {
25 | pageList,
26 | };
27 | };
28 |
--------------------------------------------------------------------------------
/ant-vue/src/hooks/useRoles.ts:
--------------------------------------------------------------------------------
1 | import { ref, watch } from "vue";
2 | import { useI18n } from "vue-i18n";
3 |
4 | /**
5 | * 自定义组合式函数,用于处理表单验证规则的国际化。
6 | *
7 | * @param obj - 一个对象,其中每个键对应一个验证规则数组。每个验证规则对象必须包含 `message` 属性。
8 | * - `message`: 验证失败时显示的提示消息,需要经过国际化处理。
9 | *
10 | * @returns 一个对象,包含以下属性:
11 | * - `rules`: 一个响应式引用,表示处理后的验证规则。每条规则的 `message` 属性经过国际化处理,并且当语言发生变化时,验证规则会自动更新。
12 | */
13 |
14 | export const useRoles = (obj: any) => {
15 | const { t, locale } = useI18n();
16 | function setRules() {
17 | const newRules = {};
18 | for (const [key, value] of Object.entries(obj)) {
19 | newRules[key] = value.map((rule: { message: any }) => ({
20 | ...rule,
21 | message: t(rule.message), // 使用 t 函数进行翻译
22 | }));
23 | }
24 | return newRules;
25 | }
26 | const rules = ref(setRules());
27 | watch(locale, (newValue) => {
28 | rules.value = setRules();
29 | });
30 |
31 | return { rules };
32 | };
33 |
--------------------------------------------------------------------------------
/ant-vue/src/hooks/useRouteJump.ts:
--------------------------------------------------------------------------------
1 | import { useRouter } from "vue-router";
2 |
3 | interface RouteJumpParams {
4 | path: string;
5 | query?: Record;
6 | newWindow?: boolean;
7 | }
8 | export const useRouteJump = () => {
9 | const router = useRouter();
10 | const routeJump = ({ path = "", query = {}, newWindow = false }: RouteJumpParams) => {
11 | if (newWindow) {
12 | const route = router.resolve({ path, query });
13 | window.open(route.href, "_blank");
14 | } else {
15 | router.push({ path, query });
16 | }
17 | };
18 | return { routeJump };
19 | };
20 |
--------------------------------------------------------------------------------
/ant-vue/src/i18n/index.ts:
--------------------------------------------------------------------------------
1 | import { createI18n, I18n } from 'vue-i18n';
2 | import en from './en';
3 | import zhCHS from './zh-CHS.ts';
4 |
5 | const messages = {
6 | en,
7 | zhCHS
8 | };
9 |
10 | const i18n: I18n = createI18n({
11 | legacy: false, // 使用 Composition API
12 | locale: 'zhCHS', // 默认语言
13 | fallbackLocale: 'zhCHS', // 回退语言
14 | messages
15 | });
16 |
17 | export default i18n;
18 |
--------------------------------------------------------------------------------
/ant-vue/src/icons/complex.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ["preset-default", "prefixIds"],
3 | };
4 |
--------------------------------------------------------------------------------
/ant-vue/src/icons/simple.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | "preset-default",
4 | "prefixIds",
5 | {
6 | name: "removeAttrs",
7 | params: {
8 | attrs: ["stroke", "fill", "fill-rule"],
9 | },
10 | },
11 | ],
12 | };
13 |
--------------------------------------------------------------------------------
/ant-vue/src/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from "vue";
2 | import { RecycleScroller } from "vue-virtual-scroller";
3 | import "normalize.css";
4 | import "virtual:svg-icons-register";
5 | import "./permission";
6 | import "./styles/index.less";
7 | import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
8 |
9 | import App from "./App.vue";
10 | import directiveRegister from "./directives";
11 | import VxeTable from "./plugins/vxe-table";
12 | import router from "./router";
13 | import store from "./stores";
14 | import i18n from './i18n';
15 |
16 | const app = createApp(App);
17 |
18 | app.use(router);
19 | app.use(store);
20 | app.component("RecycleScroller", RecycleScroller);
21 | app.use(directiveRegister);
22 | app.use(VxeTable);
23 | app.use(i18n);
24 |
25 | app.mount("#app");
26 |
--------------------------------------------------------------------------------
/ant-vue/src/plugins/vxe-table.ts:
--------------------------------------------------------------------------------
1 | import type { App } from "vue";
2 | import { Column, Grid, Table, VXETable } from "vxe-table";
3 | import "xe-utils";
4 | import "vxe-table/lib/style.css";
5 |
6 | const components = [Column, Grid, Table];
7 |
8 | // 单元格默认渲染器
9 | VXETable.renderer.add("cellRender", {
10 | renderDefault(_renderOpts, params) {
11 | const { row, column } = params;
12 | const value = row[column.field];
13 | if (value === null || value === "" || (Array.isArray(value) && value.length === 0)) {
14 | return "-";
15 | } else if (Array.isArray(value)) {
16 | return value.join(",");
17 | } else {
18 | return value;
19 | }
20 | },
21 | });
22 |
23 | export default {
24 | install(app: App) {
25 | for (const comp of components) {
26 | app.use(comp);
27 | }
28 | },
29 | };
30 |
--------------------------------------------------------------------------------
/ant-vue/src/request/error.ts:
--------------------------------------------------------------------------------
1 | import { message } from "ant-design-vue";
2 | export const errorHandler = (code: number, msg: string) => {
3 | switch (code) {
4 | case 401:
5 | message.error("没有访问权限");
6 | break;
7 | case 403:
8 | message.error("资源不可用");
9 | break;
10 | case 404:
11 | message.error("找不到对应资源");
12 | break;
13 | case 500:
14 | message.error("服务器异常");
15 | break;
16 | case 502:
17 | message.error("服务器异常");
18 | break;
19 | default:
20 | if (typeof msg === "string") {
21 | message.error(msg);
22 | } else {
23 | message.error(JSON.stringify(msg));
24 | }
25 | break;
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/ant-vue/src/router/index.ts:
--------------------------------------------------------------------------------
1 | import type { RouteRecordRaw } from "vue-router";
2 | import { createRouter, createWebHistory } from "vue-router";
3 |
4 | import single from "./single";
5 |
6 | export const routes: RouteRecordRaw[] = [
7 | {
8 | path: "/",
9 | name: "Root",
10 | redirect: "/mqtt-management",
11 | meta: { hidden: true },
12 | },
13 | ...single,
14 | ];
15 |
16 | const router = createRouter({
17 | history: createWebHistory(import.meta.env.VITE_BASE_URL),
18 | routes,
19 | });
20 |
21 | export default router;
22 |
--------------------------------------------------------------------------------
/ant-vue/src/stores/index.ts:
--------------------------------------------------------------------------------
1 | import { createPinia } from "pinia";
2 | import piniaPluginPersist from "pinia-plugin-persistedstate";
3 | const store = createPinia();
4 | store.use(piniaPluginPersist);
5 | export default store;
6 |
--------------------------------------------------------------------------------
/ant-vue/src/stores/permission.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from "pinia";
2 |
3 | interface PermissionStore {
4 | openValidator: boolean; // 是否开启权限拦截
5 | btnPermissionList: string[]; // 当前路由下按钮权限集合
6 | }
7 |
8 | const isDev = import.meta.env.MODE === "development";
9 |
10 | export const usePermissionStore = defineStore({
11 | id: "permission",
12 | state: (): PermissionStore => {
13 | return {
14 | openValidator: !isDev,
15 | btnPermissionList: [],
16 | };
17 | },
18 | });
19 |
--------------------------------------------------------------------------------
/ant-vue/src/stores/routerPath.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from "pinia";
2 |
3 | export const useRouterNameStore = defineStore({
4 | id: "routerPath",
5 | state: () => {
6 | return {
7 | routerParent:"sub1",
8 | routerPath: "/mqtt-management",
9 | };
10 | },
11 | getters: {},
12 | actions: {
13 | getRouterName() {
14 | return this.routerPath;
15 | },
16 | setRouterName(item: string | any) {
17 | this.routerPath = item;
18 | },
19 | setRouterParent(item: string | any) {
20 | this.routerParent = item;
21 | },
22 | },
23 | persist: [
24 | {
25 | key: "project_template_router",
26 | paths: ["routerParent","routerPath"],
27 | storage: localStorage,
28 | },
29 | ],
30 | });
31 |
--------------------------------------------------------------------------------
/ant-vue/src/stores/theme.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from "pinia";
2 |
3 | interface ThemeStore {
4 | // 主题模式
5 | themeMode: "dark" | "light";
6 | }
7 |
8 | export const useThemeStore = defineStore({
9 | id: "theme",
10 | state: (): ThemeStore => {
11 | return {
12 | themeMode: "light",
13 | };
14 | },
15 | getters: {
16 | isDark: (state) => {
17 | return state.themeMode === "light";
18 | },
19 | },
20 | persist: [
21 | {
22 | key: "project_template_theme",
23 | paths: ["themeMode"],
24 | storage: localStorage,
25 | },
26 | ],
27 | });
28 |
--------------------------------------------------------------------------------
/ant-vue/src/styles/index.less:
--------------------------------------------------------------------------------
1 | @import "./variable.less";
2 | @import "./library.less";
3 | @import "./scrollbar.less";
--------------------------------------------------------------------------------
/ant-vue/src/styles/library.less:
--------------------------------------------------------------------------------
1 | // 此文件用于重写组件库的组件默认样式
2 |
3 | // 按钮
4 | .ant-btn {
5 | // 按钮有图标的情况
6 | .g-svg-icon {
7 | margin-right: 8px;
8 | }
9 | }
10 |
11 | // 警告提示
12 | .ant-alert {
13 | // 成功
14 | &.ant-alert-success {
15 | color: @colorSuccess;
16 | background-color: rgba(@colorSuccessRgb, 0.2);
17 | }
18 | // 失败
19 | &.ant-alert-error {
20 | color: @colorError;
21 | background-color: rgba(@colorErrorRgb, 0.2);
22 | }
23 | // 信息
24 | &.ant-alert-info {
25 | color: @colorInfo;
26 | background-color: rgba(@colorInfoRgb, 0.2);
27 | }
28 | // 警戒
29 | &.ant-alert-warning {
30 | color: @colorWarning;
31 | background-color: rgba(@colorWarningRgb, 0.2);
32 | }
33 | }
34 |
35 | // 表单
36 | .ant-form {
37 | .ant-form-item {
38 | margin-bottom: 12px;
39 | }
40 | }
--------------------------------------------------------------------------------
/ant-vue/src/styles/scrollbar.less:
--------------------------------------------------------------------------------
1 | // 整个滚动条
2 | ::-webkit-scrollbar {
3 | width: 8px;
4 | height: 8px;
5 | }
6 |
7 | // 滚动条有滑块的轨道部分
8 | ::-webkit-scrollbar-track-piece {
9 | background-color: transparent;
10 | border-radius: 5px;
11 | }
12 |
13 | // 滚动条滑块(竖向:vertical 横向:horizontal)
14 | ::-webkit-scrollbar-thumb {
15 | cursor: pointer;
16 | background-color: var(--g-scrollbar-thumb-bg);
17 | border-radius: 5px;
18 | }
19 |
20 | // 滚动条滑块hover
21 | ::-webkit-scrollbar-thumb:hover {
22 | background-color: var(--g-scrollbar-thumb-hover-bg);
23 | }
24 |
25 | // 同时有垂直和水平滚动条时交汇的部分
26 | ::-webkit-scrollbar-corner {
27 | display: block;
28 | }
29 |
--------------------------------------------------------------------------------
/ant-vue/src/types/form.ts:
--------------------------------------------------------------------------------
1 | import type { RuleObject } from "ant-design-vue/lib/form/interface";
2 |
3 | // 表单规则类型
4 | export type FormRuleObject = Record;
5 |
--------------------------------------------------------------------------------
/ant-vue/src/utils/color.ts:
--------------------------------------------------------------------------------
1 | // 将十六进制的颜色转为rgba格式
2 | export const color2rgba = (color: string, alpha = 1) => {
3 | const arr = [];
4 | for (let i = 1; i < 7; i += 2) {
5 | arr.push(parseInt("0x" + color.slice(i, i + 2)));
6 | }
7 | return `rgba(${arr.join(",")},${alpha})`;
8 | };
9 |
--------------------------------------------------------------------------------
/ant-vue/src/utils/i18n.ts:
--------------------------------------------------------------------------------
1 | // utils/i18n.ts
2 | import { useI18n } from 'vue-i18n';
3 |
4 | export function getMetaTitle(key: string) {
5 | const { t } = useI18n();
6 | return t(key);
7 | }
--------------------------------------------------------------------------------
/ant-vue/src/utils/permission.ts:
--------------------------------------------------------------------------------
1 | import { usePermissionStore } from "@/stores/permission";
2 |
3 | // 判断是否有权限
4 | export const hasPermission = (id: string): boolean => {
5 | const permissionStore = usePermissionStore();
6 | const btnPermissionList = permissionStore.btnPermissionList;
7 | if (!permissionStore.openValidator) {
8 | return true;
9 | } else if (btnPermissionList.includes(id)) {
10 | return true;
11 | }
12 | return false;
13 | };
14 |
--------------------------------------------------------------------------------
/ant-vue/src/utils/setAxiosConfig.ts:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | interface ApiInfo {
4 | path: string;
5 | type: string;
6 | }
7 |
8 | const url: string = import.meta.env.VITE_APP_API_URL;
9 |
10 | /**
11 | * 发送网络请求的通用函数。
12 | *
13 | * @param apiInfo - 请求的配置信息对象,包括 API 路径和请求类型。
14 | * - `path`: API 的路径部分。
15 | * - `type`: HTTP 请求类型,例如 "get"、"post"、"put" 或 "delete"。
16 | * @param params - 请求的参数。对于 GET 请求,它们会作为查询参数附加到 URL 后;对于 POST 和 PUT 请求,它们会作为请求体发送;对于 DELETE 请求,它们会被附加到 URL。
17 | *
18 | * @returns 返回一个 Promise 对象,表示请求的结果。Promise 的解析值是 axios 发起请求后的响应对象。
19 | */
20 |
21 | export async function getAxiosUrl(apiInfo: ApiInfo, params: any) {
22 | const { type, path } = apiInfo;
23 | if (type === "get") {
24 | return await axios[type](`${url}${path}`, { params });
25 | } else if (type === "delete") {
26 | return await axios.post(`${url}${path}/${params}`);
27 | } else {
28 | return await axios[type](`${url}${path}`, params);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/ant-vue/src/views/coap/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ant-vue/src/views/http/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ant-vue/src/views/message-list/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ant-vue/src/views/repair-records/index.vue:
--------------------------------------------------------------------------------
1 |
2 | 维修记录
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ant-vue/src/views/shipment-records/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ant-vue/src/views/tcp/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ant-vue/src/views/visualization/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ant-vue/src/views/websocket/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ant-vue/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "target": "ES2020",
5 | "useDefineForClassFields": true,
6 | "module": "ESNext",
7 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
8 | "skipLibCheck": true,
9 | "paths": {
10 | "@/*": ["./src/*"]
11 | },
12 |
13 | /* Bundler mode */
14 | "moduleResolution": "bundler",
15 | "allowImportingTsExtensions": true,
16 | "resolveJsonModule": true,
17 | "isolatedModules": true,
18 | "noEmit": true,
19 | "jsx": "preserve",
20 |
21 | /* Linting */
22 | "strict": true,
23 | "noUnusedLocals": true,
24 | "noUnusedParameters": true,
25 | "noFallthroughCasesInSwitch": true,
26 | "allowSyntheticDefaultImports": true
27 | },
28 | "include": [".eslintrc.cjs", "*.ts", "*.d.ts", "src/**/*.cjs", "src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"],
29 | "references": [{ "path": "./tsconfig.node.json" }]
30 | }
31 |
--------------------------------------------------------------------------------
/ant-vue/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "skipLibCheck": true,
5 | "module": "ESNext",
6 | "moduleResolution": "bundler",
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "include": ["vite.config.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/deploy/IotAdminReact.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:18.19.0-alpine3.18 as build
2 |
3 |
4 | WORKDIR /app
5 | COPY ../ant-react ./ant-react
6 |
7 | RUN cd ant-react && yarn install --registry=https://registry.npmmirror.com && yarn run build
8 |
9 |
10 |
11 | FROM nginx:stable-alpine3.17
12 |
13 |
14 | COPY ../ant-react/nginx.conf /etc/nginx/nginx.conf
15 | WORKDIR /app
16 | COPY --from=build /app/ant-react/dist /app/iot/project/html
17 |
18 | RUN mkdir /var/log/nginx/iot
19 |
20 | CMD ["nginx", "-g", "daemon off;"]
21 |
--------------------------------------------------------------------------------
/deploy/IotAdminVue.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:18.19.0-alpine3.18 as build
2 |
3 |
4 | WORKDIR /app
5 | COPY ../ant-vue ./ant-vue
6 |
7 | RUN cd ant-vue && npm install --registry=https://registry.npmmirror.com && npm run build-docker
8 |
9 |
10 |
11 | FROM nginx:stable-alpine3.17
12 |
13 |
14 | COPY ../ant-vue/nginx.conf /etc/nginx/nginx.conf
15 | WORKDIR /app
16 | COPY --from=build /app/ant-vue/dist /app/iot/project/html
17 |
18 | RUN mkdir /var/log/nginx/iot
19 |
20 | CMD ["nginx", "-g", "daemon off;"]
21 |
--------------------------------------------------------------------------------
/deploy/IotGoMQ.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.22 as builder
2 |
3 | ENV GO111MODULE=on \
4 | GOPROXY=https://goproxy.cn,direct
5 |
6 | WORKDIR /app
7 |
8 |
9 | COPY ../go-iot-mq ./go-iot-mq
10 | COPY ../notice ./notice
11 | COPY ../transmit ./transmit
12 |
13 | #
14 | RUN cd go-iot-mq && go mod tidy && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
15 |
16 |
17 | RUN chmod +x /app/go-iot-mq/main
18 | # 运行阶段指定 scratch 作为基础镜像
19 | FROM alpine
20 |
21 | WORKDIR /app
22 |
23 | # 将上一个阶段publish文件夹下的所有文件复制进来
24 | COPY --from=builder /app/go-iot-mq/main .
25 | COPY --from=builder /app/go-iot-mq/app-local.yml .
26 |
27 | RUN mkdir logs
28 | ENV GIN_MODE=release \
29 | PORT=8080
30 |
31 | EXPOSE 8080
32 |
33 | #fixme: 配置需要动态调整
34 | ENTRYPOINT ["/app/main","-config","/app/app-local.yml"]
35 |
--------------------------------------------------------------------------------
/deploy/IotGoProject.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.22 as builder
2 |
3 | ENV GO111MODULE=on \
4 | GOPROXY=https://goproxy.cn,direct
5 |
6 | WORKDIR /app
7 |
8 |
9 | COPY ../iot-go-project ./iot-go-project
10 | COPY ../notice ./notice
11 | COPY ../transmit ./transmit
12 |
13 | RUN cd iot-go-project && go install github.com/swaggo/swag/cmd/swag@latest && swag init --parseDependency --parseInternal --parseDepth 5 --instanceName "swagger" && go mod tidy && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
14 |
15 | RUN chmod +x /app/iot-go-project/main
16 | # 运行阶段指定 scratch 作为基础镜像
17 | FROM alpine
18 |
19 | WORKDIR /app
20 |
21 | # 将上一个阶段publish文件夹下的所有文件复制进来
22 | COPY --from=builder /app/iot-go-project/main .
23 | COPY --from=builder /app/iot-go-project/app-local.yml .
24 |
25 | RUN mkdir logs
26 | ENV GIN_MODE=release \
27 | PORT=8080
28 |
29 | EXPOSE 8080
30 |
31 | ENTRYPOINT ["/app/main", "-config", "/app/app-local.yml"]
32 |
--------------------------------------------------------------------------------
/deploy/IotMQTT.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.22 as builder
2 |
3 | ENV GO111MODULE=on \
4 | GOPROXY=https://goproxy.cn,direct
5 |
6 | WORKDIR /app
7 |
8 |
9 | COPY ../iot-go-project ./iot-go-project
10 | COPY ../go-iot-mq ./go-iot-mq
11 | COPY ../notice ./notice
12 | COPY ../transmit ./transmit
13 | COPY ../go-iot ./go-iot
14 |
15 | #
16 | RUN cd go-iot && go mod tidy && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
17 |
18 |
19 | RUN chmod +x /app/go-iot/main
20 | # 运行阶段指定 scratch 作为基础镜像
21 | FROM alpine
22 |
23 | WORKDIR /app
24 |
25 | # 将上一个阶段publish文件夹下的所有文件复制进来
26 | COPY --from=builder /app/go-iot/main .
27 | COPY --from=builder /app/go-iot/app-local.yml .
28 |
29 | RUN mkdir logs
30 | ENV GIN_MODE=release \
31 | PORT=8080
32 |
33 | EXPOSE 8080
34 | #fixme: 配置需要动态调整
35 | ENTRYPOINT ["/app/main", "-config", "/app/app-local.yml"]
36 |
--------------------------------------------------------------------------------
/deploy/readme.md:
--------------------------------------------------------------------------------
1 | # 部署文档
2 |
3 | 1. [环境部署.md](%E7%8E%AF%E5%A2%83%E9%83%A8%E7%BD%B2.md)
4 | 1. [后台服务部署.md](%E5%90%8E%E5%8F%B0%E6%9C%8D%E5%8A%A1%E9%83%A8%E7%BD%B2.md)
5 | 1. [MQTT客户端管理项目部署.md](mqtt%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%AE%A1%E7%90%86%E9%A1%B9%E7%9B%AE%E9%83%A8%E7%BD%B2.md)
6 | 1. [rabbit消费者部署.md](rabbit%E6%B6%88%E8%B4%B9%E8%80%85%E9%83%A8%E7%BD%B2.md)
7 |
8 | 启动顺序:
9 |
10 | 1. 后台服务
11 | 2. MQTT客户端管理项目
12 | 3. rabbit消费者
--------------------------------------------------------------------------------
/deploy/环境部署.md:
--------------------------------------------------------------------------------
1 | # 环境部署
2 |
3 | | 服务名称 | 版本要求 | 安装方式 | 备注 |
4 | |----------|---------------------|--------|----------|
5 | | InfluxDB | 2.6-alpine | Docker | 时间序列数据库 |
6 | | MySQL | 8.0.33 | 手动安装 | 关系数据库 |
7 | | MQTT | emqx:5.4.1 | Docker | 消息传输协议代理 |
8 | | RabbitMQ | 3-management-alpine | Docker | 消息队列服务 |
9 | | Redis | 6.2.14 | 手动安装 | 内存数据结构存储 |
10 | | Go | 1.22 | 手动安装 | 编程语言环境 |
11 |
12 | 安装方式为Docker的可以进入 [docker](../docker) 目录进行快速启动
--------------------------------------------------------------------------------
/doc/GoIoT开发平台介绍.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/GoIoT开发平台介绍.pdf
--------------------------------------------------------------------------------
/doc/GoIoT开发平台分析.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/GoIoT开发平台分析.pdf
--------------------------------------------------------------------------------
/doc/MQTT客户端管理方案/MQTT客户端保活.drawio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/MQTT客户端管理方案/MQTT客户端保活.drawio.png
--------------------------------------------------------------------------------
/doc/MQTT客户端管理方案/MQTT客户端管理方案.drawio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/MQTT客户端管理方案/MQTT客户端管理方案.drawio.png
--------------------------------------------------------------------------------
/doc/MQTT客户端管理方案/image-20240423094241762.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/MQTT客户端管理方案/image-20240423094241762.png
--------------------------------------------------------------------------------
/doc/readme.md:
--------------------------------------------------------------------------------
1 | # Go IoT 开发平台文档库
2 |
3 | 1. [MQTT客户端管理方案](mqtt客户端管理方案.md)
4 | 1. [数据流转链路](数据流转链路.md)
5 | 1. [报警](报警.md)
6 | 1. [部署](部署.md)
--------------------------------------------------------------------------------
/doc/功能说明/人员管理.md:
--------------------------------------------------------------------------------
1 | # 人员管理
2 |
3 | 1. 基本的 RBAC 模型
4 |
5 |
6 |
7 | 系统默认行为:
8 |
9 | 1. 创建如下角色
10 | 1. 超级管理员
11 | 1. 生产管理员
12 | 1. 生产人员
13 | 1. 维修员
14 | 1. 售后员
15 | 1. 创建默认用户
16 | 1. admin/admin
--------------------------------------------------------------------------------
/doc/功能说明/协议管理.md:
--------------------------------------------------------------------------------
1 | # 协议管理
2 |
3 |
4 | ## MQTT协议管理
5 |
6 | 1. 支持创建MQTT客户端
7 | 2. 支持查看每个节点的MQTT客户端情况
8 |
9 |
10 | > 其他协议类似不做详细说明
11 |
--------------------------------------------------------------------------------
/doc/功能说明/数据管理.md:
--------------------------------------------------------------------------------
1 | # 数据管理
2 |
3 | ## 信号管理
4 | 1. 信号增删改查基本逻辑(注意需要和不同协议的转换器对接)
5 | 2. 每个信号支持信号报警(阈值范围内或者范围外)
6 | 3.
7 | ## 脚本报警
8 | 1. 支持编写脚本(脚本执行结果范围布尔值)
9 | 2. 支持脚本参数配置
10 |
11 |
12 | ## 数据计算
13 | 1. 支持编写脚本(脚本执行结果范围object)
14 | 2. 支持脚本参数配置
15 |
16 | ## 可视化
17 | 1. 支持简单的图表可视化,用于快速选择设备信号、时间范围呈现结果。
--------------------------------------------------------------------------------
/doc/功能说明/通知管理.md:
--------------------------------------------------------------------------------
1 | # 通知管理
2 | 系统目前支持:飞书机器人和钉钉机器人。
3 | 涉及的通知类型:
4 |
5 | 1. 计划开始通知
6 | 1. 计划临期通知
7 | 1. 计划到期通知
8 | 1. 生产开始通知
9 | 1. 生产完成通知
10 | 1. 维修通知
11 | 1. 维修开始通知
12 | 1. 维修结束通知
13 | 1. sim卡超时通知
14 | 1. 设备掉线通知
15 |
16 |
--------------------------------------------------------------------------------
/doc/报警/数值报警.drawio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/报警/数值报警.drawio.png
--------------------------------------------------------------------------------
/doc/报警/脚本报警.drawio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/报警/脚本报警.drawio.png
--------------------------------------------------------------------------------
/doc/数据流转链路/设备数据流转链路.drawio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/数据流转链路/设备数据流转链路.drawio.png
--------------------------------------------------------------------------------
/doc/测试方案.md:
--------------------------------------------------------------------------------
1 | # 测试方案
2 |
3 | 1. 启动管理端
4 | 2. 启动 go-iot 单机
5 | 3. 启动 go-iot-mq 数据持久消息队列处理器1个
6 |
7 |
8 | 模拟100个设备发送数据信号点位200个,时间间隔1秒,每次只发送到一个主题 , 管理端监听一个主题,不采用通配符策略
9 |
10 |
11 | 运行时间:1小时
12 |
13 | 截图要求:
14 | 1. grafana
15 | 2. influxdb 中计算上报时间和存储时间的时间差求10秒均值
16 |
--------------------------------------------------------------------------------
/doc/部署/image-20240902123240839.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/部署/image-20240902123240839.png
--------------------------------------------------------------------------------
/doc/部署/image-20240902123753596.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/部署/image-20240902123753596.png
--------------------------------------------------------------------------------
/doc/部署/image-20240902123825724.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/doc/部署/image-20240902123825724.png
--------------------------------------------------------------------------------
/docker/afa/config/mosquitto.conf:
--------------------------------------------------------------------------------
1 | allow_anonymous false
2 | listener 1883
3 | listener 9001
4 | protocol websockets
5 | persistence true
6 | password_file /mosquitto/config/pwfile
7 | persistence_file mosquitto.db
8 | persistence_location /mosquitto/data/
--------------------------------------------------------------------------------
/docker/afa/config/pwfile:
--------------------------------------------------------------------------------
1 | admin:$7$101$7pMdyMqcznuKysFg$ahJltcwpB37+8xm+sV2STNDiBcaLuPE9DASkxYjTYqrMHLlYtBRdDGyGQqvCY/wfQaKySycjJECVPHXRHAxggg==
2 |
--------------------------------------------------------------------------------
/docker/afa/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.7"
2 | services:
3 | # mqtt5 eclipse-mosquitto
4 | mqtt5:
5 | image: eclipse-mosquitto
6 | container_name: mqtt5
7 | ports:
8 | - "1883:1883" #default mqtt port
9 | - "19001:9001" #default mqtt port for websockets
10 | volumes:
11 | - ./config:/mosquitto/config:rw
12 | - ./data:/mosquitto/data:rw
13 | - ./log:/mosquitto/log:rw
14 | restart: unless-stopped
15 |
16 | # volumes for mapping data,config and log
17 | volumes:
18 | config:
19 | data:
20 | log:
21 |
22 | networks:
23 | default:
24 | name: mqtt5-network
--------------------------------------------------------------------------------
/docker/app-start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | docker-compose -f ./app/docker-compose.yml down
3 | docker rmi go-iot-project:latest go-iot-admin-vue:latest go-iot-mq:latest go-iot-mqtt:latest
4 | docker-compose -f ./app/docker-compose.yml up -d
5 | echo "项目已启动"
6 |
--------------------------------------------------------------------------------
/docker/app/docker-compose.react.yml:
--------------------------------------------------------------------------------
1 | services:
2 | iot-admin-react:
3 | build:
4 | context: ../../
5 | dockerfile: deploy/IotAdminReact.Dockerfile
6 | image: go-iot-admin-react:latest
7 | environment:
8 | - TZ=Asia/Shanghai
9 | ports:
10 | - 18081:80
11 | networks:
12 | - iot-net
13 | networks:
14 | iot-net:
15 | driver: bridge
16 |
--------------------------------------------------------------------------------
/docker/app/iot-project/config/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | port: 8080
3 | host: 192.168.3.101
4 | redis_config:
5 | host: 192.168.3.101
6 | port: 6379
7 | db: 10
8 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
9 |
10 | mq_config:
11 | host: 192.168.3.101
12 | port: 5672
13 | username: guest
14 | password: guest
15 | influx_config:
16 | host: 192.168.3.101
17 | port: 8086
18 | token: mytoken
19 | org: myorg
20 | bucket: mybucket
21 |
22 | mysql_config:
23 | username: app
24 | password: iot123456
25 | host: 192.168.3.101
26 | port: 3306
27 | dbname: iot
28 | mongo_config:
29 | host: 192.168.3.101
30 | port: 27017
31 | username: admin
32 | password: admin
33 | db: iot
34 | collection: calc
35 | waring_collection: waring
36 | script_waring_collection: script_waring
37 |
--------------------------------------------------------------------------------
/docker/app/mq/config/app-local-calc.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 29001
4 | name: mq1
5 | type: calc_queue # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 192.168.3.101
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 |
16 | mq_config:
17 | host: 192.168.3.101
18 | port: 5672
19 | username: guest
20 | password: guest
21 | influx_config:
22 | host: 192.168.3.101
23 | port: 8086
24 | token: mytoken
25 | org: myorg
26 | bucket: mybucket
27 | mongo_config:
28 | host: 192.168.3.101
29 | port: 27017
30 | username: admin
31 | password: admin
32 | db: iot
33 | collection: calc
34 | waring_collection: waring
35 | script_waring_collection: script_waring
36 |
--------------------------------------------------------------------------------
/docker/app/mq/config/app-local-pre_handler-1.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 30000
4 | name: mq1
5 | type: pre_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 192.168.3.101
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 192.168.3.101
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 192.168.3.101
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 192.168.3.101
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
35 |
--------------------------------------------------------------------------------
/docker/app/mq/config/app-local-pre_handler-2.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 30000
4 | name: mq1
5 | type: pre_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 192.168.3.101
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 192.168.3.101
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 192.168.3.101
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 192.168.3.101
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
35 |
--------------------------------------------------------------------------------
/docker/app/mq/config/app-local-pre_handler-3.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 30000
4 | name: mq1
5 | type: pre_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 192.168.3.101
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 192.168.3.101
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 192.168.3.101
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 192.168.3.101
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
35 |
--------------------------------------------------------------------------------
/docker/app/mq/config/app-local-pre_handler.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 29002
4 | name: mq1
5 | type: pre_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 192.168.3.101
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 192.168.3.101
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 192.168.3.101
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 192.168.3.101
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
35 |
--------------------------------------------------------------------------------
/docker/app/mq/config/app-local-waring_handler.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 29003
4 | name: mq1
5 | type: waring_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 192.168.3.101
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 192.168.3.101
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 192.168.3.101
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 192.168.3.101
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
35 |
--------------------------------------------------------------------------------
/docker/app/mq/config/app-local-wd.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 29004
4 | name: mq1
5 | type: waring_delay_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 192.168.3.101
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 192.168.3.101
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 192.168.3.101
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 192.168.3.101
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
35 |
--------------------------------------------------------------------------------
/docker/app/mqtt/config/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 8006
4 | name: m1
5 | type: mqtt
6 | size: 300
7 | redis_config:
8 | host: 192.168.3.101
9 | port: 6379
10 | db: 10
11 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
12 |
13 |
14 |
15 | mq_config:
16 | host: 192.168.3.101
17 | port: 5672
18 | username: guest
19 | password: guest
20 |
--------------------------------------------------------------------------------
/docker/app/mqtt/config/app-local2.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 8007
4 | name: m2
5 | type: mqtt
6 | size: 3
7 | redis_config:
8 | host: 192.168.3.101
9 | port: 6379
10 | db: 10
11 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
12 |
13 |
14 |
15 | mq_config:
16 | host: 192.168.3.101
17 | port: 5672
18 | username: guest
19 | password: guest
20 |
--------------------------------------------------------------------------------
/docker/app/mqtt/config/app-local3.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 192.168.3.101
3 | port: 8008
4 | name: m3
5 | type: mqtt
6 | size: 3
7 | redis_config:
8 | host: 192.168.3.101
9 | port: 6379
10 | db: 10
11 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
12 |
13 |
14 |
15 | mq_config:
16 | host: 192.168.3.101
17 | port: 5672
18 | username: guest
19 | password: guest
20 |
--------------------------------------------------------------------------------
/docker/env-start.sh:
--------------------------------------------------------------------------------
1 | #!bin/bash
2 | docker-compose -f ./env/base-env-docker-compose.yml up -d
3 | echo "环境后台准备中...,请稍后"
4 |
--------------------------------------------------------------------------------
/docker/env/Cassandra/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3' #choose version as per your need
2 |
3 | services:
4 | cassandra:
5 | image: cassandra:latest
6 | container_name: cassandra-container
7 | ports:
8 | - "9042:9042"
9 | environment:
10 | - CASSANDRA_USER=admin
11 | - CASSANDRA_PASSWORD=admin
12 | volumes:
13 | - ./dataa:/var/lib/cassandra
14 |
15 | volumes:
16 | cassandra-data:
--------------------------------------------------------------------------------
/docker/env/clickhouse/config/docker_related_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ::
4 | 0.0.0.0
5 | 1
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/docker/env/clickhouse/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | clickhouse:
5 | image: yandex/clickhouse-server:22.1.3.7
6 | container_name: clickhouse
7 | restart: always
8 | ports:
9 | - "8123:8123"
10 | - "9000:9000"
11 | volumes:
12 | # 默认配置
13 | - ./config/docker_related_config.xml:/etc/clickhouse-server/config.d/docker_related_config.xml:rw
14 | - ./config/config.xml:/etc/clickhouse-server/config.xml:rw
15 | - ./config/users.xml:/etc/clickhouse-server/users.xml:rw
16 | - /etc/localtime:/etc/localtime:ro
17 | # 运行日志
18 | - ./log:/var/log/clickhouse-server
19 | # 数据持久
20 | - ./data:/var/lib/clickhouse:rw
--------------------------------------------------------------------------------
/docker/env/influx/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | influxdb:
5 | image: influxdb:2.6-alpine
6 | env_file:
7 | - influxv2.env
8 | volumes:
9 | # Mount for influxdb data directory and configuration
10 | - influxdbv2:/var/lib/influxdb2:rw
11 | ports:
12 | - "8086:8086"
13 | telegraf:
14 | image: telegraf:1.25-alpine
15 | depends_on:
16 | - influxdb
17 | volumes:
18 | # Mount for telegraf config
19 | - ./telegraf/mytelegraf.conf:/etc/telegraf/telegraf.conf:ro
20 | env_file:
21 | - influxv2.env
22 |
23 | volumes:
24 | influxdbv2:
25 |
--------------------------------------------------------------------------------
/docker/env/influx/influxv2.env:
--------------------------------------------------------------------------------
1 | DOCKER_INFLUXDB_INIT_MODE=setup
2 | DOCKER_INFLUXDB_INIT_USERNAME=myusername
3 | DOCKER_INFLUXDB_INIT_PASSWORD=passwordpasswordpassword
4 | DOCKER_INFLUXDB_INIT_ORG=myorg
5 | DOCKER_INFLUXDB_INIT_BUCKET=mybucket
6 | DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=mytoken
7 |
--------------------------------------------------------------------------------
/docker/env/iotdb/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | iotdb-service:
4 | image: apache/iotdb:1.3.0-standalone
5 | hostname: iotdb-service
6 | container_name: iotdb-service
7 | ports:
8 | - "6667:6667"
9 | environment:
10 | - cn_internal_address=iotdb-service
11 | - cn_internal_port=10710
12 | - cn_consensus_port=10720
13 | - cn_seed_config_node=iotdb-service:10710
14 | - dn_rpc_address=iotdb-service
15 | - dn_internal_address=iotdb-service
16 | - dn_rpc_port=6667
17 | - dn_mpp_data_exchange_port=10740
18 | - dn_schema_region_consensus_port=10750
19 | - dn_data_region_consensus_port=10760
20 | - dn_seed_config_node=iotdb-service:10710
21 | volumes:
22 | - ./data:/iotdb/data
23 | - ./logs:/iotdb/logs
24 | networks:
25 | iotdb:
26 | ipv4_address: 172.18.0.6
27 |
28 | networks:
29 | iotdb:
30 | driver: bridge
--------------------------------------------------------------------------------
/docker/env/kafka/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.5'
2 | services:
3 | zookeeper:
4 | image: wurstmeister/zookeeper
5 | container_name: zookeeper
6 | ports:
7 | - "2181:2181"
8 | kafka:
9 | image: wurstmeister/kafka
10 | container_name: kafka
11 | volumes:
12 | - /etc/localtime:/etc/localtime
13 | ports:
14 | - "9092:9092"
15 | environment:
16 | KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1
17 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
18 | KAFKA_ADVERTISED_PORT: 9092
19 | KAFKA_LOG_RETENTION_HOURS: 120
20 | KAFKA_MESSAGE_MAX_BYTES: 10000000
21 | KAFKA_REPLICA_FETCH_MAX_BYTES: 10000000
22 | KAFKA_GROUP_MAX_SESSION_TIMEOUT_MS: 60000
23 | KAFKA_NUM_PARTITIONS: 3
24 | KAFKA_DELETE_RETENTION_MS: 1000
25 | kafka-manager:
26 | image: sheepkiller/kafka-manager
27 | container_name: kafka-manager
28 | environment:
29 | ZK_HOSTS: 127.0.0.1
30 | ports:
31 | - "9009:9000"
32 |
--------------------------------------------------------------------------------
/docker/env/mongo/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | mongodb:
4 | image: mongo
5 | container_name: mongodb
6 | ports:
7 | - 27017:27017
8 | volumes:
9 | - ./database:/data/db
10 | environment:
11 | - MONGO_INITDB_ROOT_USERNAME=admin
12 | - MONGO_INITDB_ROOT_PASSWORD=admin
13 | mongo-express:
14 | image: mongo-express
15 | container_name: mongo-express
16 | restart: always
17 | ports:
18 | - 8181:8081
19 | environment:
20 | - ME_CONFIG_MONGODB_ADMINUSERNAME=admin
21 | - ME_CONFIG_MONGODB_ADMINPASSWORD=admin
22 | - ME_CONFIG_MONGODB_SERVER=mongodb
23 |
24 | networks:
25 | default:
26 | name: mongodb_network
--------------------------------------------------------------------------------
/docker/env/mongo/init-mongo.js:
--------------------------------------------------------------------------------
1 | dbAdmin = db.getSiblingDB("admin");
2 | dbAdmin.createUser({
3 | user: "iot",
4 | pwd: "iot123",
5 | roles: [{ role: "userAdminAnyDatabase", db: "admin" }],
6 | mechanisms: ["SCRAM-SHA-1"],
7 | });
8 |
9 | // Authenticate user
10 | dbAdmin.auth({
11 | user: "iot",
12 | pwd: "iot123",
13 | mechanisms: ["SCRAM-SHA-1"],
14 | digestPassword: true,
15 | });
16 |
17 | use iot;
18 | db.createCollection("calc");
19 | db.createCollection("waring");
20 | db.createCollection("script_waring");
21 |
22 | // todo 导入数据可以在此处操作,或者新建一个单独的用户来操作有权限的库
23 |
--------------------------------------------------------------------------------
/docker/env/mqtt/mock/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.21
2 |
3 | ENV GO111MODULE=on \
4 | GOPROXY=https://goproxy.cn,direct \
5 | GIN_MODE=release \
6 | PORT=80
7 |
8 | WORKDIR /app
9 | COPY . .
10 |
11 |
12 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
13 | ENV TZ=Asia/Shanghai
14 |
15 | RUN go mod download
16 |
17 | RUN go build -o /godocker
18 |
19 |
20 |
21 | EXPOSE 8080
22 |
23 | CMD [ "/godocker" ]
--------------------------------------------------------------------------------
/docker/env/mqtt/mock/go.mod:
--------------------------------------------------------------------------------
1 | module mqtt-mock
2 |
3 | go 1.22
4 |
5 | require (
6 | github.com/eclipse/paho.mqtt.golang v1.4.3
7 | gopkg.in/yaml.v3 v3.0.1
8 | github.com/google/uuid v1.5.0
9 |
10 | )
11 |
12 | require (
13 | github.com/gorilla/websocket v1.5.0 // indirect
14 | golang.org/x/net v0.8.0 // indirect
15 | golang.org/x/sync v0.1.0 // indirect
16 | )
17 |
--------------------------------------------------------------------------------
/docker/env/mqtt/mock/mqtt.yml:
--------------------------------------------------------------------------------
1 | mqtt:
2 | host: tcp://localhost:1883
3 | username: admin
4 | password: admin
5 | port: 1883
6 | size: 10
7 | sleep: 5 # 发送间隔
--------------------------------------------------------------------------------
/docker/env/mqtt/mock/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # 使用nohup命令在后台运行mqtt-mock程序,忽略挂断信号
4 | nohup ./mqtt-mock > output.log 2>&1 &
5 |
6 | echo "mqtt-mock程序已启动,输出将被重定向到output.log"
--------------------------------------------------------------------------------
/docker/env/mqtt/readme.md:
--------------------------------------------------------------------------------
1 | # mqtt 模拟
2 |
3 | 1. 执行如下命令将 mqtt 服务端本地启动
4 |
5 | ```shell
6 | docker-compose up -d
7 | ```
8 |
9 | 2. 使用 golang 程序模拟 n 个 mqtt 硬件
10 |
11 | ```shell
12 | sh mock/build.sh
13 |
14 | ```
--------------------------------------------------------------------------------
/docker/env/mysql/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | mysql:
5 | image: mysql:8.0.38
6 | container_name: mysql8
7 | restart: always
8 | environment:
9 | MYSQL_ROOT_PASSWORD: root123
10 | MYSQL_DATABASE: iot
11 | MYSQL_USER: app
12 | MYSQL_PASSWORD: iot123456
13 | TZ: "Asia/Shanghai"
14 | volumes:
15 | - ./data:/var/lib/mysql
16 | ports:
17 | - "3306:3306"
18 | command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --binlog-format=ROW
19 |
--------------------------------------------------------------------------------
/docker/env/rabbitmq/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rabbitmq:3.10.6-management
2 |
3 | ADD plugins/rabbitmq_delayed_message_exchange-3.10.2.ez /plugins
4 |
5 | # 开启插件
6 | RUN rabbitmq-plugins enable rabbitmq_delayed_message_exchange
7 |
8 | ENTRYPOINT ["rabbitmq-server"]
--------------------------------------------------------------------------------
/docker/env/rabbitmq/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.2"
2 | services:
3 | rabbitmq:
4 | image: rabbitmq:3.13.3-management
5 | container_name: 'rabbitmq'
6 | ports:
7 | - 5672:5672
8 | - 15672:15672
9 | volumes:
10 | - ./data/:/var/lib/rabbitmq/
11 | - ./log/:/var/log/rabbitmq
12 | - ./plugins:/usr/lib/rabbitmq/plugins
13 | - ./enabled_plugins:/etc/rabbitmq/enabled_plugins:rw
14 | environment:
15 | - RABBITMQ_PLUGINS_DIR=/opt/rabbitmq/plugins:/usr/lib/rabbitmq/plugins
16 | networks:
17 | - rabbitmq_go_net
18 |
19 | networks:
20 | rabbitmq_go_net:
21 | driver: bridge
--------------------------------------------------------------------------------
/docker/env/rabbitmq/enabled_plugins:
--------------------------------------------------------------------------------
1 | [rabbitmq_management,rabbitmq_prometheus,rabbitmq_delayed_message_exchange].
--------------------------------------------------------------------------------
/docker/env/rabbitmq/plugins/rabbitmq_delayed_message_exchange-3.10.2.ez:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/docker/env/rabbitmq/plugins/rabbitmq_delayed_message_exchange-3.10.2.ez
--------------------------------------------------------------------------------
/docker/env/redis/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.8'
2 | services:
3 | cache:
4 | image: redis:6.2-alpine
5 | restart: always
6 | ports:
7 | - '6379:6379'
8 | command: redis-server --save 20 1 --loglevel warning --requirepass eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
9 | volumes:
10 | - ./data:/data
11 | - ./conf:/usr/local/etc/redis
12 | - ./log:/var/log/redis
13 | volumes:
14 | cache:
15 | driver: local
16 |
--------------------------------------------------------------------------------
/docker/metricsMonitor/grafana/config/datasources.json:
--------------------------------------------------------------------------------
1 | {
2 | "apiVersion": 1,
3 | "datasources": [
4 | {
5 | "name": "iotPrometheus",
6 | "type": "prometheus",
7 | "url": "http://192.168.3.101:9090",
8 | "isDefault": true
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/docker/metricsMonitor/grafana/config/grafana.ini:
--------------------------------------------------------------------------------
1 | [security]
2 | admin_user = admin
3 |
--------------------------------------------------------------------------------
/docker/metricsMonitor/metrics-monitor-docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | prometheus:
4 | image: bitnami/prometheus:latest
5 | environment:
6 | - TZ=Asia/Shanghai
7 | ports:
8 | - '9090:9090'
9 | volumes:
10 | - ./prometheus/prometheus.yml:/opt/bitnami/prometheus/conf/prometheus.yml
11 | networks:
12 | - iot-metrics-monitor
13 | grafana:
14 | image: grafana/grafana
15 | environment:
16 | - TZ=Asia/Shanghai
17 | - GF_AUTH_ADMIN_PASSWORD=iot123456
18 | ports:
19 | - '9091:3000'
20 | volumes:
21 | - ./grafana/config/grafana.ini:/etc/grafana/grafana.ini
22 | # command: >
23 | # bash -c "/usr/sbin/grafana-cli --config /etc/grafana/grafana.ini datasources import /etc/grafana/provisioning/datasources/datasources.json &&
24 | # /run.sh"
25 | networks:
26 | - iot-metrics-monitor
27 | networks:
28 | iot-metrics-monitor:
29 | driver: bridge
30 |
--------------------------------------------------------------------------------
/docker/rabbitmq/data/.erlang.cookie:
--------------------------------------------------------------------------------
1 | MQYFVUNDKSFGEFEDDIWO
--------------------------------------------------------------------------------
/go-iot-mq/app-local-calc.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 29001
4 | name: mq1
5 | type: calc_queue # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 127.0.0.1
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 |
16 | mq_config:
17 | host: 127.0.0.1
18 | port: 5672
19 | username: guest
20 | password: guest
21 | influx_config:
22 | host: 127.0.0.1
23 | port: 8086
24 | token: mytoken
25 | org: myorg
26 | bucket: mybucket
27 | mongo_config:
28 | host: 127.0.0.1
29 | port: 27017
30 | username: admin
31 | password: admin
32 | db: iot
33 | collection: calc
34 | waring_collection: waring
35 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/app-local-pre_coap_handler.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 39004
4 | name: mq1
5 | type: pre_coap_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 127.0.0.1
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 127.0.0.1
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 127.0.0.1
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/app-local-pre_handler.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 29002
4 | name: mq1
5 | type: pre_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 127.0.0.1
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 127.0.0.1
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 127.0.0.1
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/app-local-pre_http_handler.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 39002
4 | name: mq1
5 | type: pre_http_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 127.0.0.1
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 127.0.0.1
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 127.0.0.1
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/app-local-pre_tcp_handler.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 39005
4 | name: mq1
5 | type: pre_tcp_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 127.0.0.1
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 127.0.0.1
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 127.0.0.1
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/app-local-pre_ws_handler.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 39003
4 | name: mq1
5 | type: pre_ws_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 127.0.0.1
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 127.0.0.1
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 127.0.0.1
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/app-local-transmit.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 39006
4 | name: mq1
5 | type: transmit_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 127.0.0.1
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 127.0.0.1
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 127.0.0.1
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/app-local-waring_handler.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 29003
4 | name: mq1
5 | type: waring_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 127.0.0.1
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 127.0.0.1
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 127.0.0.1
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/app-local-wd.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 29004
4 | name: mq1
5 | type: waring_delay_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 | redis_config:
9 | host: 127.0.0.1
10 | port: 6379
11 | db: 10
12 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
20 | influx_config:
21 | host: 127.0.0.1
22 | port: 8086
23 | token: mytoken
24 | org: myorg
25 | bucket: mybucket
26 | mongo_config:
27 | host: 127.0.0.1
28 | port: 27017
29 | username: admin
30 | password: admin
31 | db: iot
32 | collection: calc
33 | waring_collection: waring
34 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 19000
4 | name: mq1
5 | type: waring_handler # pre_handler、 waring_handler、 calc_queue、waring_delay_handler
6 |
7 |
8 |
9 | redis_config:
10 | host: 127.0.0.1
11 | port: 6379
12 | db: 10
13 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
14 |
15 |
16 |
17 | mq_config:
18 | host: 127.0.0.1
19 | port: 5672
20 | username: guest
21 | password: guest
22 | influx_config:
23 | host: 127.0.0.1
24 | port: 8086
25 | token: i6XHSnNXeUoU3GoFXMm4qqrrgt69JKvQLqm0FCtnYG-rjb-nkDcry0pdwv4fpcXsSwi-mTGmAUTygkJtR-6CWA==
26 | org: myorg
27 | bucket: buc
28 | mongo_config:
29 | host: 127.0.0.1
30 | port: 27017
31 | username: admin
32 | password: admin
33 | db: iot
34 | collection: calc
35 | waring_collection: waring
36 | script_waring_collection: script_waring
--------------------------------------------------------------------------------
/go-iot-mq/handler_transmit.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | amqp "github.com/rabbitmq/amqp091-go"
6 | "go.uber.org/zap"
7 | "iot-transmit/cache"
8 | "iot-transmit/common"
9 | )
10 |
11 | var transmitCacheBiz = cache.TransmitCacheBiz{}
12 |
13 | func HandlerTransmit(messages <-chan amqp.Delivery) {
14 |
15 | go func() {
16 |
17 | for d := range messages {
18 | var data []common.DataRowList
19 |
20 | err := json.Unmarshal(d.Body, &data)
21 |
22 | if err != nil {
23 | zap.S().Error("处理cassandra数据失败", zap.Error(err))
24 | }
25 |
26 | transmitCacheBiz.Run(globalRedisClient, data)
27 | err = d.Ack(false)
28 | if err != nil {
29 | zap.S().Errorf("消息确认异常:%+v", err)
30 |
31 | }
32 | }
33 | }()
34 |
35 | zap.S().Infof(" [*] Waiting for messages. To exit press CTRL+C")
36 | }
37 |
--------------------------------------------------------------------------------
/go-iot-mq/start-calc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | rm -rf output.log
3 | nohup ./gim -config app-local-calc.yml > output.log 2>&1 &
4 |
5 | echo "gim程序已启动,输出将被重定向到output.log"
--------------------------------------------------------------------------------
/go-iot-mq/start-pre.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | rm -rf output.log
3 | nohup ./gim -config app-local-pre_handler.yml > output.log 2>&1 &
4 |
5 | echo "gim程序已启动,输出将被重定向到output.log"
--------------------------------------------------------------------------------
/go-iot-mq/start-waring.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | rm -rf output.log
3 | nohup ./gim -config app-local-waring_handler.yml > output.log 2>&1 &
4 |
5 | echo "gim程序已启动,输出将被重定向到output.log"
--------------------------------------------------------------------------------
/go-iot-mq/start-wd.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | rm -rf output.log
3 | nohup ./gim -config app-local-wd.yml > output.log 2>&1 &
4 |
5 | echo "gim程序已启动,输出将被重定向到output.log"
--------------------------------------------------------------------------------
/go-iot/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/go-iot/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 8081
4 | name: m122222
5 | type: mqtt
6 | size: 3000
7 | redis_config:
8 | host: 127.0.0.1
9 | port: 6379
10 | db: 10
11 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
12 |
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
--------------------------------------------------------------------------------
/go-iot/app-local2.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 18081
4 | name: m2
5 | type: mqtt
6 | size: 3
7 | redis_config:
8 | host: 127.0.0.1
9 | port: 6379
10 | db: 10
11 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
12 |
13 |
14 | mq_config:
15 | host: 127.0.0.1
16 | port: 5672
17 | username: guest
18 | password: guest
--------------------------------------------------------------------------------
/go-iot/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 |
5 |
6 | docker rm -f go_iot
7 | sleep 1
8 | docker rmi -f go_iot:1.0
9 | sleep 1
10 | docker build -t go_iot:1.0 -f Dockerfile .
11 | sleep 1
12 | docker run -d -p8919:8080 --restart=always --name go_iot go_iot:1.0
--------------------------------------------------------------------------------
/go-iot/c.svg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/go-iot/c.svg
--------------------------------------------------------------------------------
/go-iot/redis.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "github.com/redis/go-redis/v9"
7 | "go.uber.org/zap"
8 | )
9 |
10 | var globalRedisClient *redis.Client
11 |
12 | func initGlobalRedisClient(config RedisConfig) {
13 |
14 | add := fmt.Sprintf("%s:%d", config.Host, config.Port)
15 | globalRedisClient = redis.NewClient(&redis.Options{
16 | Addr: add,
17 | Password: config.Password, // 如果没有设置密码,就留空字符串
18 | DB: config.Db, // 使用默认数据库
19 | })
20 |
21 | // 检查连接是否成功
22 | if err := globalRedisClient.Ping(context.Background()).Err(); err != nil {
23 | zap.S().Fatalf("Could not connect to Redis: %v", err)
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/go-iot/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | nohup ./go-iot -config app-local.yml > output.log 2>&1 &
4 |
5 | echo "go-iot程序已启动,输出将被重定向到output.log"
--------------------------------------------------------------------------------
/iot-go-project/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | port: 8080
3 | redis_config:
4 | host: 127.0.0.1
5 | port: 6379
6 | db: 10
7 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
8 |
9 | mq_config:
10 | host: 127.0.0.1
11 | port: 5672
12 | username: guest
13 | password: guest
14 | influx_config:
15 | host: 127.0.0.1
16 | port: 8086
17 | token: mytoken
18 | org: myorg
19 | bucket: mybucket
20 |
21 | mysql_config:
22 | username: root
23 | password: root123@
24 | host: 127.0.0.1
25 | port: 3306
26 | dbname: iot
27 | mongo_config:
28 | host: 127.0.0.1
29 | port: 27017
30 | username: admin
31 | password: admin
32 | db: iot
33 | collection: calc
34 | waring_collection: waring
35 | script_waring_collection: script_waring
36 |
--------------------------------------------------------------------------------
/iot-go-project/biz/calc_rule_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type CalcRuleBiz struct{}
10 |
11 | func (biz *CalcRuleBiz) PageData(name string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var rules []models.CalcRule
14 |
15 | db := glob.GDb
16 |
17 | if name != "" {
18 | db = db.Where("name like ?", "%"+name+"%")
19 | }
20 | db.Model(&models.CalcRule{}).Count(&pagination.Total) // 计算总记录数
21 |
22 | offset := (page - 1) * size
23 | db.Offset(offset).Limit(size).Find(&rules)
24 |
25 | pagination.Data = rules
26 | pagination.Page = page
27 | pagination.Size = size
28 |
29 | return &pagination, nil
30 | }
31 |
--------------------------------------------------------------------------------
/iot-go-project/biz/cron_test.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "testing"
6 | "time"
7 |
8 | "github.com/robfig/cron/v3"
9 | )
10 |
11 | func TestPreviousCronExecutionTime(t *testing.T) {
12 | // 定义一个 6 位 cron 表达式,格式为:秒 分 时 日 月 星期几
13 | schedule := "1 0/1 * * * *"
14 |
15 | // 使用 cron.Parse 函数解析 cron 表达式
16 | c, _ := cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow).Parse(schedule)
17 |
18 | // 可以进一步使用 c.Next(time.Now()) 来获取下一次执行的时间
19 | nextTime := c.Next(time.Now())
20 | glob.GLog.Sugar().Infof("Next run time: %+v", nextTime)
21 | }
22 |
--------------------------------------------------------------------------------
/iot-go-project/biz/dashboard_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type DashboardBiz struct{}
10 |
11 | func (biz *DashboardBiz) PageData(name string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var dashboards []models.Dashboard
14 |
15 | db := glob.GDb
16 |
17 | if name != "" {
18 | db = db.Where("name like ?", "%"+name+"%")
19 | }
20 |
21 | db.Model(&models.Dashboard{}).Count(&pagination.Total) // 计算总记录数
22 | offset := (page - 1) * size
23 | db.Offset(offset).Limit(size).Find(&dashboards)
24 |
25 | pagination.Data = dashboards
26 | pagination.Page = page
27 | pagination.Size = size
28 |
29 | return &pagination, nil
30 | }
31 |
--------------------------------------------------------------------------------
/iot-go-project/biz/device_group_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type DeviceGroupBiz struct{}
10 |
11 | func (biz *DeviceGroupBiz) PageData(name string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var dt []models.DeviceGroup
14 |
15 | db := glob.GDb
16 |
17 | if name != "" {
18 | db = db.Where("name like ?", "%"+name+"%")
19 | }
20 |
21 | db.Model(&models.DeviceGroup{}).Count(&pagination.Total)
22 | offset := (page - 1) * size
23 | db.Offset(offset).Limit(size).Find(&dt)
24 |
25 | pagination.Data = dt
26 | pagination.Page = page
27 | pagination.Size = size
28 |
29 | return &pagination, nil
30 | }
31 |
--------------------------------------------------------------------------------
/iot-go-project/biz/device_install_record_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type DeviceInstallRecordBiz struct{}
10 |
11 | func (biz *DeviceInstallRecordBiz) PageData(sn string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var dt []models.DeviceInstallRecord
14 |
15 | db := glob.GDb
16 |
17 | db.Model(&models.DeviceInstallRecord{}).Count(&pagination.Total)
18 | offset := (page - 1) * size
19 | db.Offset(offset).Limit(size).Find(&dt)
20 |
21 | pagination.Data = dt
22 | pagination.Page = page
23 | pagination.Size = size
24 |
25 | return &pagination, nil
26 | }
27 |
--------------------------------------------------------------------------------
/iot-go-project/biz/message_list_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type MessageListBiz struct{}
10 |
11 | func (biz *MessageListBiz) PageData(messageTypeId string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var dt []models.MessageList
14 |
15 | db := glob.GDb
16 |
17 | if messageTypeId != "" {
18 | db = db.Where("message_type_id = ?", "%"+messageTypeId+"%")
19 | }
20 |
21 | db.Model(&models.MessageList{}).Count(&pagination.Total) // 计算总记录数
22 | offset := (page - 1) * size
23 | db.Offset(offset).Limit(size).Find(&dt)
24 |
25 | pagination.Data = dt
26 | pagination.Page = page
27 | pagination.Size = size
28 |
29 | return &pagination, nil
30 | }
31 |
--------------------------------------------------------------------------------
/iot-go-project/biz/product_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type ProductBiz struct{}
10 |
11 | func (biz *ProductBiz) PageData(name string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var dt []models.Product
14 |
15 | db := glob.GDb
16 |
17 | if name != "" {
18 | db = db.Where("name like ?", "%"+name+"%")
19 | }
20 |
21 | db.Model(&models.Product{}).Count(&pagination.Total)
22 | offset := (page - 1) * size
23 | db.Offset(offset).Limit(size).Find(&dt)
24 |
25 | pagination.Data = dt
26 | pagination.Page = page
27 | pagination.Size = size
28 |
29 | return &pagination, nil
30 | }
31 |
32 | func (biz *ProductBiz) FindById(id uint) *models.Product {
33 |
34 | var Product models.Product
35 |
36 | result := glob.GDb.First(&Product, id)
37 | if result.Error != nil {
38 | return nil
39 | }
40 | return &Product
41 | }
42 |
--------------------------------------------------------------------------------
/iot-go-project/biz/repair_record_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type RepairRecordBiz struct{}
10 |
11 | func (biz *RepairRecordBiz) PageData(sn string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var dt []models.RepairRecord
14 |
15 | db := glob.GDb
16 |
17 | db.Model(&models.RepairRecord{}).Count(&pagination.Total)
18 | offset := (page - 1) * size
19 | db.Offset(offset).Limit(size).Find(&dt)
20 |
21 | pagination.Data = dt
22 | pagination.Page = page
23 | pagination.Size = size
24 |
25 | return &pagination, nil
26 | }
27 |
--------------------------------------------------------------------------------
/iot-go-project/biz/role_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type RoleBiz struct{}
10 |
11 | func (biz *RoleBiz) PageData(name string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var dt []models.Role
14 |
15 | db := glob.GDb
16 |
17 | if name != "" {
18 | db = db.Where("name like ?", "%"+name+"%")
19 | }
20 |
21 | db.Model(&models.Role{}).Count(&pagination.Total) // 计算总记录数
22 | offset := (page - 1) * size
23 | db.Offset(offset).Limit(size).Find(&dt)
24 |
25 | pagination.Data = dt
26 | pagination.Page = page
27 | pagination.Size = size
28 |
29 | return &pagination, nil
30 | }
31 |
32 | func (biz *RoleBiz) FindByUserId(userId uint) []uint {
33 | var roles []models.UserRole
34 | db := glob.GDb
35 | db.Where("user_id = ?", userId).Find(&roles)
36 | var roleIds []uint
37 | for _, v := range roles {
38 | roleIds = append(roleIds, v.RoleId)
39 | }
40 | return roleIds
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/iot-go-project/biz/script_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "github.com/dop251/goja"
5 | "go.uber.org/zap"
6 | "igp/servlet"
7 | )
8 |
9 | type ScriptBiz struct{}
10 |
11 | func (biz *ScriptBiz) CheckScript(param string, script string) *[]servlet.DataRowList {
12 |
13 | vm := goja.New()
14 | _, err := vm.RunString(script)
15 | if err != nil {
16 | zap.S().Errorf("JS代码有问题! %+v", err)
17 | return nil
18 | }
19 | var fn func(string2 string) *[]servlet.DataRowList
20 | err = vm.ExportTo(vm.Get("main"), &fn)
21 | if err != nil {
22 | zap.S().Errorf("Js函数映射到 Go 函数失败! %+v", err)
23 | return nil
24 | }
25 | a := fn(param)
26 | return a
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/iot-go-project/biz/script_list_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type ScriptListBiz struct{}
10 |
11 | func (biz *ScriptListBiz) PageData(name string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var feishu []models.ScriptList
14 |
15 | db := glob.GDb
16 |
17 | if name != "" {
18 | db = db.Where("name like ?", "%"+name+"%")
19 | }
20 |
21 | db.Model(&models.FeiShu{}).Count(&pagination.Total) // 计算总记录数
22 | offset := (page - 1) * size
23 | db.Offset(offset).Limit(size).Find(&feishu)
24 |
25 | pagination.Data = feishu
26 | pagination.Page = page
27 | pagination.Size = size
28 |
29 | return &pagination, nil
30 | }
31 |
--------------------------------------------------------------------------------
/iot-go-project/biz/shipment_record_biz.go:
--------------------------------------------------------------------------------
1 | package biz
2 |
3 | import (
4 | "igp/glob"
5 | "igp/models"
6 | "igp/servlet"
7 | )
8 |
9 | type ShipmentRecordBiz struct{}
10 |
11 | func (biz *ShipmentRecordBiz) PageData(customerName, status string, page, size int) (*servlet.PaginationQ, error) {
12 | var pagination servlet.PaginationQ
13 | var dt []models.ShipmentRecord
14 |
15 | db := glob.GDb
16 |
17 | if status != "" {
18 | db = db.Where("status = ?", status)
19 | }
20 |
21 | if customerName != "" {
22 | db = db.Where("customer_name like ?", "%"+customerName+"%")
23 | }
24 | db.Model(&models.ShipmentRecord{}).Count(&pagination.Total) // 计算总记录数
25 | offset := (page - 1) * size
26 | db.Offset(offset).Limit(size).Find(&dt)
27 |
28 | pagination.Data = dt
29 | pagination.Page = page
30 | pagination.Size = size
31 |
32 | return &pagination, nil
33 | }
34 |
--------------------------------------------------------------------------------
/iot-go-project/models/action.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "gorm.io/gorm"
4 |
5 | // MqttPushAction 消息推送动作
6 | type MqttPushAction struct {
7 |
8 | gorm.Model `structs:"-"`
9 |
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/iot-go-project/models/valicate.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "errors"
5 | "time"
6 | )
7 |
8 | type Validate interface {
9 | Validate() error
10 | }
11 |
12 | // Validate 验证SimCard实例是否满足业务规则
13 | func (card *SimCard) Validate() error {
14 | // 验证接入号
15 | if card.AccessNumber == "" {
16 | return errors.New("接入号不能为空")
17 | }
18 |
19 | // 验证集成电路卡识别码
20 | if card.ICCID == "" {
21 | return errors.New("集成电路卡识别码不能为空")
22 | }
23 |
24 | // 验证国际移动用户识别码
25 | if card.IMSI == "" {
26 | return errors.New("国际移动用户识别码不能为空")
27 | }
28 |
29 | // 验证运营商名称
30 | if card.Operator == "" {
31 | return errors.New("运营商名称不能为空")
32 | }
33 |
34 | // 验证到期时间是否为未来时间
35 | if card.Expiration.Before(time.Now()) {
36 | return errors.New("到期时间必须是未来的日期")
37 | }
38 |
39 | // 如果所有验证都通过,则返回nil表示没有错误
40 | return nil
41 | }
42 |
--------------------------------------------------------------------------------
/iot-go-project/readme.md:
--------------------------------------------------------------------------------
1 | # Iot Go Project
2 |
3 | 后台管理端项目,主要用于完成基础数据的统一管理。
4 |
5 | - swagger 文档生产指令
6 | ```shell
7 | swag init --parseDependency --parseInternal --parseDepth 5 --instanceName "swagger"
8 |
9 | ```
--------------------------------------------------------------------------------
/iot-go-project/router/promethues.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "fmt"
5 | "github.com/newrelic/go-agent/v3/newrelic"
6 | "os"
7 | )
8 |
9 | func Mem() {
10 | }
11 |
12 | func NewRelicConfig() *newrelic.Application {
13 | app, err := newrelic.NewApplication(
14 | newrelic.ConfigAppName("管理后台"),
15 | newrelic.ConfigLicense("mit"),
16 | newrelic.ConfigCodeLevelMetricsEnabled(true),
17 | newrelic.ConfigAppLogForwardingEnabled(true),
18 | )
19 | if nil != err {
20 | fmt.Printf("New Relic initialization failed: %v", err)
21 | os.Exit(1)
22 | }
23 |
24 | return app
25 | }
26 |
--------------------------------------------------------------------------------
/iot-go-project/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # 使用nohup命令在后台运行igp程序,忽略挂断信号
4 | nohup ./igp -config app-node1.yml > output.log 2>&1 &
5 |
6 | echo "igp程序已启动,输出将被重定向到output.log"
--------------------------------------------------------------------------------
/notice/readme.md:
--------------------------------------------------------------------------------
1 | # notice
2 | 通知服务
3 |
4 | 钉钉通知
5 |
6 | 目前只针对单个信号报警进行通知,脚本模式的暂时不支持
--------------------------------------------------------------------------------
/notice/sender/ding_sender.go:
--------------------------------------------------------------------------------
1 | package sender
2 |
3 | type DingSender struct {
4 | AccessToken string
5 | Sec string
6 | }
7 |
8 | func (s *DingSender) Init(msg string, to []string) error {
9 | return nil
10 | }
11 |
--------------------------------------------------------------------------------
/notice/sender/sender.go:
--------------------------------------------------------------------------------
1 | package sender
2 |
3 | type Sender interface {
4 | Send(msg string) error
5 | }
6 |
--------------------------------------------------------------------------------
/operation/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/image.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606094255537.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606094255537.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606094311563.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606094311563.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606094417071.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606094417071.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606094431736.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606094431736.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606095128822.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606095128822.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606095204696.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606095204696.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606095303850.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606095303850.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606095609024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606095609024.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606101016121.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606101016121.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606101935355.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606101935355.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606102215355.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606102215355.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606102407166.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606102407166.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606102427935.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606102427935.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606102919129.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606102919129.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606102937751.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606102937751.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606103447234.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606103447234.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606103550811.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606103550811.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606103946874.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606103946874.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606103953112.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606103953112.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606104453746.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606104453746.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606104745498.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606104745498.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606105047390.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606105047390.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606105138761.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606105138761.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606105443413.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606105443413.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606105502418.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606105502418.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606105928178.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606105928178.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606105954148.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606105954148.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606110124477.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606110124477.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606110140876.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606110140876.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606110528155.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606110528155.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606110554774.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606110554774.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606110630063.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606110630063.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606110653819.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606110653819.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606111305558.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606111305558.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606111429126.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606111429126.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606111609969.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606111609969.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606111858944.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606111858944.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606111939061.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606111939061.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606112501476.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606112501476.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606112518583.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606112518583.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606112841272.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606112841272.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606112945960.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606112945960.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606112959902.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606112959902.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606123826130.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606123826130.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606123927495.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606123927495.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606124428648.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606124428648.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606124444863.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606124444863.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606124936036.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606124936036.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606125101076.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606125101076.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606125408906.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606125408906.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606125650440.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606125650440.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606125710860.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606125710860.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606125743694.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606125743694.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606125841654.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606125841654.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606130011982.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606130011982.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606130045585.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606130045585.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606130457564.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606130457564.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606130509502.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606130509502.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606130856586.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606130856586.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606130923434.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606130923434.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606130959242.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606130959242.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606135730782.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606135730782.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606135808693.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606135808693.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606135902648.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606135902648.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606140147152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606140147152.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606142743931.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606142743931.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606142934074.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606142934074.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606143003737.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606143003737.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606143149691.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606143149691.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606143413851.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606143413851.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606143635353.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606143635353.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606144929189.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606144929189.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606145602958.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606145602958.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606145659098.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606145659098.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606145847500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606145847500.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606145948476.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606145948476.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606150004980.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606150004980.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606150154486.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606150154486.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606150726511.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606150726511.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606150805927.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606150805927.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606150858294.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606150858294.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606151858847.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606151858847.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606151915415.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606151915415.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606152036372.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606152036372.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606152220117.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606152220117.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606152257812.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606152257812.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606152646143.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606152646143.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606152945561.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606152945561.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606153511205.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606153511205.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606153911041.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606153911041.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606153937040.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606153937040.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606154524267.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606154524267.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606154921513.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606154921513.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606155158429.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606155158429.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606155217737.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606155217737.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606155540984.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606155540984.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606155657395.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606155657395.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606155727562.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606155727562.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606155844230.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606155844230.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606160355023.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606160355023.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606160413988.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606160413988.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606160958746.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606160958746.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606161321205.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606161321205.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606161425423.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606161425423.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606161520450.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606161520450.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606161535507.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606161535507.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606161646066.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606161646066.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606161712411.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606161712411.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606161744750.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606161744750.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606161904468.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606161904468.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606162113076.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606162113076.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606162136009.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606162136009.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606162252098.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606162252098.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606162307908.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606162307908.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606162721881.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606162721881.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606162939311.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606162939311.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606163142021.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606163142021.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606163211691.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606163211691.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606163315820.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606163315820.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606163335959.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606163335959.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606163441432.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606163441432.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606163457246.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606163457246.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606163553406.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606163553406.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606163900046.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606163900046.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606163916249.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606163916249.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606164219841.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606164219841.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606164308715.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606164308715.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606164324452.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606164324452.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606164753125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606164753125.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606164806521.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606164806521.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606164936877.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606164936877.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606165008936.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606165008936.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606165106823.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606165106823.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606165223720.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606165223720.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606165725939.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606165725939.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606165740680.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606165740680.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606165858358.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606165858358.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170209153.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170209153.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170230662.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170230662.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170243011.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170243011.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170327143.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170327143.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170412260.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170412260.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170511155.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170511155.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170549901.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170549901.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170711994.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170711994.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170832389.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170832389.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606170845707.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606170845707.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606171045130.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606171045130.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240606171235567.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240606171235567.png
--------------------------------------------------------------------------------
/operation/操作文档/image-20240607163432931.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/operation/操作文档/image-20240607163432931.png
--------------------------------------------------------------------------------
/protocol/coap/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 5683
4 | name: copa-server-1
5 | type: coap
6 | size: 3
7 | redis_config:
8 | host: 127.0.0.1
9 | port: 6379
10 | db: 10
11 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
12 |
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
--------------------------------------------------------------------------------
/protocol/coap/beat.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "time"
7 |
8 | "go.uber.org/zap"
9 | )
10 |
11 | // registerInfo 注册节点信息
12 | func registerInfo(node *NodeInfo) {
13 | zap.S().Debugf("registerInfo 开始, node = %v", node)
14 |
15 | jsonData, _ := json.Marshal(node)
16 | globalRedisClient.Set(context.Background(), "pod:info:coap:"+node.Name, jsonData, 1*time.Hour)
17 |
18 | }
19 | func BeatTask(f NodeInfo) {
20 | zap.S().Debugf("BeatTask 开始, f = %v", f)
21 | registerInfo(&f)
22 |
23 | ticker := time.NewTicker(1 * time.Hour)
24 | for range ticker.C {
25 | registerInfo(&f)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/protocol/coap/data_handler_st.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "context"
4 |
5 | func DataHandlerCount(){
6 | globalRedisClient.Incr(context.Background(),"count:copa:"+globalConfig.NodeInfo.Name)
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/protocol/coap/redis.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "github.com/redis/go-redis/v9"
7 | "go.uber.org/zap"
8 | )
9 |
10 | var globalRedisClient *redis.Client
11 |
12 | func initGlobalRedisClient(config RedisConfig) {
13 |
14 | add := fmt.Sprintf("%s:%d", config.Host, config.Port)
15 | globalRedisClient = redis.NewClient(&redis.Options{
16 | Addr: add,
17 | Password: config.Password, // 如果没有设置密码,就留空字符串
18 | DB: config.Db, // 使用默认数据库
19 | })
20 |
21 | // 检查连接是否成功
22 | if err := globalRedisClient.Ping(context.Background()).Err(); err != nil {
23 | zap.S().Fatalf("Could not connect to Redis: %v", err)
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/protocol/http/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 8888
4 | name: http1
5 | redis_config:
6 | host: 127.0.0.1
7 | port: 6379
8 | db: 10
9 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
10 |
11 |
12 |
13 | mq_config:
14 | host: 127.0.0.1
15 | port: 5672
16 | username: guest
17 | password: guest
--------------------------------------------------------------------------------
/protocol/http/beat.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "time"
7 |
8 | "go.uber.org/zap"
9 | )
10 |
11 | // registerInfo 注册节点信息
12 | func registerInfo(node *NodeInfo) {
13 | zap.S().Infof("registerInfo 开始, node = %v", node)
14 | jsonData, _ := json.Marshal(node)
15 | globalRedisClient.Set(context.Background(), "pod:info:http:"+node.Name, jsonData, 1*time.Hour)
16 |
17 | }
18 | func BeatTask(f NodeInfo) {
19 | zap.S().Infof("BeatTask 开始, f = %v", f)
20 | registerInfo(&f)
21 |
22 | ticker := time.NewTicker(1 * time.Hour)
23 | for range ticker.C {
24 | registerInfo(&f)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/protocol/modbus/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 3332
4 | redis_config:
5 | host: 127.0.0.1
6 | port: 6379
7 | db: 10
8 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
9 |
10 |
11 |
12 | mq_config:
13 | host: 127.0.0.1
14 | port: 5672
15 | username: guest
16 | password: guest
--------------------------------------------------------------------------------
/protocol/modbus/go.mod:
--------------------------------------------------------------------------------
1 | module iot-modbus
2 |
3 | go 1.22
4 |
5 | require (
6 | github.com/goburrow/modbus v0.1.0
7 | github.com/google/uuid v1.6.0
8 | github.com/rabbitmq/amqp091-go v1.10.0
9 | github.com/redis/go-redis/v9 v9.6.0
10 | github.com/tbrandon/mbserver v0.0.0-20231208015628-36eb59221ac2
11 | go.uber.org/zap v1.27.0
12 | )
13 |
14 | require (
15 | github.com/cespare/xxhash/v2 v2.2.0 // indirect
16 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
17 | github.com/goburrow/serial v0.1.0 // indirect
18 | go.uber.org/multierr v1.10.0 // indirect
19 | )
20 |
--------------------------------------------------------------------------------
/protocol/modbus/redis.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "github.com/redis/go-redis/v9"
7 | "go.uber.org/zap"
8 | )
9 |
10 | var globalRedisClient *redis.Client
11 |
12 | func initGlobalRedisClient(config RedisConfig) {
13 |
14 | add := fmt.Sprintf("%s:%d", config.Host, config.Port)
15 | globalRedisClient = redis.NewClient(&redis.Options{
16 | Addr: add,
17 | Password: config.Password, // 如果没有设置密码,就留空字符串
18 | DB: config.Db, // 使用默认数据库
19 | })
20 |
21 | // 检查连接是否成功
22 | if err := globalRedisClient.Ping(context.Background()).Err(); err != nil {
23 | zap.S().Fatalf("Could not connect to Redis: %v", err)
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/protocol/modbus/sample/client/client.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/goburrow/modbus"
7 | )
8 |
9 | func main() {
10 | handler := modbus.NewTCPClientHandler("localhost:1502")
11 | // Connect manually so that multiple requests are handled in one session
12 | err := handler.Connect()
13 | defer handler.Close()
14 | client := modbus.NewClient(handler)
15 |
16 |
17 |
18 | _, err = client.WriteMultipleRegisters(0, 5, []byte{0, 1, 0, 4, 0, 5, 1, 1, 1, 2})
19 | if err != nil {
20 | fmt.Printf("%v\n", err)
21 | }
22 |
23 | results, err := client.ReadHoldingRegisters(0, 5)
24 | if err != nil {
25 | fmt.Printf("%v\n", err)
26 | }
27 | fmt.Printf("results %v\n", results)
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/protocol/modbus/sample/server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "time"
6 |
7 | "github.com/tbrandon/mbserver"
8 | )
9 |
10 | func main() {
11 | serv := mbserver.NewServer()
12 | err := serv.ListenTCP("127.0.0.1:1502")
13 | if err != nil {
14 | log.Printf("%v\n", err)
15 | }
16 | defer serv.Close()
17 | // Wait forever
18 | serv.RegisterFunctionHandler(1, func(s *mbserver.Server, f mbserver.Framer) ([]byte, *mbserver.Exception) {
19 | log.Printf("Function 1 called\n")
20 | return []byte{0x01, 0x02}, nil
21 | })
22 |
23 | for {
24 | time.Sleep(1 * time.Second)
25 | }
26 | }
--------------------------------------------------------------------------------
/protocol/readme/image-20240725103427236.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/protocol/readme/image-20240725103427236.png
--------------------------------------------------------------------------------
/protocol/tcp/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 3332
4 | name: tcp-01
5 | type: tcp-server
6 | size: 1
7 | redis_config:
8 | host: 127.0.0.1
9 | port: 6379
10 | db: 10
11 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
12 |
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
--------------------------------------------------------------------------------
/protocol/tcp/beat.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "time"
7 |
8 | "go.uber.org/zap"
9 | )
10 |
11 | // registerInfo 注册节点信息
12 | func registerInfo(node *NodeInfo) {
13 | zap.S().Infof("registerInfo 开始, node = %v", node)
14 | jsonData, _ := json.Marshal(node)
15 | globalRedisClient.Set(context.Background(), "pod:info:tcp:"+node.Name, jsonData, 1*time.Hour)
16 |
17 | }
18 | func BeatTask(f NodeInfo) {
19 | zap.S().Infof("BeatTask 开始, f = %v", f)
20 | registerInfo(&f)
21 |
22 | ticker := time.NewTicker(1 * time.Hour)
23 | for range ticker.C {
24 | registerInfo(&f)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/protocol/tcp/go.mod:
--------------------------------------------------------------------------------
1 | module iot-tcp
2 |
3 | go 1.22.4
4 |
5 | require (
6 | github.com/google/uuid v1.6.0
7 | github.com/prometheus/client_golang v1.20.4
8 | github.com/rabbitmq/amqp091-go v1.10.0
9 | github.com/redis/go-redis/v9 v9.6.0
10 | go.uber.org/zap v1.27.0
11 | gopkg.in/yaml.v3 v3.0.1
12 | )
13 |
14 | require (
15 | github.com/beorn7/perks v1.0.1 // indirect
16 | github.com/cespare/xxhash/v2 v2.3.0 // indirect
17 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
18 | github.com/klauspost/compress v1.17.9 // indirect
19 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
20 | github.com/prometheus/client_model v0.6.1 // indirect
21 | github.com/prometheus/common v0.55.0 // indirect
22 | github.com/prometheus/procfs v0.15.1 // indirect
23 | go.uber.org/multierr v1.10.0 // indirect
24 | golang.org/x/sys v0.22.0 // indirect
25 | google.golang.org/protobuf v1.34.2 // indirect
26 | )
27 |
--------------------------------------------------------------------------------
/protocol/tcp/redis.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "github.com/redis/go-redis/v9"
7 | "go.uber.org/zap"
8 | )
9 |
10 | var globalRedisClient *redis.Client
11 |
12 | func initGlobalRedisClient(config RedisConfig) {
13 |
14 | add := fmt.Sprintf("%s:%d", config.Host, config.Port)
15 | globalRedisClient = redis.NewClient(&redis.Options{
16 | Addr: add,
17 | Password: config.Password, // 如果没有设置密码,就留空字符串
18 | DB: config.Db, // 使用默认数据库
19 | })
20 |
21 | // 检查连接是否成功
22 | if err := globalRedisClient.Ping(context.Background()).Err(); err != nil {
23 | zap.S().Fatalf("Could not connect to Redis: %v", err)
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/protocol/tcp/server_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "testing"
4 |
5 | func TestServer(t *testing.T) {
6 | server := New(&Config{
7 | Host: "localhost",
8 | Port: "3333",
9 | })
10 | server.Run()
11 | }
--------------------------------------------------------------------------------
/protocol/ws/app-local.yml:
--------------------------------------------------------------------------------
1 | node_info:
2 | host: 127.0.0.1
3 | port: 13333
4 | size: 10
5 | name: ws1
6 | type: websocket-server
7 | redis_config:
8 | host: 127.0.0.1
9 | port: 6379
10 | db: 10
11 | password: eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
12 |
13 |
14 |
15 | mq_config:
16 | host: 127.0.0.1
17 | port: 5672
18 | username: guest
19 | password: guest
--------------------------------------------------------------------------------
/protocol/ws/beat.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "time"
7 |
8 | "go.uber.org/zap"
9 | )
10 |
11 | // registerInfo 注册节点信息
12 | func registerInfo(node *NodeInfo) {
13 | zap.S().Infof("registerInfo 开始, node = %v", node)
14 |
15 | jsonData, _ := json.Marshal(node)
16 | globalRedisClient.Set(context.Background(), "pod:info:ws:"+node.Name, jsonData, 1*time.Hour)
17 |
18 | }
19 | func BeatTask(f NodeInfo) {
20 | zap.S().Infof("BeatTask 开始, f = %v", f)
21 | registerInfo(&f)
22 |
23 | ticker := time.NewTicker(1 * time.Hour)
24 | for range ticker.C {
25 | registerInfo(&f)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/protocol/ws/redis.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "github.com/redis/go-redis/v9"
7 | "go.uber.org/zap"
8 | )
9 |
10 | var globalRedisClient *redis.Client
11 |
12 | func initGlobalRedisClient(config RedisConfig) {
13 |
14 | add := fmt.Sprintf("%s:%d", config.Host, config.Port)
15 | globalRedisClient = redis.NewClient(&redis.Options{
16 | Addr: add,
17 | Password: config.Password, // 如果没有设置密码,就留空字符串
18 | DB: config.Db, // 使用默认数据库
19 | })
20 |
21 | // 检查连接是否成功
22 | if err := globalRedisClient.Ping(context.Background()).Err(); err != nil {
23 | zap.S().Fatalf("Could not connect to Redis: %v", err)
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/protocol/ws/template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 | hello
9 |
33 |
34 |
--------------------------------------------------------------------------------
/readme/image-20240524123513247.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/image-20240524123513247.png
--------------------------------------------------------------------------------
/readme/image-20240524123533112.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/image-20240524123533112.png
--------------------------------------------------------------------------------
/readme/image-20240524123606435.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/image-20240524123606435.png
--------------------------------------------------------------------------------
/readme/image-20240524123618542.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/image-20240524123618542.png
--------------------------------------------------------------------------------
/readme/image-20240524123658849.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/image-20240524123658849.png
--------------------------------------------------------------------------------
/readme/image-20240524123718443.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/image-20240524123718443.png
--------------------------------------------------------------------------------
/readme/image-20240524123729546.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/image-20240524123729546.png
--------------------------------------------------------------------------------
/readme/image-20240524123805587.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/image-20240524123805587.png
--------------------------------------------------------------------------------
/readme/image-20240524123820684.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/image-20240524123820684.png
--------------------------------------------------------------------------------
/readme/o1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/o1.png
--------------------------------------------------------------------------------
/readme/数据图.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/数据图.jpg
--------------------------------------------------------------------------------
/readme/架构图.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/架构图.png
--------------------------------------------------------------------------------
/readme/网络-数据结构图.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/readme/网络-数据结构图.png
--------------------------------------------------------------------------------
/roadmap.md:
--------------------------------------------------------------------------------
1 | # 开发路线
2 | - [x] MQTT 客户端集群方案
3 | - [x] 数据解析(JavaScript)
4 | - [ ] 数据解析 (Lua)
5 | - [ ] 数据解析(Python)
6 | - [x] 数据存储(influxdb)
7 | - [x] 数据报警(区间比较、脚本比较)
8 | - 数据利用
9 | - [ ] 折线图+柱状图的可配置化展示
10 | - [ ] 基于JavaScript的统计功能(低代码)
11 | - [ ] 系统内通知
12 | - [ ] 系统外通知(微信公众号、钉钉、邮件)
13 | - [ ] 飞书机器人
14 | - [ ] 钉钉机器人
15 | - 数据转发
16 | - [ ] kafka
17 | - [ ] influxdb
18 | - [ ] cassandra
19 | - [ ] clickhouse
20 | - [ ] mongo
21 | - [ ] mysql
22 | - [ ] rabbit
23 | - [ ] rocket
24 | - 开源结合
25 | - [ ] Flink
26 | - [ ] Kafka Stream
27 | - [ ] Spark
28 | - [ ] doris
29 | - AI 结合
30 | - [ ] 时序预测
31 | - 标准协议对接
32 | - [ ] JT808
33 | - [ ] OCPP
34 | - 运营管理
35 | - [ ] 用户模块
36 | - [ ] 运维模块
37 | - 通讯协议对接
38 | - [x] MQTT
39 | - [x] HTTP
40 | - [x] WEBSOCKET
41 | - [ ] MODBUS
42 | - [X] TCP/IP
43 | - [ ] 硬件版本管理(OTA)
44 | - [ ] 报警后置行为
--------------------------------------------------------------------------------
/swagger.sh:
--------------------------------------------------------------------------------
1 | swag init --output=./iot-go-project/docs --dir=./iot-go-project,./notice --parseDependency --parseInternal --parseDepth 5 --instanceName "swagger"
2 |
--------------------------------------------------------------------------------
/test/2.txt:
--------------------------------------------------------------------------------
1 | TT_44
2 | TT_4
3 | TT_93
4 | TT_35
5 | TT_74
6 | TT_22
7 | TT_15
8 | TT_92
9 | TT_9
10 | TT_53
11 | TT_47
12 | TT_33
13 | TT_12
14 | TT_39
15 | TT_32
16 | TT_17
17 | TT_87
18 | TT_18
19 | TT_80
20 | TT_14
21 | TT_1
22 | TT_85
23 | TT_8
24 | TT_58
25 | TT_73
26 | TT_11
27 | TT_5
28 | TT_6
29 | TT_99
30 | TT_42
31 | TT_37
32 | TT_45
33 | TT_51
34 | TT_36
35 | TT_34
36 | TT_0
37 | TT_84
38 | TT_67
39 | TT_69
40 | TT_71
41 | TT_61
42 | TT_7
43 | TT_28
44 | TT_75
45 | TT_98
46 | TT_95
47 | TT_49
48 | TT_29
49 | TT_54
50 | TT_19
51 | TT_38
52 | TT_65
53 | TT_27
54 | TT_13
55 | TT_10
56 | TT_86
57 | TT_40
58 | TT_70
59 | TT_3
60 | TT_46
61 | TT_76
62 | TT_23
63 | TT_55
64 | TT_26
65 | TT_68
66 | TT_82
67 | TT_63
68 | TT_48
69 | TT_20
70 | TT_97
71 | TT_81
72 | TT_62
73 | TT_57
--------------------------------------------------------------------------------
/test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.22.4
2 |
3 | ENV GO111MODULE=on \
4 | GOPROXY=https://goproxy.cn,direct \
5 | GIN_MODE=release \
6 | PORT=80
7 |
8 | WORKDIR /app
9 | COPY . .
10 |
11 |
12 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
13 | ENV TZ=Asia/Shanghai
14 |
15 | RUN go mod tidy
16 |
17 | RUN go build -o /godocker
18 |
19 |
20 |
21 | EXPOSE 11111
22 |
23 | CMD [ "/godocker" ]
--------------------------------------------------------------------------------
/test/check.py:
--------------------------------------------------------------------------------
1 | # 读取 txt 文件,每一行都是字符串,加入到数组中,去掉换行符
2 | def read_txt(file_path):
3 | with open(file_path, "r") as f:
4 | lines = f.readlines()
5 | for i in range(len(lines)):
6 | lines[i] = lines[i].strip()
7 | return lines
8 |
9 | nodebind = read_txt("1.txt")
10 |
11 | mqtt_config = read_txt("2.txt")
12 |
13 | # 对比 nodebind 和 mqtt_config 求差异元素
14 | def compare(nodebind, mqtt_config):
15 | nodebind_set = set(nodebind)
16 | print(nodebind_set)
17 | mqtt_config_set = set(mqtt_config)
18 | print(mqtt_config_set)
19 | return mqtt_config_set.difference(nodebind_set)
20 |
21 | print(compare(nodebind, mqtt_config))
--------------------------------------------------------------------------------
/test/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | mqtttest:
3 | image: mqtttest:latest
4 | build:
5 | context: .
6 | dockerfile: Dockerfile
7 | entrypoint: ["/godocker"]
8 | environment:
9 | - TZ=Asia/Shanghai
10 | ports:
11 | - 11111:11111
12 | networks:
13 | - iot-net
14 | networks:
15 | iot-net:
16 | driver: bridge
17 |
--------------------------------------------------------------------------------
/test/go.mod:
--------------------------------------------------------------------------------
1 | module iot-test
2 |
3 | go 1.22.4
4 |
5 | require (
6 | github.com/eclipse/paho.mqtt.golang v1.5.0
7 | github.com/google/uuid v1.6.0
8 | go.uber.org/zap v1.27.0
9 | gopkg.in/natefinch/lumberjack.v2 v2.2.1
10 | )
11 |
12 | require (
13 | github.com/gorilla/websocket v1.5.3 // indirect
14 | go.uber.org/multierr v1.10.0 // indirect
15 | golang.org/x/net v0.27.0 // indirect
16 | golang.org/x/sync v0.7.0 // indirect
17 | )
18 |
--------------------------------------------------------------------------------
/test/init_redis.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Redis服务器地址
4 | REDIS_HOST="localhost"
5 | # Redis服务器端口
6 | REDIS_PORT="6379"
7 | # Redis密码
8 | REDIS_PASSWORD="eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81"
9 |
10 | # 连接到Redis服务器并进行身份验证
11 | redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD < /etc/timezone
13 | ENV TZ=Asia/Shanghai
14 |
15 | RUN go mod tidy
16 |
17 | RUN go build -o /godocker
18 |
19 |
20 |
21 | EXPOSE 11111
22 |
23 | CMD [ "/godocker" ]
--------------------------------------------------------------------------------
/test/mock_coap/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | mock-coap:
3 | image: mock_coap:latest
4 | build:
5 | context: .
6 | dockerfile: Dockerfile
7 | entrypoint: ["/godocker"]
8 | environment:
9 | - TZ=Asia/Shanghai
10 | ports:
11 | - 11112:11111
12 | networks:
13 | - iot-net
14 | networks:
15 | iot-net:
16 | driver: bridge
17 |
--------------------------------------------------------------------------------
/test/mock_coap/go.mod:
--------------------------------------------------------------------------------
1 | module mock_coap
2 |
3 | go 1.22.4
4 |
5 | require github.com/dustin/go-coap v0.0.0-20190908170653-752e0f79981e
6 |
--------------------------------------------------------------------------------
/test/mock_coap/go.sum:
--------------------------------------------------------------------------------
1 | github.com/dustin/go-coap v0.0.0-20190908170653-752e0f79981e h1:oppjHFVTardH+VyOD32F9uBtgT5Wd/qVqEGcwj389Lc=
2 | github.com/dustin/go-coap v0.0.0-20190908170653-752e0f79981e/go.mod h1:as2rZ2aojRzZF8bGx1bPAn1yi9ICG6LwkiPOj6PBtjc=
3 |
--------------------------------------------------------------------------------
/test/mock_coap/start_mock_coap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | docker-compose -f ./docker-compose.yml down
3 | docker rmi mock_coap:latest
4 | docker-compose -f ./docker-compose.yml up -d
5 | echo "coap设备模拟启动"
6 |
--------------------------------------------------------------------------------
/test/mock_http/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.22.4
2 |
3 | ENV GO111MODULE=on \
4 | GOPROXY=https://goproxy.cn,direct \
5 | GIN_MODE=release \
6 | PORT=80
7 |
8 | WORKDIR /app
9 | COPY . .
10 |
11 |
12 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
13 | ENV TZ=Asia/Shanghai
14 |
15 | RUN go mod tidy
16 |
17 | RUN go build -o /godocker
18 |
19 |
20 |
21 | EXPOSE 11111
22 |
23 | CMD [ "/godocker" ]
--------------------------------------------------------------------------------
/test/mock_http/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | mock-http:
3 | image: mock_http:latest
4 | build:
5 | context: .
6 | dockerfile: Dockerfile
7 | entrypoint: ["/godocker"]
8 | environment:
9 | - TZ=Asia/Shanghai
10 | ports:
11 | - 11113:11111
12 | networks:
13 | - iot-net
14 | networks:
15 | iot-net:
16 | driver: bridge
17 |
--------------------------------------------------------------------------------
/test/mock_http/go.mod:
--------------------------------------------------------------------------------
1 | module mock_http
2 |
3 | go 1.22.4
4 |
5 | require github.com/dustin/go-coap v0.0.0-20190908170653-752e0f79981e
6 |
--------------------------------------------------------------------------------
/test/mock_http/go.sum:
--------------------------------------------------------------------------------
1 | github.com/dustin/go-coap v0.0.0-20190908170653-752e0f79981e h1:oppjHFVTardH+VyOD32F9uBtgT5Wd/qVqEGcwj389Lc=
2 | github.com/dustin/go-coap v0.0.0-20190908170653-752e0f79981e/go.mod h1:as2rZ2aojRzZF8bGx1bPAn1yi9ICG6LwkiPOj6PBtjc=
3 |
--------------------------------------------------------------------------------
/test/mock_http/start_mock_http.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | docker-compose -f ./docker-compose.yml down
3 | docker rmi mock_http:latest
4 | docker-compose -f ./docker-compose.yml up -d
5 | echo "http设备模拟启动"
6 |
--------------------------------------------------------------------------------
/test/mock_mqtt/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.22.4
2 |
3 | ENV GO111MODULE=on \
4 | GOPROXY=https://goproxy.cn,direct \
5 | GIN_MODE=release \
6 | PORT=80
7 |
8 | WORKDIR /app
9 | COPY . .
10 |
11 |
12 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
13 | ENV TZ=Asia/Shanghai
14 |
15 | RUN go mod tidy
16 |
17 | RUN go build -o /godocker
18 |
19 |
20 |
21 | EXPOSE 11111
22 |
23 | CMD [ "/godocker" ]
--------------------------------------------------------------------------------
/test/mock_mqtt/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | mock-mqtt:
3 | image: mock_mqtt:latest
4 | build:
5 | context: .
6 | dockerfile: Dockerfile
7 | entrypoint: ["/godocker"]
8 | environment:
9 | - TZ=Asia/Shanghai
10 | ports:
11 | - 11111:11111
12 | networks:
13 | - iot-net
14 | networks:
15 | iot-net:
16 | driver: bridge
17 |
--------------------------------------------------------------------------------
/test/mock_mqtt/go.mod:
--------------------------------------------------------------------------------
1 | module iot-test
2 |
3 | go 1.22.4
4 |
5 | require (
6 | github.com/eclipse/paho.mqtt.golang v1.5.0
7 | github.com/google/uuid v1.6.0
8 | go.uber.org/zap v1.27.0
9 | gopkg.in/natefinch/lumberjack.v2 v2.2.1
10 | )
11 |
12 | require (
13 | github.com/gorilla/websocket v1.5.3 // indirect
14 | go.uber.org/multierr v1.10.0 // indirect
15 | golang.org/x/net v0.27.0 // indirect
16 | golang.org/x/sync v0.7.0 // indirect
17 | )
18 |
--------------------------------------------------------------------------------
/test/mock_mqtt/go.sum:
--------------------------------------------------------------------------------
1 | github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
2 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
3 | github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
4 | go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
5 | go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
6 | golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
7 | golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
8 | gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
9 |
--------------------------------------------------------------------------------
/test/mock_mqtt/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func main() {
4 | go main2()
5 | select {
6 |
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/mock_mqtt/start_mock_mqtt.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | docker-compose -f ./docker-compose.yml down
3 | docker rmi mock_mqtt:latest
4 | docker-compose -f ./docker-compose.yml up -d
5 | echo "mqtt设备模拟启动"
6 |
--------------------------------------------------------------------------------
/test/mock_tcp/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.22.4
2 |
3 | ENV GO111MODULE=on \
4 | GOPROXY=https://goproxy.cn,direct \
5 | GIN_MODE=release \
6 | PORT=80
7 |
8 | WORKDIR /app
9 | COPY . .
10 |
11 |
12 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
13 | ENV TZ=Asia/Shanghai
14 |
15 | RUN go mod tidy
16 |
17 | RUN go build -o /godocker
18 |
19 |
20 |
21 | EXPOSE 11111
22 |
23 | CMD [ "/godocker" ]
--------------------------------------------------------------------------------
/test/mock_tcp/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | mock-tcp:
3 | image: mock_tcp:latest
4 | build:
5 | context: .
6 | dockerfile: Dockerfile
7 | entrypoint: ["/godocker"]
8 | environment:
9 | - TZ=Asia/Shanghai
10 | ports:
11 | - 11114:11111
12 | networks:
13 | - iot-net
14 | networks:
15 | iot-net:
16 | driver: bridge
17 |
--------------------------------------------------------------------------------
/test/mock_tcp/go.mod:
--------------------------------------------------------------------------------
1 | module mock_tcp
2 |
3 | go 1.22.4
4 |
--------------------------------------------------------------------------------
/test/mock_tcp/start_mock_tcp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | docker-compose -f ./docker-compose.yml down
3 | docker rmi mock_tcp:latest
4 | docker-compose -f ./docker-compose.yml up -d
5 | echo "tcp设备模拟启动"
6 |
--------------------------------------------------------------------------------
/test/mock_ws/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.22.4
2 |
3 | ENV GO111MODULE=on \
4 | GOPROXY=https://goproxy.cn,direct \
5 | GIN_MODE=release \
6 | PORT=80
7 |
8 | WORKDIR /app
9 | COPY . .
10 |
11 |
12 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
13 | ENV TZ=Asia/Shanghai
14 |
15 | RUN go mod tidy
16 |
17 | RUN go build -o /godocker
18 |
19 |
20 |
21 | EXPOSE 11111
22 |
23 | CMD [ "/godocker" ]
--------------------------------------------------------------------------------
/test/mock_ws/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | mock-ws:
3 | image: mock_ws:latest
4 | build:
5 | context: .
6 | dockerfile: Dockerfile
7 | entrypoint: ["/godocker"]
8 | environment:
9 | - TZ=Asia/Shanghai
10 | ports:
11 | - 11114:11111
12 | networks:
13 | - iot-net
14 | networks:
15 | iot-net:
16 | driver: bridge
17 |
--------------------------------------------------------------------------------
/test/mock_ws/go.mod:
--------------------------------------------------------------------------------
1 | module mock_ws
2 |
3 | go 1.22.4
4 |
5 | require github.com/gorilla/websocket v1.5.3
6 |
--------------------------------------------------------------------------------
/test/mock_ws/go.sum:
--------------------------------------------------------------------------------
1 | github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
2 | github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
3 |
--------------------------------------------------------------------------------
/test/mock_ws/start_mock_ws.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | docker-compose -f ./docker-compose.yml down
3 | docker rmi mock_ws:latest
4 | docker-compose -f ./docker-compose.yml up -d
5 | echo "ws设备模拟启动"
6 |
--------------------------------------------------------------------------------
/todo.md:
--------------------------------------------------------------------------------
1 | - 物联网卡管理
2 | - 接入号
3 | - ICCID
4 | - IMSI
5 | - 运营商
6 | - 到期时间
7 | - modbus
8 | - websocket
--------------------------------------------------------------------------------
/transmit/common/common_interface.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | type DataRowList struct {
4 | Time int64 `json:"time"` // 秒级时间戳
5 | DeviceUid string `json:"device_uid"` // 能够产生网络通讯的唯一编码
6 | IdentificationCode string `json:"identification_code"` // 设备标识码
7 | DataRows []DataRow `json:"data"`
8 | Nc string `json:"nc"`
9 | Protocol string `json:"protocol"`
10 | }
11 | type DataRow struct {
12 | Name string `json:"name"`
13 | Value string `json:"value"`
14 | }
15 |
--------------------------------------------------------------------------------
/transmit/readme.md:
--------------------------------------------------------------------------------
1 | # 转发服务
2 |
3 | 1. 数据库
4 | 2. mysql
5 | 3. PG
6 | 4. MONGO
7 | 2. 消息队列
8 | 3. RABBIT
9 | 4. RocketMQ
10 | 5. Kafka
11 | 6. Pulsar
--------------------------------------------------------------------------------