diff --git a/README.md b/README.md index fd77b123..d8df28e6 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ +

logo

diff --git a/data/init/sys_app.json b/data/init/sys_app.json index 5d4f7b05..b842569f 100644 --- a/data/init/sys_app.json +++ b/data/init/sys_app.json @@ -3,7 +3,7 @@ "id": 453554819821637, "appName": "微信小程序", "appId": "wx5eebdd2bab2d805c", - "appSecret": "cd8096ac1d6a901fe98d5f745d2bfc2b", + "appSecret": "a92c69537573141d06a59a5c814dd02c", "appType": "1", "remark": "微信小程序", "tenantId": "452748015218757" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..a354a5c1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,75 @@ +version: "3.4" + +services: + mysql: + container_name: iot-mysql + image: mysql:8 + restart: unless-stopped + tty: true + ports: + - "3306:3306" + environment: + MYSQL_DATABASE: ${MYSQL_DATABASE:-iotkit} + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-123456} + volumes: + - mysql:/var/lib/mysql/ + + + redis: + container_name: iot-redis + image: redis:6-alpine + restart: unless-stopped + ports: + - "6379:6379" + volumes: + - redis:/data + + server: + container_name: iot-server + build: + context: ./ + image: iot-server + restart: unless-stopped + ports: + - "8086:8086" + environment: + # https://github.com/polovyivan/docker-pass-configs-to-container + SPRING_PROFILES_ACTIVE: local + JAVA_OPTS: + ${JAVA_OPTS:- + -Xms512m + -Xmx512m + -Djava.security.egd=file:/dev/./urandom + } + ARGS: + --spring.datasource.dynamic.datasource.master.url=${MASTER_DATASOURCE_URL:-jdbc:mysql://iot-mysql:3306/iotkit?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true} + --spring.datasource.dynamic.datasource.master.username=${MASTER_DATASOURCE_USERNAME:-root} + --spring.datasource.dynamic.datasource.master.password=${MASTER_DATASOURCE_PASSWORD:-123456} + --spring.datasource.dynamic.datasource.slave.url=${SLAVE_DATASOURCE_URL:-jdbc:mysql://iot-mysql:3306/iotkit?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true} + --spring.datasource.dynamic.datasource.slave.username=${SLAVE_DATASOURCE_USERNAME:-root} + --spring.datasource.dynamic.datasource.slave.password=${SLAVE_DATASOURCE_PASSWORD:-123456} + --spring.redis.host=${REDIS_HOST:-iot-redis} + depends_on: + - redis + + admin: + container_name: iot-admin + build: + context: ./iot-ui-admin + args: + NODE_ENV: + ENV=${NODE_ENV:-production} + PUBLIC_PATH=${PUBLIC_PATH:-/} + VUE_APP_TITLE=${VUE_APP_TITLE:-openiita管理系统} + image: iot-admin + restart: unless-stopped + ports: + - "8080:80" + depends_on: + - server + +volumes: + mysql: + driver: local + redis: + driver: local diff --git a/docker-compose/docker-compose-iita.yml b/docker-compose/docker-compose-iita.yml index 9e4dac0f..c03dfe3c 100644 --- a/docker-compose/docker-compose-iita.yml +++ b/docker-compose/docker-compose-iita.yml @@ -14,7 +14,8 @@ services: network_mode: "host" volumes: # - ./admin-service.jar:/admin-service.jar - - /app/data:/app/data/ + - /app/data/components:/app/data/components + - /app/data/converters:/app/data/converters - /app/config:/app/config/ - /app/log:/app/log/ command: diff --git a/docker.env b/docker.env new file mode 100644 index 00000000..71c3bdc1 --- /dev/null +++ b/docker.env @@ -0,0 +1,19 @@ +## mysql +MYSQL_DATABASE=iotkit +MYSQL_ROOT_PASSWORD=123456 + +## server +JAVA_OPTS=-Xms512m -Xmx512m -Djava.security.egd=file:/dev/./urandom + +MASTER_DATASOURCE_URL=jdbc:mysql://iot-mysql:3306/${MYSQL_DATABASE}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true +MASTER_DATASOURCE_USERNAME=root +MASTER_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD} +SLAVE_DATASOURCE_URL=${MASTER_DATASOURCE_URL} +SLAVE_DATASOURCE_USERNAME=${MASTER_DATASOURCE_USERNAME} +SLAVE_DATASOURCE_PASSWORD=${MASTER_DATASOURCE_PASSWORD} +REDIS_HOST=iot-redis + +## admin +NODE_ENV=production +PUBLIC_PATH=/ +VUE_APP_TITLE=iot管理系统 diff --git a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/IJPACommData.java b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/IJPACommData.java index 0873c2cd..f4f711ef 100644 --- a/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/IJPACommData.java +++ b/iot-dao/iot-data-serviceImpl-rdb/src/main/java/cc/iotkit/data/dao/IJPACommData.java @@ -137,5 +137,4 @@ public interface IJPACommData, ID> extends ICommonData { ); } - } diff --git a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java index 014aeb03..22db6d7e 100644 --- a/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java +++ b/iot-module/iot-plugin/iot-plugin-main/src/main/java/cc/iotkit/plugin/main/PluginMainImpl.java @@ -104,17 +104,16 @@ public class PluginMainImpl implements IPluginMain, DeviceService { throw new BizException(ErrCode.PLUGIN_SERVICE_NOT_FOUND); } - if (!(service.getParams() instanceof Map)) { - throw new BizException(ErrCode.PARAMS_EXCEPTION); - } - Map params = (Map) service.getParams(); - IDevice deviceService = deviceServices.get(0); String type = service.getType(); String identifier = service.getIdentifier(); ActionResult result = null; if (ThingService.TYPE_SERVICE.equals(type)) { + if (!(service.getParams() instanceof Map)) { + throw new BizException(ErrCode.PARAMS_EXCEPTION); + } + Map params = (Map) service.getParams(); //服务调用 ServiceInvoke action = ServiceInvoke.builder() .id(service.getMid()) @@ -128,6 +127,10 @@ public class PluginMainImpl implements IPluginMain, DeviceService { publish(service, result.getCode()); } else if (ThingService.TYPE_PROPERTY.equals(type)) { if ("set".equals(identifier)) { + if (!(service.getParams() instanceof Map)) { + throw new BizException(ErrCode.PARAMS_EXCEPTION); + } + Map params = (Map) service.getParams(); //属性设置 PropertySet action = PropertySet.builder() .id(service.getMid()) @@ -144,7 +147,7 @@ public class PluginMainImpl implements IPluginMain, DeviceService { .id(service.getMid()) .productKey(linkPk) .deviceName(linkDn) - .keys(new ArrayList<>(params.keySet())) + .keys((List) service.getParams()) .build(); //调用插件设备服务接口 result = deviceService.propertyGet(action); diff --git a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/handler/RuleDeviceConsumer.java b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/handler/RuleDeviceConsumer.java index 67cd4e80..1b3539eb 100644 --- a/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/handler/RuleDeviceConsumer.java +++ b/iot-module/iot-rule-engine/src/main/java/cc/iotkit/ruleengine/handler/RuleDeviceConsumer.java @@ -23,6 +23,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -53,6 +54,9 @@ public class RuleDeviceConsumer implements ConsumerHandler, A for (DeviceMessageHandler handler : this.handlers) { messageHandlerPool.submit(() -> { try { + if (!(msg.getData() instanceof Map)) { + msg.setData(new HashMap<>()); + } handler.handle(msg); } catch (Throwable e) { log.error("handler message error", e); diff --git a/iot-starter/src/main/java/cc/iotkit/web/controller/AuthController.java b/iot-starter/src/main/java/cc/iotkit/web/controller/AuthController.java index 54ed8b9e..260f7d72 100644 --- a/iot-starter/src/main/java/cc/iotkit/web/controller/AuthController.java +++ b/iot-starter/src/main/java/cc/iotkit/web/controller/AuthController.java @@ -19,6 +19,7 @@ import cn.dev33.satoken.annotation.SaIgnore; import cn.hutool.core.collection.CollUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; @@ -69,6 +70,22 @@ public class AuthController { return loginVo; } + /** + * 小程序登录(示例) + * + * @param xcxCode 小程序code + * @return 结果 + */ + @ApiOperation("小程序登录") + @PostMapping("/xcxLogin") + public LoginVo xcxLogin(@NotBlank(message = "{xcx.appId.not.blank}") String appId,@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) { + LoginVo loginVo = new LoginVo(); + // 生成令牌 + String token = loginService.xcxLogin(appId,xcxCode); + loginVo.setToken(token); + return loginVo; + } + /** * 退出登录 diff --git a/iot-starter/src/main/java/cc/iotkit/web/service/SysLoginService.java b/iot-starter/src/main/java/cc/iotkit/web/service/SysLoginService.java index 8fad215f..9e8b1a69 100644 --- a/iot-starter/src/main/java/cc/iotkit/web/service/SysLoginService.java +++ b/iot-starter/src/main/java/cc/iotkit/web/service/SysLoginService.java @@ -172,7 +172,7 @@ public class SysLoginService { // 生成token LoginHelper.loginByDevice(loginUser, DeviceType.XCX); -// recordLoginInfo(loginUser.getTenantId(), user.getNickName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); + recordLoginInfo(loginUser.getTenantId(), user.getNickName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); // recordLoginInfo(user.getId()); return StpUtil.getTokenValue(); } diff --git a/iot-starter/src/main/resources/application.yml b/iot-starter/src/main/resources/application.yml index f98e2129..294a47e9 100644 --- a/iot-starter/src/main/resources/application.yml +++ b/iot-starter/src/main/resources/application.yml @@ -100,11 +100,11 @@ spring: #================es时序数据配置结束===============>> #<<===========tdengine时序数据库配置开始============ -# td-datasource: -# url: jdbc:TAOS-RS://127.0.0.1:6041/iotkit?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8 -# username: root -# password: taosdata -# driverClassName: com.taosdata.jdbc.rs.RestfulDriver + # td-datasource: + # url: jdbc:TAOS-RS://127.0.0.1:6041/iotkit?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8 + # username: root + # password: taosdata + # driverClassName: com.taosdata.jdbc.rs.RestfulDriver #===========tdengine时序数据库配置开始============>> diff --git a/iot-starter/src/main/resources/sql/schema-postgre.sql b/iot-starter/src/main/resources/sql/schema-postgre.sql new file mode 100644 index 00000000..c593d651 --- /dev/null +++ b/iot-starter/src/main/resources/sql/schema-postgre.sql @@ -0,0 +1,112 @@ + +-- ---------------------------- +-- 18、代码生成业务表 +-- ---------------------------- +drop table if exists gen_table; +create table if not exists gen_table +( + table_id int8, + data_name varchar(200) default ''::varchar, + table_name varchar(200) default ''::varchar, + table_comment varchar(500) default ''::varchar, + sub_table_name varchar(64) default ''::varchar, + sub_table_fk_name varchar(64) default ''::varchar, + class_name varchar(100) default ''::varchar, + tpl_category varchar(200) default 'crud'::varchar, + package_name varchar(100) default null::varchar, + module_name varchar(30) default null::varchar, + business_name varchar(30) default null::varchar, + function_name varchar(50) default null::varchar, + function_author varchar(50) default null::varchar, + gen_type char default '0'::bpchar not null, + gen_path varchar(200) default '/'::varchar, + options varchar(1000) default null::varchar, + create_dept int8, + create_by int8, + create_time timestamp, + update_by int8, + update_time timestamp, + remark varchar(500) default null::varchar, + constraint gen_table_pk primary key (table_id) + ); + +comment on table gen_table is '代码生成业务表'; +comment on column gen_table.table_id is '编号'; +comment on column gen_table.data_name is '数据源名称'; +comment on column gen_table.table_name is '表名称'; +comment on column gen_table.table_comment is '表描述'; +comment on column gen_table.sub_table_name is '关联子表的表名'; +comment on column gen_table.sub_table_fk_name is '子表关联的外键名'; +comment on column gen_table.class_name is '实体类名称'; +comment on column gen_table.tpl_category is '使用的模板(CRUD单表操作 TREE树表操作)'; +comment on column gen_table.package_name is '生成包路径'; +comment on column gen_table.module_name is '生成模块名'; +comment on column gen_table.business_name is '生成业务名'; +comment on column gen_table.function_name is '生成功能名'; +comment on column gen_table.function_author is '生成功能作者'; +comment on column gen_table.gen_type is '生成代码方式(0zip压缩包 1自定义路径)'; +comment on column gen_table.gen_path is '生成路径(不填默认项目路径)'; +comment on column gen_table.options is '其它生成选项'; +comment on column gen_table.create_dept is '创建部门'; +comment on column gen_table.create_by is '创建者'; +comment on column gen_table.create_time is '创建时间'; +comment on column gen_table.update_by is '更新者'; +comment on column gen_table.update_time is '更新时间'; +comment on column gen_table.remark is '备注'; + +-- ---------------------------- +-- 19、代码生成业务表字段 +-- ---------------------------- +drop table if exists gen_table_column; +create table if not exists gen_table_column +( + column_id int8, + table_id int8, + column_name varchar(200) default null::varchar, + column_comment varchar(500) default null::varchar, + column_type varchar(100) default null::varchar, + java_type varchar(500) default null::varchar, + java_field varchar(200) default null::varchar, + is_pk char default null::bpchar, + is_increment char default null::bpchar, + is_required char default null::bpchar, + is_insert char default null::bpchar, + is_edit char default null::bpchar, + is_list char default null::bpchar, + is_query char default null::bpchar, + query_type varchar(200) default 'EQ'::varchar, + html_type varchar(200) default null::varchar, + dict_type varchar(200) default ''::varchar, + sort int4, + create_dept int8, + create_by int8, + create_time timestamp, + update_by int8, + update_time timestamp, + constraint gen_table_column_pk primary key (column_id) + ); + +comment on table gen_table_column is '代码生成业务表字段'; +comment on column gen_table_column.column_id is '编号'; +comment on column gen_table_column.table_id is '归属表编号'; +comment on column gen_table_column.column_name is '列名称'; +comment on column gen_table_column.column_comment is '列描述'; +comment on column gen_table_column.column_type is '列类型'; +comment on column gen_table_column.java_type is 'JAVA类型'; +comment on column gen_table_column.java_field is 'JAVA字段名'; +comment on column gen_table_column.is_pk is '是否主键(1是)'; +comment on column gen_table_column.is_increment is '是否自增(1是)'; +comment on column gen_table_column.is_required is '是否必填(1是)'; +comment on column gen_table_column.is_insert is '是否为插入字段(1是)'; +comment on column gen_table_column.is_edit is '是否编辑字段(1是)'; +comment on column gen_table_column.is_list is '是否列表字段(1是)'; +comment on column gen_table_column.is_query is '是否查询字段(1是)'; +comment on column gen_table_column.query_type is '查询方式(等于、不等于、大于、小于、范围)'; +comment on column gen_table_column.html_type is '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)'; +comment on column gen_table_column.dict_type is '字典类型'; +comment on column gen_table_column.sort is '排序'; +comment on column gen_table_column.create_dept is '创建部门'; +comment on column gen_table_column.create_by is '创建者'; +comment on column gen_table_column.create_time is '创建时间'; +comment on column gen_table_column.update_by is '更新者'; +comment on column gen_table_column.update_time is '更新时间';