├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── LICENSE ├── a.js ├── ant-react ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .husky │ ├── commit-msg │ └── pre-commit ├── .prettierignore ├── .prettierrc.js ├── README.md ├── config │ ├── config.dev.ts │ ├── config.prod.ts │ ├── config.ts │ ├── defaultSettings.ts │ ├── oneapi.json │ ├── proxy.ts │ └── routes.ts ├── jest.config.ts ├── jsconfig.json ├── nginx.conf ├── package.json ├── pnpm-lock.yaml ├── public │ ├── CNAME │ ├── favicon.ico │ ├── icons │ │ ├── icon-128x128.png │ │ ├── icon-192x192.png │ │ └── icon-512x512.png │ ├── logo.svg │ ├── pro_icon.svg │ └── scripts │ │ └── loading.js ├── src │ ├── access.ts │ ├── app.tsx │ ├── components │ │ ├── Footer │ │ │ └── index.tsx │ │ ├── HeaderDropdown │ │ │ └── index.tsx │ │ ├── RightContent │ │ │ ├── AvatarDropdown.tsx │ │ │ └── index.tsx │ │ └── index.ts │ ├── global.less │ ├── global.tsx │ ├── locales │ │ ├── bn-BD.ts │ │ ├── bn-BD │ │ │ ├── component.ts │ │ │ ├── globalHeader.ts │ │ │ ├── menu.ts │ │ │ ├── pages.ts │ │ │ ├── pwa.ts │ │ │ ├── settingDrawer.ts │ │ │ └── settings.ts │ │ ├── en-US.ts │ │ ├── en-US │ │ │ ├── component.ts │ │ │ ├── globalHeader.ts │ │ │ ├── menu.ts │ │ │ ├── pages.ts │ │ │ ├── pwa.ts │ │ │ ├── settingDrawer.ts │ │ │ └── settings.ts │ │ ├── fa-IR.ts │ │ ├── fa-IR │ │ │ ├── component.ts │ │ │ ├── globalHeader.ts │ │ │ ├── menu.ts │ │ │ ├── pages.ts │ │ │ ├── pwa.ts │ │ │ ├── settingDrawer.ts │ │ │ └── settings.ts │ │ ├── id-ID.ts │ │ ├── id-ID │ │ │ ├── component.ts │ │ │ ├── globalHeader.ts │ │ │ ├── menu.ts │ │ │ ├── pages.ts │ │ │ ├── pwa.ts │ │ │ ├── settingDrawer.ts │ │ │ └── settings.ts │ │ ├── ja-JP.ts │ │ ├── ja-JP │ │ │ ├── component.ts │ │ │ ├── globalHeader.ts │ │ │ ├── menu.ts │ │ │ ├── pages.ts │ │ │ ├── pwa.ts │ │ │ ├── settingDrawer.ts │ │ │ └── settings.ts │ │ ├── pt-BR.ts │ │ ├── pt-BR │ │ │ ├── component.ts │ │ │ ├── globalHeader.ts │ │ │ ├── menu.ts │ │ │ ├── pages.ts │ │ │ ├── pwa.ts │ │ │ ├── settingDrawer.ts │ │ │ └── settings.ts │ │ ├── zh-CN.ts │ │ ├── zh-CN │ │ │ ├── component.ts │ │ │ ├── globalHeader.ts │ │ │ ├── menu.ts │ │ │ ├── pages.ts │ │ │ ├── pwa.ts │ │ │ ├── settingDrawer.ts │ │ │ └── settings.ts │ │ ├── zh-TW.ts │ │ └── zh-TW │ │ │ ├── component.ts │ │ │ ├── globalHeader.ts │ │ │ ├── menu.ts │ │ │ ├── pages.ts │ │ │ ├── pwa.ts │ │ │ ├── settingDrawer.ts │ │ │ └── settings.ts │ ├── manifest.json │ ├── pages │ │ ├── 404.tsx │ │ ├── Admin.tsx │ │ ├── Data │ │ │ ├── Calc │ │ │ │ ├── CalcRuleResult.tsx │ │ │ │ ├── CalcRuleUpdateForm.tsx │ │ │ │ ├── MockRun.tsx │ │ │ │ └── index.tsx │ │ │ ├── CalcParam │ │ │ │ ├── CalcParamUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── ScriptParam │ │ │ │ ├── ScriptNameShow.tsx │ │ │ │ ├── ScriptParamUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── ScriptWaring │ │ │ │ ├── DebugScript.tsx │ │ │ │ ├── History.tsx │ │ │ │ ├── ScriptWaringUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── Signal │ │ │ │ ├── DeviceUidShow.tsx │ │ │ │ ├── History.tsx │ │ │ │ ├── SignalNameShow.tsx │ │ │ │ ├── SignalUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── SignalVis │ │ │ │ └── index.tsx │ │ │ └── SignalWaring │ │ │ │ ├── History.tsx │ │ │ │ ├── SignalWaringUpdateForm.tsx │ │ │ │ └── index.tsx │ │ ├── Device │ │ │ ├── DeviceGroup │ │ │ │ ├── DeviceGroup.tsx │ │ │ │ ├── DeviceGroupBindForm.tsx │ │ │ │ └── DeviceGroupUpdateForm.tsx │ │ │ └── DeviceInfo │ │ │ │ ├── DeviceInfo.tsx │ │ │ │ └── DeviceInfoUpdateForm.tsx │ │ ├── Lifecycle │ │ │ ├── OperationList │ │ │ │ └── OperationList.tsx │ │ │ ├── ProduceList │ │ │ │ └── ProduceList.tsx │ │ │ ├── ProductList │ │ │ │ ├── ProductList.tsx │ │ │ │ ├── ProductUpdateForm.tsx │ │ │ │ └── TagsRow.tsx │ │ │ ├── ShipmentRecord │ │ │ │ └── ShipmentRecord.tsx │ │ │ └── SimList │ │ │ │ ├── SimList.tsx │ │ │ │ └── SimUpdateForm.tsx │ │ ├── Protocol │ │ │ ├── coap │ │ │ │ ├── clients │ │ │ │ │ ├── CoapHandlerUpdateForm.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── nodes │ │ │ │ │ └── index.tsx │ │ │ ├── http │ │ │ │ ├── clients │ │ │ │ │ ├── HttpHandlerUpdateForm.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── nodes │ │ │ │ │ └── index.tsx │ │ │ ├── mqtt │ │ │ │ ├── clients │ │ │ │ │ ├── MqttUpdateForm.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── nodes │ │ │ │ │ └── index.tsx │ │ │ ├── tcp │ │ │ │ ├── clients │ │ │ │ │ ├── TcpHandlerUpdateForm.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── nodes │ │ │ │ │ └── index.tsx │ │ │ └── ws │ │ │ │ ├── clients │ │ │ │ ├── WsHandlerUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ │ └── nodes │ │ │ │ └── index.tsx │ │ ├── TableList │ │ │ ├── components │ │ │ │ └── UpdateForm.tsx │ │ │ └── index.tsx │ │ ├── User │ │ │ ├── DeptList │ │ │ │ ├── DeptList.tsx │ │ │ │ └── DeptUpdateForm.tsx │ │ │ ├── Login │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── login.test.tsx.snap │ │ │ │ ├── index.tsx │ │ │ │ └── login.test.tsx │ │ │ ├── MessageList │ │ │ │ └── MessageList.tsx │ │ │ ├── RoleList │ │ │ │ ├── RoleList.tsx │ │ │ │ └── RoleUpdateForm.tsx │ │ │ └── UserList │ │ │ │ ├── UserList.tsx │ │ │ │ └── UserUpdateForm.tsx │ │ ├── Welcome.tsx │ │ ├── dashboard │ │ │ ├── AlarmStatistics.tsx │ │ │ ├── DeviceMap.tsx │ │ │ ├── DeviceStatsChart.tsx │ │ │ ├── MessageList.tsx │ │ │ ├── ProductDeviceCards.tsx │ │ │ ├── ProtocolStatsTable.tsx │ │ │ └── index.tsx │ │ ├── forward │ │ │ ├── cassandra │ │ │ │ ├── CassandraTransmitUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── cassandra_bind │ │ │ │ ├── CassandraTransmitBindUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── clickhouse │ │ │ │ ├── ClickhouseTransmitUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── clickhouse_bind │ │ │ │ ├── ClickhouseTransmitBindUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── influxdb2 │ │ │ │ ├── InfluxdbTransmitUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── influxdb2_bind │ │ │ │ ├── InfluxdbTransmitBindUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── mongo │ │ │ │ ├── MongoTransmitUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── mongo_bind │ │ │ │ ├── MongoTransmitBindUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── mysql │ │ │ │ ├── MySQLTransmitUpdateForm.tsx │ │ │ │ └── index.tsx │ │ │ └── mysql_bind │ │ │ │ ├── MysqlTransmitBindUpdateForm.tsx │ │ │ │ └── index.tsx │ │ ├── mirror │ │ │ ├── admin │ │ │ │ └── index.tsx │ │ │ └── protocol │ │ │ │ ├── MetricsModal.tsx │ │ │ │ ├── coap.tsx │ │ │ │ ├── http.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── mqtt.tsx │ │ │ │ ├── tcp.tsx │ │ │ │ └── ws.tsx │ │ └── notice │ │ │ ├── dingding │ │ │ ├── DingDingUpdateForm.tsx │ │ │ └── index.tsx │ │ │ └── feishu │ │ │ ├── FeishuUpdateForm.tsx │ │ │ └── index.tsx │ ├── requestErrorConfig.ts │ ├── service-worker.js │ ├── services │ │ ├── ant-design-pro │ │ │ ├── api.ts │ │ │ ├── common.ts │ │ │ ├── index.ts │ │ │ ├── login.ts │ │ │ └── typings.d.ts │ │ └── swagger │ │ │ ├── index.ts │ │ │ ├── pet.ts │ │ │ ├── store.ts │ │ │ ├── typings.d.ts │ │ │ └── user.ts │ └── typings.d.ts ├── tests │ └── setupTests.jsx ├── tsconfig.json └── types │ ├── cache │ ├── cache.json │ ├── login.cache.json │ └── mock │ │ ├── login.mock.cache.js │ │ └── mock.cache.js │ └── index.d.ts ├── ant-vue ├── .commitlintrc ├── .env.development ├── .env.docker ├── .env.production ├── .eslintrc.cjs ├── .gitignore ├── .prettierrc ├── .vscode │ ├── extensions.json │ └── settings.json ├── README.md ├── env.d.ts ├── index.html ├── nginx.conf ├── package-lock.json ├── package.json ├── pnpm-lock.yaml ├── public │ └── vite.svg ├── src │ ├── App.vue │ ├── api │ │ └── index.ts │ ├── components │ │ ├── Tag │ │ │ └── index.vue │ │ ├── echarts │ │ │ ├── index.d.ts │ │ │ ├── index.vue │ │ │ └── walden.project.json │ │ ├── index.ts │ │ ├── select │ │ │ ├── CalculateSelect.vue │ │ │ ├── DeptSelect.vue │ │ │ ├── MqttModSelect.vue │ │ │ ├── MqttSelect.vue │ │ │ ├── Product.vue │ │ │ ├── SignalDelayWaring.vue │ │ │ ├── SignalModeSelect.vue │ │ │ └── SignalSelect.vue │ │ └── upload │ │ │ └── index.vue │ ├── constants │ │ └── index.ts │ ├── directives │ │ ├── copy.ts │ │ ├── index.ts │ │ ├── permission.ts │ │ └── resize.ts │ ├── hooks │ │ ├── useAddPage.ts │ │ ├── useColumns.ts │ │ ├── useDeletePage.ts │ │ ├── useECharts.ts │ │ ├── useEditableData.ts │ │ ├── usePagination.ts │ │ ├── useQueryPage.ts │ │ ├── useRoles.ts │ │ ├── useRouteJump.ts │ │ ├── useTheme.ts │ │ └── useUpdatePage.ts │ ├── i18n │ │ ├── en.ts │ │ ├── index.ts │ │ └── zh-CHS.ts │ ├── icons │ │ ├── complex.config.cjs │ │ ├── complex │ │ │ └── empty.svg │ │ ├── simple.config.cjs │ │ └── simple │ │ │ └── loading.svg │ ├── layout │ │ └── index.vue │ ├── main.ts │ ├── permission.ts │ ├── plugins │ │ └── vxe-table.ts │ ├── request │ │ ├── cancel.ts │ │ ├── empty.ts │ │ ├── error.ts │ │ └── index.ts │ ├── router │ │ ├── index.ts │ │ └── single.ts │ ├── stores │ │ ├── index.ts │ │ ├── permission.ts │ │ ├── routerPath.ts │ │ └── theme.ts │ ├── styles │ │ ├── index.less │ │ ├── library.less │ │ ├── scrollbar.less │ │ └── variable.less │ ├── theme │ │ ├── dark.ts │ │ └── light.ts │ ├── types │ │ └── form.ts │ ├── utils │ │ ├── color.ts │ │ ├── date.ts │ │ ├── el.ts │ │ ├── i18n.ts │ │ ├── permission.ts │ │ └── setAxiosConfig.ts │ └── views │ │ ├── calculate-parameters │ │ └── index.vue │ │ ├── calculation-rules │ │ └── index.vue │ │ ├── calculation-view │ │ ├── add.vue │ │ └── index.vue │ │ ├── cassandra │ │ └── index.vue │ │ ├── clickhouse │ │ └── index.vue │ │ ├── coap │ │ └── index.vue │ │ ├── comp-preview │ │ └── index.vue │ │ ├── dept │ │ └── index.vue │ │ ├── deviceGroup │ │ ├── index.vue │ │ └── modal │ │ │ └── bindDevice.vue │ │ ├── deviceInfos │ │ └── index.vue │ │ ├── dingdingRobot │ │ └── index.vue │ │ ├── draggable │ │ ├── add.vue │ │ └── index.vue │ │ ├── feishuRobot │ │ └── index.vue │ │ ├── http │ │ └── index.vue │ │ ├── icon-preview │ │ └── index.vue │ │ ├── influxdb2 │ │ └── index.vue │ │ ├── message-list │ │ └── index.vue │ │ ├── mongo │ │ └── index.vue │ │ ├── mqtt-management │ │ └── index.vue │ │ ├── mysql │ │ └── index.vue │ │ ├── node-details │ │ └── index.vue │ │ ├── product │ │ └── index.vue │ │ ├── production-plans │ │ └── index.vue │ │ ├── repair-records │ │ └── index.vue │ │ ├── role │ │ └── index.vue │ │ ├── script-alarm-parameters │ │ └── index.vue │ │ ├── script-alarm │ │ └── index.vue │ │ ├── shipment-records │ │ └── index.vue │ │ ├── signal-configuration │ │ └── index.vue │ │ ├── signal │ │ └── index.vue │ │ ├── sim-card │ │ └── index.vue │ │ ├── tcp │ │ └── index.vue │ │ ├── user │ │ └── index.vue │ │ ├── visualization │ │ ├── add.vue │ │ ├── index.vue │ │ └── list.vue │ │ └── websocket │ │ └── index.vue ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── deploy ├── IotAdminReact.Dockerfile ├── IotAdminVue.Dockerfile ├── IotGoMQ.Dockerfile ├── IotGoProject.Dockerfile ├── IotMQTT.Dockerfile ├── mqtt客户端管理项目部署.md ├── rabbit消费者部署.md ├── readme.md ├── 后台服务部署.md └── 环境部署.md ├── doc ├── Go IoT 开发平台对数据上报的思考.md ├── GoIoT开发平台介绍.pdf ├── GoIoT开发平台分析.pdf ├── MQTT客户端管理方案.md ├── MQTT客户端管理方案 │ ├── MQTT客户端保活.drawio.png │ ├── MQTT客户端管理方案.drawio.png │ └── image-20240423094241762.png ├── readme.md ├── 功能说明 │ ├── 人员管理.md │ ├── 协议管理.md │ ├── 数据管理.md │ ├── 生命周期.md │ └── 通知管理.md ├── 报警.md ├── 报警 │ ├── 数值报警.drawio.png │ └── 脚本报警.drawio.png ├── 数据流转链路.md ├── 数据流转链路 │ └── 设备数据流转链路.drawio.png ├── 测试方案.md ├── 设备模拟.md ├── 部署.md └── 部署 │ ├── image-20240902123240839.png │ ├── image-20240902123753596.png │ └── image-20240902123825724.png ├── docker ├── afa │ ├── config │ │ ├── mosquitto.conf │ │ └── pwfile │ └── docker-compose.yml ├── app-start.sh ├── app │ ├── docker-compose.react.yml │ ├── docker-compose.yml │ ├── iot-project │ │ └── config │ │ │ └── app-local.yml │ ├── mq │ │ └── config │ │ │ ├── app-local-calc.yml │ │ │ ├── app-local-pre_handler-1.yml │ │ │ ├── app-local-pre_handler-2.yml │ │ │ ├── app-local-pre_handler-3.yml │ │ │ ├── app-local-pre_handler.yml │ │ │ ├── app-local-waring_handler.yml │ │ │ └── app-local-wd.yml │ └── mqtt │ │ └── config │ │ ├── app-local.yml │ │ ├── app-local2.yml │ │ └── app-local3.yml ├── env-start.sh ├── env │ ├── Cassandra │ │ └── docker-compose.yml │ ├── Pulsar │ │ └── docker-compose.yml │ ├── base-env-docker-compose.yml │ ├── big-data-env-docker-compose.yml │ ├── clickhouse │ │ ├── config │ │ │ ├── config.xml │ │ │ ├── docker_related_config.xml │ │ │ └── users.xml │ │ └── docker-compose.yml │ ├── influx │ │ ├── docker-compose.yml │ │ ├── influxv2.env │ │ └── telegraf │ │ │ └── mytelegraf.conf │ ├── iotdb │ │ └── docker-compose.yml │ ├── kafka │ │ └── docker-compose.yml │ ├── mongo │ │ ├── docker-compose.yml │ │ └── init-mongo.js │ ├── mqtt │ │ ├── docker-compose.yml │ │ ├── mock │ │ │ ├── Dockerfile │ │ │ ├── go.mod │ │ │ ├── go.sum │ │ │ ├── main.go │ │ │ ├── mqtt.yml │ │ │ └── start.sh │ │ └── readme.md │ ├── mysql │ │ └── docker-compose.yml │ ├── rabbitmq │ │ ├── Dockerfile │ │ ├── docker-compose.yml │ │ ├── enabled_plugins │ │ └── plugins │ │ │ └── rabbitmq_delayed_message_exchange-3.10.2.ez │ ├── redis │ │ ├── conf │ │ │ └── redis.conf │ │ └── docker-compose.yml │ └── rocketmq │ │ └── docker-compose.yml ├── metricsMonitor │ ├── grafana │ │ └── config │ │ │ ├── datasources.json │ │ │ └── grafana.ini │ ├── metrics-monitor-docker-compose.yml │ └── prometheus │ │ └── prometheus.yml └── rabbitmq │ └── data │ └── .erlang.cookie ├── go-iot-mq ├── MongoUt.go ├── app-local-calc.yml ├── app-local-pre_coap_handler.yml ├── app-local-pre_handler.yml ├── app-local-pre_http_handler.yml ├── app-local-pre_tcp_handler.yml ├── app-local-pre_ws_handler.yml ├── app-local-transmit.yml ├── app-local-waring_handler.yml ├── app-local-wd.yml ├── app-local.yml ├── customer.go ├── go.mod ├── go.sum ├── handler_calc.go ├── handler_coap_storage.go ├── handler_http_storage.go ├── handler_mqtt_storage.go ├── handler_notice.go ├── handler_tcp_storage.go ├── handler_transmit.go ├── handler_waring.go ├── handler_waring_delay.go ├── handler_ws_storage.go ├── log.go ├── main.go ├── mq.go ├── push_time_check.go ├── redis.go ├── start-calc.sh ├── start-pre.sh ├── start-waring.sh ├── start-wd.sh ├── structs.go └── z_test.go ├── go-iot ├── .gitignore ├── app-local.yml ├── app-local2.yml ├── beat.go ├── build.sh ├── c.svg ├── ctr.go ├── go.mod ├── go.sum ├── log.go ├── main.go ├── mq_test.go ├── mqtt.go ├── mqtt_redis.go ├── mqtt_service.go ├── rabbit_mq.go ├── readme.md ├── redis.go ├── redis_lock.go ├── service_instance.go └── start.sh ├── iot-go-project ├── app-local.yml ├── biz │ ├── calc_param_biz.go │ ├── calc_rule_biz.go │ ├── calc_run_biz.go │ ├── coap_biz.go │ ├── cron_test.go │ ├── dashboard_biz.go │ ├── dept_biz.go │ ├── device_group_biz.go │ ├── device_info_biz.go │ ├── device_install_record_biz.go │ ├── http_biz.go │ ├── influxdb_biz.go │ ├── message_list_biz.go │ ├── mqtt_client_biz.go │ ├── node_biz.go │ ├── notice │ │ ├── dingding_biz.go │ │ └── feishu_biz.go │ ├── product_biz.go │ ├── production_plan_biz.go │ ├── redis_expire_biz.go │ ├── repair_record_biz.go │ ├── role_biz.go │ ├── script_biz.go │ ├── script_list_biz.go │ ├── script_test.go │ ├── shipment_record_biz.go │ ├── signal_biz.go │ ├── signal_delay_waring_biz.go │ ├── signal_delay_waring_param_biz.go │ ├── sim_card_biz.go │ ├── tcp_biz.go │ ├── transmit │ │ ├── cassandra_transmit_biz.go │ │ ├── clickhouse_transmit_biz.go │ │ ├── influxdb_transmit_biz.go │ │ ├── kafka_transmit_biz.go │ │ ├── mongo_transmit_biz.go │ │ ├── mqtt │ │ │ ├── cassandra_bind_mqtt_biz.go │ │ │ ├── clickhouse_bind_mqtt_biz.go │ │ │ ├── influxdb_bind_mqtt_biz.go │ │ │ ├── kafka_bind_mqtt_biz.go │ │ │ ├── mongo_bind_mqtt_biz.go │ │ │ ├── mysql_bind_mqtt_biz.go │ │ │ └── rabbit_bind_mqtt_biz.go │ │ ├── mysql_transmit_biz.go │ │ └── rabbit_transmit_biz.go │ ├── user_biz.go │ └── ws_biz.go ├── config │ └── config.go ├── glob │ └── glob.go ├── go.mod ├── go.sum ├── initialize │ ├── init.go │ └── redis_lock.go ├── main.go ├── models │ ├── action.go │ ├── models.go │ ├── notice.go │ ├── transmit.go │ └── valicate.go ├── readme.md ├── router │ ├── calc_param_router.go │ ├── calc_rule_router.go │ ├── coap_handler_router.go │ ├── dashboard_router.go │ ├── data_router.go │ ├── dept_router.go │ ├── device_group_router.go │ ├── device_info_router.go │ ├── device_install_record_router.go │ ├── file_router.go │ ├── http_handler_router.go │ ├── login_router.go │ ├── message_list_router.go │ ├── mqtt_client_router.go │ ├── notice │ │ ├── dingding_router.go │ │ └── feishu_router.go │ ├── pod_router.go │ ├── product_router.go │ ├── production_plan_router.go │ ├── promethues.go │ ├── protocol_router.go │ ├── repair_record_router.go │ ├── role_router.go │ ├── script_list_router.go │ ├── shipment_record_router.go │ ├── signal_delay_waring_param_router.go │ ├── signal_delay_waring_router.go │ ├── signal_router.go │ ├── signal_waring_config_router.go │ ├── sim_card_router.go │ ├── statistics │ │ └── statistics_router.go │ ├── tcp_handler_router.go │ ├── transmit │ │ ├── cassandra_transmit_router.go │ │ ├── clickhouse_transmit_router.go │ │ ├── influxdb_transmit_router.go │ │ ├── kafka_transmit_router.go │ │ ├── mongo_transmit_router.go │ │ ├── mysql_transmit_router.go │ │ ├── rabbit_transmit_router.go │ │ └── transmit_mqtt │ │ │ ├── cassandra_bind_mqtt_router.go │ │ │ ├── clickhouse_bind_mqtt_router.go │ │ │ ├── influxdb_bind_mqtt_router.go │ │ │ ├── kafka_bind_mqtt_router.go │ │ │ ├── mongo_bind_mqtt_router.go │ │ │ ├── mysql_bind_mqtt_router.go │ │ │ └── rabbit_bind_mqtt_router.go │ ├── user_router.go │ └── ws_handler_router.go ├── servlet │ └── servlet.go ├── start.sh ├── task │ └── task.go └── ut │ ├── InfluxUt.go │ ├── MongoUt.go │ └── times.go ├── notice ├── go.mod ├── go.sum ├── models │ └── models.go ├── readme.md ├── sender │ ├── ding_sender.go │ └── sender.go └── test │ └── ding_test.go ├── operation ├── image.png ├── 操作文档.md └── 操作文档 │ ├── image-20240606094255537.png │ ├── image-20240606094311563.png │ ├── image-20240606094417071.png │ ├── image-20240606094431736.png │ ├── image-20240606095128822.png │ ├── image-20240606095204696.png │ ├── image-20240606095303850.png │ ├── image-20240606095609024.png │ ├── image-20240606101016121.png │ ├── image-20240606101935355.png │ ├── image-20240606102215355.png │ ├── image-20240606102407166.png │ ├── image-20240606102427935.png │ ├── image-20240606102919129.png │ ├── image-20240606102937751.png │ ├── image-20240606103447234.png │ ├── image-20240606103550811.png │ ├── image-20240606103946874.png │ ├── image-20240606103953112.png │ ├── image-20240606104453746.png │ ├── image-20240606104745498.png │ ├── image-20240606105047390.png │ ├── image-20240606105138761.png │ ├── image-20240606105443413.png │ ├── image-20240606105502418.png │ ├── image-20240606105928178.png │ ├── image-20240606105954148.png │ ├── image-20240606110124477.png │ ├── image-20240606110140876.png │ ├── image-20240606110528155.png │ ├── image-20240606110554774.png │ ├── image-20240606110630063.png │ ├── image-20240606110653819.png │ ├── image-20240606111305558.png │ ├── image-20240606111429126.png │ ├── image-20240606111609969.png │ ├── image-20240606111858944.png │ ├── image-20240606111939061.png │ ├── image-20240606112501476.png │ ├── image-20240606112518583.png │ ├── image-20240606112841272.png │ ├── image-20240606112945960.png │ ├── image-20240606112959902.png │ ├── image-20240606123826130.png │ ├── image-20240606123927495.png │ ├── image-20240606124428648.png │ ├── image-20240606124444863.png │ ├── image-20240606124936036.png │ ├── image-20240606125101076.png │ ├── image-20240606125408906.png │ ├── image-20240606125650440.png │ ├── image-20240606125710860.png │ ├── image-20240606125743694.png │ ├── image-20240606125841654.png │ ├── image-20240606130011982.png │ ├── image-20240606130045585.png │ ├── image-20240606130457564.png │ ├── image-20240606130509502.png │ ├── image-20240606130856586.png │ ├── image-20240606130923434.png │ ├── image-20240606130959242.png │ ├── image-20240606135730782.png │ ├── image-20240606135808693.png │ ├── image-20240606135902648.png │ ├── image-20240606140147152.png │ ├── image-20240606142743931.png │ ├── image-20240606142934074.png │ ├── image-20240606143003737.png │ ├── image-20240606143149691.png │ ├── image-20240606143413851.png │ ├── image-20240606143635353.png │ ├── image-20240606144929189.png │ ├── image-20240606145602958.png │ ├── image-20240606145659098.png │ ├── image-20240606145847500.png │ ├── image-20240606145948476.png │ ├── image-20240606150004980.png │ ├── image-20240606150154486.png │ ├── image-20240606150726511.png │ ├── image-20240606150805927.png │ ├── image-20240606150858294.png │ ├── image-20240606151858847.png │ ├── image-20240606151915415.png │ ├── image-20240606152036372.png │ ├── image-20240606152220117.png │ ├── image-20240606152257812.png │ ├── image-20240606152646143.png │ ├── image-20240606152945561.png │ ├── image-20240606153511205.png │ ├── image-20240606153911041.png │ ├── image-20240606153937040.png │ ├── image-20240606154524267.png │ ├── image-20240606154921513.png │ ├── image-20240606155158429.png │ ├── image-20240606155217737.png │ ├── image-20240606155540984.png │ ├── image-20240606155657395.png │ ├── image-20240606155727562.png │ ├── image-20240606155844230.png │ ├── image-20240606160355023.png │ ├── image-20240606160413988.png │ ├── image-20240606160958746.png │ ├── image-20240606161321205.png │ ├── image-20240606161425423.png │ ├── image-20240606161520450.png │ ├── image-20240606161535507.png │ ├── image-20240606161646066.png │ ├── image-20240606161712411.png │ ├── image-20240606161744750.png │ ├── image-20240606161904468.png │ ├── image-20240606162113076.png │ ├── image-20240606162136009.png │ ├── image-20240606162252098.png │ ├── image-20240606162307908.png │ ├── image-20240606162721881.png │ ├── image-20240606162939311.png │ ├── image-20240606163142021.png │ ├── image-20240606163211691.png │ ├── image-20240606163315820.png │ ├── image-20240606163335959.png │ ├── image-20240606163441432.png │ ├── image-20240606163457246.png │ ├── image-20240606163553406.png │ ├── image-20240606163900046.png │ ├── image-20240606163916249.png │ ├── image-20240606164219841.png │ ├── image-20240606164308715.png │ ├── image-20240606164324452.png │ ├── image-20240606164753125.png │ ├── image-20240606164806521.png │ ├── image-20240606164936877.png │ ├── image-20240606165008936.png │ ├── image-20240606165106823.png │ ├── image-20240606165223720.png │ ├── image-20240606165725939.png │ ├── image-20240606165740680.png │ ├── image-20240606165858358.png │ ├── image-20240606170209153.png │ ├── image-20240606170230662.png │ ├── image-20240606170243011.png │ ├── image-20240606170327143.png │ ├── image-20240606170412260.png │ ├── image-20240606170511155.png │ ├── image-20240606170549901.png │ ├── image-20240606170711994.png │ ├── image-20240606170832389.png │ ├── image-20240606170845707.png │ ├── image-20240606171045130.png │ ├── image-20240606171235567.png │ └── image-20240607163432931.png ├── protocol ├── coap │ ├── app-local.yml │ ├── beat.go │ ├── data_handler_st.go │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── rabbit_mq.go │ ├── redis.go │ ├── redis_lock.go │ ├── sample │ │ ├── client │ │ │ └── main.go │ │ └── server │ │ │ └── main.go │ ├── server.go │ └── task.go ├── http │ ├── app-local.yml │ ├── beat.go │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── rabbit_mq.go │ └── redis.go ├── modbus │ ├── app-local.yml │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── rabbit_mq.go │ ├── redis.go │ ├── redis_lock.go │ └── sample │ │ ├── client │ │ └── client.go │ │ └── server │ │ └── server.go ├── readme.md ├── readme │ └── image-20240725103427236.png ├── tcp │ ├── app-local.yml │ ├── beat.go │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── rabbit_mq.go │ ├── redis.go │ ├── redis_lock.go │ ├── server.go │ ├── server_test.go │ └── task.go └── ws │ ├── app-local.yml │ ├── beat.go │ ├── ctr.go │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── rabbit_mq.go │ ├── redis.go │ ├── redis_lock.go │ ├── task.go │ ├── template │ └── index.html │ └── ws.go ├── readme.md ├── readme ├── image-20240524123513247.png ├── image-20240524123533112.png ├── image-20240524123606435.png ├── image-20240524123618542.png ├── image-20240524123658849.png ├── image-20240524123718443.png ├── image-20240524123729546.png ├── image-20240524123805587.png ├── image-20240524123820684.png ├── o1.png ├── 数据图.jpg ├── 架构图.png └── 网络-数据结构图.png ├── readme_CN.md ├── roadmap.md ├── swagger.sh ├── test ├── 1.txt ├── 2.txt ├── Dockerfile ├── MQTT-TEST.log ├── b.go ├── check.py ├── docker-compose.yml ├── go.mod ├── go.sum ├── init_redis.sh ├── log.go ├── main.go ├── mock_coap │ ├── Dockerfile │ ├── docker-compose.yml │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── start_mock_coap.sh ├── mock_http │ ├── Dockerfile │ ├── docker-compose.yml │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── start_mock_http.sh ├── mock_mqtt │ ├── 1.txt │ ├── Dockerfile │ ├── docker-compose.yml │ ├── go.mod │ ├── go.sum │ ├── log.go │ ├── main.go │ ├── start_mock_mqtt.sh │ └── v.go ├── mock_tcp │ ├── Dockerfile │ ├── docker-compose.yml │ ├── go.mod │ ├── main.go │ └── start_mock_tcp.sh ├── mock_ws │ ├── Dockerfile │ ├── docker-compose.yml │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── start_mock_ws.sh ├── mqtt_serv.go └── v.go ├── todo.md └── transmit ├── cache ├── transmit_cache.go ├── transmit_cache_biz.go └── transmit_cache_test.go ├── cassandra ├── cassandra_op.go └── cassandra_op_test.go ├── clickhouse ├── clickhouse_op.go └── clickhouse_op_test.go ├── common └── common_interface.go ├── go.mod ├── go.sum ├── influxdb2 ├── influxdb_op.go └── influxdb_op_test.go ├── mongo ├── mongo_op.go └── mongo_op_test.go ├── mysql ├── mysql_op.go └── mysql_op_test.go └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | docs/ 2 | ppt/ 3 | 4 | .idea/ 5 | 6 | /docker/rabbitmq/data 7 | /docker/mongo/database 8 | fileupdate/ 9 | /docker/Cassandra/dataa/ 10 | /docker/RocketMQ/data/ 11 | /docker/clickhouse/data/ 12 | /docker/clickhouse/log/ 13 | 14 | docker/Cassandra/dataa 15 | 16 | docker/env/mongo/database 17 | docker/env/mysql/data 18 | docker/env/rabbitmq/data 19 | docker/env/redis/data 20 | node_modules -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.gotoLocation.alternativeDeclarationCommand": "editor.action.revealDefinition", 3 | "editor.gotoLocation.alternativeDefinitionCommand": "editor.action.revealDefinition", 4 | "editor.gotoLocation.alternativeTypeDefinitionCommand": "editor.action.revealDefinition", 5 | "editor.selectionHighlight": false, 6 | "files.autoSave": "onFocusChange", 7 | "editor.suggest.snippetsPreventQuickSuggestions": false, 8 | "editor.quickSuggestions": { 9 | "other": "on", 10 | "comments": "off", 11 | "strings": "on" 12 | } 13 | } -------------------------------------------------------------------------------- /ant-react/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /ant-react/.eslintignore: -------------------------------------------------------------------------------- 1 | /lambda/ 2 | /scripts 3 | /config 4 | .history 5 | public 6 | dist 7 | .umi 8 | mock -------------------------------------------------------------------------------- /ant-react/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [require.resolve('@umijs/lint/dist/config/eslint')], 3 | globals: { 4 | page: true, 5 | REACT_APP_ENV: true, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /ant-react/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | **/node_modules 5 | # roadhog-api-doc ignore 6 | /src/utils/request-temp.js 7 | _roadhog-api-doc 8 | 9 | # production 10 | /dist 11 | 12 | # misc 13 | .DS_Store 14 | npm-debug.log* 15 | yarn-error.log 16 | 17 | /coverage 18 | .idea 19 | yarn.lock 20 | package-lock.json 21 | *bak 22 | .vscode 23 | 24 | 25 | # visual studio code 26 | .history 27 | *.log 28 | functions/* 29 | .temp/** 30 | 31 | # umi 32 | .umi 33 | .umi-production 34 | .umi-test 35 | 36 | # screenshot 37 | screenshot 38 | .firebase 39 | .eslintcache 40 | 41 | build 42 | -------------------------------------------------------------------------------- /ant-react/.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | # Export Git hook params 5 | export GIT_PARAMS=$* 6 | 7 | npx --no-install fabric verify-commit 8 | -------------------------------------------------------------------------------- /ant-react/.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install lint-staged 5 | -------------------------------------------------------------------------------- /ant-react/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.svg 2 | .umi 3 | .umi-production 4 | /dist 5 | .dockerignore 6 | .DS_Store 7 | .eslintignore 8 | *.png 9 | *.toml 10 | docker 11 | .editorconfig 12 | Dockerfile* 13 | .gitignore 14 | .prettierignore 15 | LICENSE 16 | .eslintcache 17 | *.lock 18 | yarn-error.log 19 | .history 20 | CNAME 21 | /build 22 | /public 23 | -------------------------------------------------------------------------------- /ant-react/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | trailingComma: 'all', 4 | printWidth: 100, 5 | proseWrap: 'never', 6 | endOfLine: 'lf', 7 | overrides: [ 8 | { 9 | files: '.prettierrc', 10 | options: { 11 | parser: 'json', 12 | }, 13 | }, 14 | { 15 | files: 'document.ejs', 16 | options: { 17 | parser: 'html', 18 | }, 19 | }, 20 | ], 21 | }; 22 | -------------------------------------------------------------------------------- /ant-react/config/config.dev.ts: -------------------------------------------------------------------------------- 1 | 2 | import { defineConfig } from 'umi'; 3 | 4 | export default defineConfig({ 5 | define: { 6 | APP_ENV: 'dev', 7 | 'process.env.domain' : 'http://localhost:8080' 8 | }, 9 | }); 10 | -------------------------------------------------------------------------------- /ant-react/config/config.prod.ts: -------------------------------------------------------------------------------- 1 | 2 | import { defineConfig } from 'umi'; 3 | 4 | export default defineConfig({ 5 | define: { 6 | APP_ENV: 'prod', 7 | 'process.env.domain' : 'http://localhost:8080' 8 | 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /ant-react/jest.config.ts: -------------------------------------------------------------------------------- 1 | import { configUmiAlias, createConfig } from '@umijs/max/test'; 2 | 3 | export default async () => { 4 | const config = await configUmiAlias({ 5 | ...createConfig({ 6 | target: 'browser', 7 | }), 8 | }); 9 | console.log(JSON.stringify(config)); 10 | 11 | return { 12 | ...config, 13 | testEnvironmentOptions: { 14 | ...(config?.testEnvironmentOptions || {}), 15 | url: 'http://localhost:8000', 16 | }, 17 | setupFiles: [...(config.setupFiles || []), './tests/setupTests.jsx'], 18 | globals: { 19 | ...config.globals, 20 | localStorage: null, 21 | }, 22 | }; 23 | }; 24 | -------------------------------------------------------------------------------- /ant-react/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react-jsx", 4 | "emitDecoratorMetadata": true, 5 | "experimentalDecorators": true, 6 | "baseUrl": ".", 7 | "paths": { 8 | "@/*": ["./src/*"] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ant-react/public/CNAME: -------------------------------------------------------------------------------- 1 | preview.pro.ant.design -------------------------------------------------------------------------------- /ant-react/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/ant-react/public/favicon.ico -------------------------------------------------------------------------------- /ant-react/public/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/ant-react/public/icons/icon-128x128.png -------------------------------------------------------------------------------- /ant-react/public/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/ant-react/public/icons/icon-192x192.png -------------------------------------------------------------------------------- /ant-react/public/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-ecology/go-iot-platform/d2ed524f637dfd9a8d78db908079350b5385908f/ant-react/public/icons/icon-512x512.png -------------------------------------------------------------------------------- /ant-react/public/pro_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ant-react/src/access.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://umijs.org/docs/max/access#access 3 | * */ 4 | export default function access(initialState: { currentUser?: API.CurrentUser } | undefined) { 5 | const { currentUser } = initialState ?? {}; 6 | return { 7 | canAdmin: currentUser && currentUser.access === 'admin', 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /ant-react/src/components/Footer/index.tsx: -------------------------------------------------------------------------------- 1 | import { GithubOutlined } from '@ant-design/icons'; 2 | import { DefaultFooter } from '@ant-design/pro-components'; 3 | import React from 'react'; 4 | 5 | const Footer: React.FC = () => { 6 | const currentYear = new Date().getFullYear(); 7 | const defaultMessage = "Zen HuiFer" 8 | return ( 9 | , 24 | href: 'https://gitee.com/pychfarm_admin/go-iot-platform', 25 | blankTarget: true, 26 | }, 27 | 28 | ]} 29 | /> 30 | ); 31 | }; 32 | 33 | export default Footer; 34 | -------------------------------------------------------------------------------- /ant-react/src/components/HeaderDropdown/index.tsx: -------------------------------------------------------------------------------- 1 | import { Dropdown } from 'antd'; 2 | import type { DropDownProps } from 'antd/es/dropdown'; 3 | import React from 'react'; 4 | import { createStyles } from 'antd-style'; 5 | import classNames from 'classnames'; 6 | 7 | const useStyles = createStyles(({ token }) => { 8 | return { 9 | dropdown: { 10 | [`@media screen and (max-width: ${token.screenXS}px)`]: { 11 | width: '100%', 12 | }, 13 | }, 14 | }; 15 | }); 16 | 17 | export type HeaderDropdownProps = { 18 | overlayClassName?: string; 19 | placement?: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topCenter' | 'topRight' | 'bottomCenter'; 20 | } & Omit; 21 | 22 | const HeaderDropdown: React.FC = ({ 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 | 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 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ant-vue/src/views/http/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ant-vue/src/views/message-list/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ant-vue/src/views/repair-records/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ant-vue/src/views/shipment-records/index.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ant-vue/src/views/tcp/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ant-vue/src/views/visualization/index.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ant-vue/src/views/websocket/index.vue: -------------------------------------------------------------------------------- 1 | 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 --------------------------------------------------------------------------------