[
  {
    "path": ".gitignore",
    "content": ".idea\ntarget\n*.iml\n.DS_Store"
  },
  {
    "path": "README.md",
    "content": "\n自定义BI改变了传统IT主导开发固定报表的时代，让数据能够即席分析达到所见即所得，随着大模型的兴起与火热，LLMs 结合数据可视化技术，通过问答的方式能够让系统智能与数据交互与生成图表，无论是BI copilot还是ChatBI, 除了替代之前小助手功能只能查询已有报表数据外，更多的是省略创建dashboard的时候图表的拖拉拽操作，让系统自动生成的图表能够在dashboard中布局应用。\n![自动图表生成](./doc/photo/自动生成图表.png)\n\n#### 一、实现思路主要考虑\n\n1、如果没有大模型或者大模型服务宕机，自动化生成可视化工程化就不能实现？\n\n        —— 直接解耦，大模型不能影响主体工程，图表这块不能大模型生成。\n        \n2、如果大模型正常服务能够推理，是否所有的问答都要经过推理服务？\n\n        —— 大模型的推理是否那么靠谱稳定、对应响应的耗时以及对应采用商业大模型服务的费用成本因素。\n        \n3、以SQL交互为核心的配套组件，通过系统化的工程来达到生产可用要求。\n\n      借鉴[SQLChat](https://github.com/sqlchat/sqlchat), [DB-GPT](https://github.com/csunny/DB-GPT), 的开源项目思路，确定以SQL生成为核心，和数据库交互获取数据，通过data + 可视化图表组件方式实现。不考虑大模型自动生成图表的方式，主要考虑一是美观，二是灵活性，三最主要的是性能是否可控，尤其是大量查询的data很大时，是否分页等可以手动人为干预控制；而靠大模型自动生成图表类似markdown/html估计不会很理想。\n\n\n#### 二、主要思路框架\n   ![框架图](./doc/photo/模块架构.jpeg)\n\n#### 三、说明\n1、是否有表，指标字段，维度字段列级的查询权限，以及行级 ${input_dim_conditions} <= ${user_has_permission}，否直接报权限不足。\n\n2、如果维度、度量，都来自于一张表，解析查询条件，然后sql模版组装：\n```sql\nselect ${input_dim_names} , ${input_metric_names} from ${get_meta_table_name} where ${input_dim_conditions}  [group by $s] [order by $s];\n```\n    这种sql组装拼接成熟度很高，不一定直接依赖大模型服务，唯一有难点的就是文本中对应条件的解析。\n    \n3、 如果维度、度量都来自于多张表，则查找相似匹配的问题对应的答案Sql:\n\n      ①、如果有对应sql, 则直接应用，可能只组装的就是sql的where条件。\n      \n      ②、如果有相似sql, 例如2张表的join找2张表join的sql模版则对应需要增加子查询方式与拼接where,  即\n```sql\nselect ${input_dim_names} , ${input_metric_names} from ( ${get_query_sql} ) TT where ${input_dim_conditions}  [group by $s] [order by $s];\n```\n    \n**属于可选步骤(也可以直接调用大模型能力）**，这里where一般可以，sql引擎都支持谓词下推，但是子查询多列可能带来性能影响，不是所有的sql引擎都支持列剪裁。 同时注意相似如果是2张表join,则不能找3张表join的sql语句去拼接。\n\n    ③、如果sql为null或者校验error的sql, 则通过提示词(问题、schema)交给大模型推理返回推理生成查询sql。\n\n整体框架可能存在不足，但是相信随着时间的进步，大模型会越来越稳定可靠，响应快 以及细分领域SQL LLMs的诞生；也相信利他主义的开源者，会诞生更优秀的ChatBI项目。\n#### 四、模块结构\n\n|--rest  api层\n\n&nbsp;&nbsp;&nbsp;&nbsp;|-- server  服务层，调用解析，执行sql，和数据库交互\n   \n&nbsp;&nbsp;&nbsp;&nbsp;|-- mapper  元数据匹配\n   \n&nbsp;&nbsp;&nbsp;&nbsp;|--validate  sql校验\n   \n|--common\n\n|--parse   文本解析\n\n|--plugins 大模型插件，和大模型交互，智能生成\n"
  },
  {
    "path": "chat_rest/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>chatBI</artifactId>\n        <groupId>com.am</groupId>\n        <version>1.0-SNAPSHOT</version>\n        <relativePath/>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>chat_rest</artifactId>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter</artifactId>\n            <exclusions>\n                <exclusion>\n                    <artifactId>logback-classic</artifactId>\n                    <groupId>ch.qos.logback</groupId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-web</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-context-support</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-websocket</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-configuration-processor</artifactId>\n            <optional>true</optional>\n        </dependency>\n\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-test</artifactId>\n            <scope>test</scope>\n        </dependency>\n\n        <dependency>\n            <groupId>io.springfox</groupId>\n            <artifactId>springfox-swagger2</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>io.springfox</groupId>\n            <artifactId>springfox-swagger-ui</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>com.github.pagehelper</groupId>\n            <artifactId>pagehelper-spring-boot-starter</artifactId>\n            <exclusions>\n                <exclusion>\n                    <artifactId>mybatis-spring-boot-starter</artifactId>\n                    <groupId>org.mybatis.spring.boot</groupId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <!-- db -->\n        <dependency>\n            <groupId>org.mybatis.spring.boot</groupId>\n            <artifactId>mybatis-spring-boot-starter</artifactId>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.springframework.boot</groupId>\n                    <artifactId>spring-boot-starter</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n\n        <dependency>\n            <groupId>com.alibaba</groupId>\n            <artifactId>druid-spring-boot-starter</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>mysql</groupId>\n            <artifactId>mysql-connector-java</artifactId>\n            <scope>runtime</scope>\n        </dependency>\n\n        <dependency>\n            <groupId>org.mybatis.spring.boot</groupId>\n            <artifactId>mybatis-spring-boot-starter-test</artifactId>\n        </dependency>\n\n        <!-- tool -->\n        <dependency>\n            <groupId>org.projectlombok</groupId>\n            <artifactId>lombok</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>org.apache.commons</groupId>\n            <artifactId>commons-lang3</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n            <exclusions>\n                <exclusion>\n                    <artifactId>logback-core</artifactId>\n                    <groupId>ch.qos.logback</groupId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-core</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>redis.clients</groupId>\n            <artifactId>jedis</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>com.am</groupId>\n            <artifactId>plugins</artifactId>\n            <scope>compile</scope>\n            <version>1.0-SNAPSHOT</version>\n        </dependency>\n    </dependencies>\n\n    <profiles>\n        <profile>\n            <id>dev</id>\n            <properties>\n                <env>dev</env>\n            </properties>\n            <activation>\n                <activeByDefault>true</activeByDefault>\n            </activation>\n        </profile>\n        <profile>\n            <id>test</id>\n            <properties>\n                <env>test</env>\n            </properties>\n        </profile>\n        <profile>\n            <id>prod</id>\n            <properties>\n                <env>prod</env>\n            </properties>\n        </profile>\n        <profile>\n            <id>press</id>\n            <properties>\n                <env>press</env>\n            </properties>\n        </profile>\n    </profiles>\n\n    <build>\n        <finalName>${project.artifactId}</finalName>\n        <sourceDirectory>src/main/java</sourceDirectory>\n        <scriptSourceDirectory>src/main/shell</scriptSourceDirectory>\n        <resources>\n            <resource>\n                <directory>src/main/resources</directory>\n                <includes>\n                    <include>*.xml</include>\n                    <include>**/*.xml</include>\n                    <include>*.yml</include>\n                    <include>static/</include>\n                    <include>templates/</include>\n                    <include>mapper/</include>\n                </includes>\n                <!--<targetPath>${project.build.directory}/config</targetPath>-->\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.mybatis.generator</groupId>\n                <artifactId>mybatis-generator-maven-plugin</artifactId>\n                <version>1.3.2</version>\n                <dependencies>\n                    <dependency>\n                        <groupId>mysql</groupId>\n                        <artifactId>mysql-connector-java</artifactId>\n                        <version>5.1.38</version>\n                    </dependency>\n                </dependencies>\n                <executions>\n                    <execution>\n                        <id>Generate MyBatis Artifacts</id>\n                        <phase>none</phase>\n                        <goals>\n                            <goal>generate</goal>\n                        </goals>\n                    </execution>\n                </executions>\n                <configuration>\n                    <!--配置文件的路径-->\n                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>\n                    <overwrite>true</overwrite>\n                </configuration>\n            </plugin>\n            <!-- 打包jar文件时，配置manifest文件，加入lib包的jar依赖 -->\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-jar-plugin</artifactId>\n                <version>3.0.2</version>\n                <configuration>\n                    <archive>\n                        <!-- 生成的jar中，不要包含pom.xml和pom.properties这两个文件 -->\n                        <addMavenDescriptor>false</addMavenDescriptor>\n                        <!-- 清单文件 -->\n                        <manifest>\n                            <addClasspath>true</addClasspath>\n                            <classpathPrefix>lib/</classpathPrefix>\n                            <mainClass>${start-class}</mainClass>\n                        </manifest>\n                        <!-- 给清单文件添加键值对(配置文件外置) -->\n                        <manifestEntries>\n                            <Class-Path>config/</Class-Path>\n                        </manifestEntries>\n                    </archive>\n                    <excludes>\n                        <exclude>*.xml</exclude>\n                        <exclude>*.conf</exclude>\n                        <exclude>*.yml</exclude>\n                        <exclude>*.properties</exclude>\n                    </excludes>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-assembly-plugin</artifactId>\n                <configuration>\n                    <descriptors>\n                        <descriptor>src/main/resources/assembly.xml</descriptor>\n                    </descriptors>\n                    <appendAssemblyId>false</appendAssemblyId>\n                </configuration>\n                <executions>\n                    <execution>\n                        <id>make-assembly</id>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>single</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n</project>"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/ChatBIApplication.java",
    "content": "package com.am.chat.bi;\n\nimport org.mybatis.spring.annotation.MapperScan;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.web.servlet.ServletComponentScan;\n\n@SpringBootApplication\n@ServletComponentScan\n@MapperScan(basePackages = { \"com.am.chat.bi.dao\" })\npublic class ChatBIApplication {\n    private static final Logger LOG = LoggerFactory.getLogger(ChatBIApplication.class);\n\n    public static void main(String[] args) {\n        SpringApplication.run(ChatBIApplication.class, args);\n        LOG.info(\"ChatBIApplication start run!\");\n    }\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/comm/AppCode.java",
    "content": "package com.am.chat.bi.comm;\n\n/**\n * @author wpl\n * 后期数据库配置\n */\npublic enum AppCode {\n    VSKIT(1, \"vskit\")\n    ;\n    private int code;\n    private String appName;\n\n    AppCode(int code, String appName) {\n        this.code = code;\n        this.appName = appName;\n    }\n\n    public int getCode() {\n        return code;\n    }\n\n    public String getAppName() {\n        return appName;\n    }\n\n    public static String getAppName(int code) {\n        switch (code){\n            case 1:\n            case 2:\n            default:\n                return VSKIT.getAppName();\n        }\n    }\n    \n}\n\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/comm/ErrorCode.java",
    "content": "package com.am.chat.bi.comm;\n\n/**\n * @author wpl\n */\npublic enum ErrorCode {\n    SUCCESS(1000, \"success\"),\n    FAIL(1010, \"fail\"),\n    FAIL_LLMs(1020, \"fail LLMs\"),\n    FAIL_INSERT(1001, \"fail insert\"),\n    FAIL_UPDATE(1002, \"fail update\"),\n    FAIL_SELECT(1003, \"fail select\"),\n    FAIL_UPLOAD(1004, \"fail upload\"),\n    FAIL_EXPORT(1005, \"fail export\"),\n    FAIL_DEL(1006, \"fail delete\"),\n    FAIL_RUN_TASK(1007, \"fail run task\"),\n    ;\n\n    private int code;\n    private String msg;\n\n    ErrorCode(int code, String msg) {\n        this.code = code;\n        this.msg = msg;\n    }\n\n    public int getCode() {\n        return code;\n    }\n\n    public String getMsg() {\n        return msg;\n    }\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/comm/Result.java",
    "content": "package com.am.chat.bi.comm;\n\nimport io.swagger.annotations.ApiModel;\nimport io.swagger.annotations.ApiModelProperty;\nimport lombok.Data;\nimport org.apache.commons.lang3.builder.ToStringBuilder;\nimport org.apache.commons.lang3.builder.ToStringStyle;\n\n/**\n * @author wpl\n */\n@Data\n@ApiModel\npublic class Result<T> {\n\n    @ApiModelProperty(value = \"元数据\", required = true)\n    private ResultMeta meta;\n\n    @ApiModelProperty(value = \"返回结果\")\n    private T response;\n\n    public Result() {}\n\n    private Result(ErrorCode errorCode) {\n        this.meta = new ResultMeta(errorCode);\n    }\n\n    public static <T> Result<T> success() {\n        return new Result<>(ErrorCode.SUCCESS);\n    }\n\n    public static <T> Result<T> fail(ErrorCode errorCode) {\n        return new Result<>(errorCode);\n    }\n\n    public static boolean isSuccess(Result result) {\n        return result != null && result.meta != null && result.meta.getCode() == 0;\n    }\n\n    public Result<T> withErrorMsg(String msg) {\n        this.meta.setMsg(msg);\n        return this;\n    }\n\n    public Result<T> withResponse(T response) {\n        this.response = response;\n        return this;\n    }\n\n    @Override\n    public String toString() {\n        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);\n    }\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/comm/ResultMeta.java",
    "content": "package com.am.chat.bi.comm;\n\nimport io.swagger.annotations.ApiModel;\nimport io.swagger.annotations.ApiModelProperty;\nimport lombok.Data;\n\n/**\n * @Author: wpl\n */\n@Data\n@ApiModel\npublic class ResultMeta {\n\n    @ApiModelProperty(value = \"错误码\", required = true)\n    private int code;\n    @ApiModelProperty(value = \"描述\", required = true)\n    private String msg;\n\n    public ResultMeta() {}\n\n    public ResultMeta(ErrorCode errorCode) {\n        this.code = errorCode.getCode();\n        this.msg = errorCode.getMsg();\n    }\n\n    void setMsg(String msg) {\n        this.msg = this.msg + \" : \" + msg;\n    }\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/comm/StateCode.java",
    "content": "package com.am.chat.bi.comm;\n\n/**\n * @author wpl\n */\npublic enum StateCode {\n    IS_ADD(0),\n    IS_UPDATE(1),\n    IS_DEL(2)\n    ;\n\n    private Integer code;\n    StateCode(Integer code) {\n        this.code = code;\n    }\n\n    public static StateCode getStateCode(Integer code) {\n        switch (code){\n            case 1:\n                return IS_UPDATE;\n            case 2:\n                return IS_DEL;\n            default:\n                return IS_ADD;\n        }\n    }\n\n    public Integer getCode() {\n        return code;\n    }\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/comm/Utils.java",
    "content": "package com.am.chat.bi.comm;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.concurrent.atomic.AtomicLong;\n\npublic class Utils {\n    private static final Logger LOG = LoggerFactory.getLogger(Utils.class);\n    public static String getStringDate(Date date) {\n        SimpleDateFormat formatter = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n        String dateString = formatter.format(date);\n        return dateString;\n    }\n\n    public static Date getStringToDate(String date) {\n        SimpleDateFormat formatter = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n        try {\n            Date result = formatter.parse(date);\n            return result;\n        } catch (ParseException e) {\n            e.printStackTrace();\n            LOG.error(\"string date 解析出错\", e);\n        }\n        return null;\n    }\n}\n\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/config/SwaggerConfiguration.java",
    "content": "package com.am.chat.bi.config;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport springfox.documentation.builders.ApiInfoBuilder;\nimport springfox.documentation.builders.PathSelectors;\nimport springfox.documentation.builders.RequestHandlerSelectors;\nimport springfox.documentation.service.ApiInfo;\nimport springfox.documentation.spi.DocumentationType;\nimport springfox.documentation.spring.web.plugins.Docket;\nimport springfox.documentation.swagger2.annotations.EnableSwagger2;\n\n\n/**\n * @author wpl\n */\n@EnableSwagger2\n@Configuration\npublic class SwaggerConfiguration {\n    @Value(\"${com.am.chat.bi.api.doc.path:com.am.chat.bi}\")\n    private String path;\n\n    @Value(\"${com.am.chat.bi.api.doc.title:Chat BI Platform API doc}\")\n    private String title;\n\n    @Value(\"${com.am.chat.bi.api.doc.version:1.0}\")\n    private String version;\n\n    @Value(\"${com.am.chat.bi.api.doc.description:Chat BI Platform API doc}\")\n    private String description;\n\n    @Bean\n    public Docket createApi() {\n        return new Docket(DocumentationType.SWAGGER_2)\n                .apiInfo(apiInfo())\n                .pathMapping(\"/\")\n                .select()\n                .apis(RequestHandlerSelectors.basePackage(path))\n                .paths(PathSelectors.any())\n                .build();\n    }\n\n    private ApiInfo apiInfo() {\n        return new ApiInfoBuilder()\n                .title(title)\n                .description(description)\n                .version(version)\n                .build();\n    }\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/controller/LLMsController.java",
    "content": "package com.am.chat.bi.controller;\n\n\nimport com.am.chat.bi.comm.Result;\nimport com.am.chat.bi.service.LLMsService;\nimport io.swagger.annotations.Api;\nimport io.swagger.annotations.ApiOperation;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RestController;\n\n@RestController\n@RequestMapping(\"/chat\")\n@Api(value = \"大模型服务\", description = \"大模型服务\", tags = {\"LLMs APIß\"})\npublic class LLMsController {\n\n    @Autowired\n    LLMsService llMsService;\n\n    @PostMapping(value = \"/intention\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\n    @ApiOperation(value = \"查询意图\", notes = \"查询意图\", response = Result.class)\n    public ResponseEntity<?> intention(@RequestBody String queryContent) {\n        Result result = llMsService.getIntention(queryContent);\n        return new ResponseEntity<>(result, HttpStatus.OK);\n    }\n\n    @PostMapping(value = \"/dimMetrics\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\n    @ApiOperation(value = \"查询维度指标\", notes = \"查询维度指标\", response = Result.class)\n    public ResponseEntity<?> dimMetrics(@RequestBody String queryContent) {\n        Result result = llMsService.getDimMetric(queryContent);\n        return new ResponseEntity<>(result, HttpStatus.OK);\n    }\n\n    @PostMapping(value = \"/querySql\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\n    @ApiOperation(value = \"生成查询sql\", notes = \"生成查询sql\", response = Result.class)\n    public ResponseEntity<?> querySql(@RequestBody String queryContent) {\n        Result result = llMsService.getSql(queryContent);\n        return new ResponseEntity<>(result, HttpStatus.OK);\n    }\n\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/domain/dao/SchemaMetaInfo.java",
    "content": "package com.am.chat.bi.domain.dao;\n\npublic class SchemaMetaInfo {\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/domain/vo/ResponseVo.java",
    "content": "package com.am.chat.bi.domain.vo;\n\nimport lombok.Data;\n\n/**\n * @author wpl\n * @param <T>\n */\n@Data\npublic class ResponseVo<T> {\n    //返回插入或者修改的主键id\n    private String name;\n    private T value;\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/service/LLMsService.java",
    "content": "package com.am.chat.bi.service;\n\nimport com.am.chat.bi.comm.Result;\n\npublic interface LLMsService {\n    Result getIntention(String queryContent);\n    Result getDimMetric(String queryContent);\n    Result getSql(String queryContent);\n}\n"
  },
  {
    "path": "chat_rest/src/main/java/com/am/chat/bi/service/impl/LLMsServiceImpl.java",
    "content": "package com.am.chat.bi.service.impl;\n\nimport com.am.chat.bi.comm.ErrorCode;\nimport com.am.chat.bi.comm.Result;\nimport com.am.chat.bi.domain.vo.ResponseVo;\nimport com.am.chat.bi.service.LLMsService;\nimport com.am.chat.bi.utils.AliLLMsUtil;\nimport com.am.chat.bi.utils.LLMsResultUtil;\nimport com.am.chat.bi.utils.PromptUtil;\nimport com.google.gson.JsonElement;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class LLMsServiceImpl implements LLMsService {\n\n    private static final Logger LOG = LoggerFactory.getLogger(LLMsServiceImpl.class);\n\n    @Override\n    public Result getIntention(String queryContent) {\n        LOG.info(\"chat query content: {}\",  queryContent);\n        try {\n            String intentionPrompt = PromptUtil.getIntentionPrompt(queryContent);\n            String intentionResult = AliLLMsUtil.getResult(intentionPrompt);\n            String result = LLMsResultUtil.getIntentionResult(intentionResult);\n\n            ResponseVo responseVo = new ResponseVo();\n            responseVo.setName(\"result\");\n            responseVo.setValue(result);\n\n            return Result.success().withResponse(responseVo);\n        } catch (Exception e) {\n            LOG.error(\"用户查询意图大模型结果判断异常：\", e);\n            return Result.fail(ErrorCode.FAIL_LLMs).withErrorMsg(e.getMessage());\n        }\n    }\n\n    @Override\n    public Result getDimMetric(String queryContent) {\n        LOG.info(\"chat query content: {}\",  queryContent);\n        try {\n            String dimensionMetricPrompt = PromptUtil.getDimensionMetricPrompt(queryContent);\n            String dimensionMetricResult = AliLLMsUtil.getResult(dimensionMetricPrompt);\n\n            String dimMetricJson = LLMsResultUtil.getDimMetricJson(dimensionMetricResult);\n\n            JsonElement dimensions = LLMsResultUtil.getJsonValue(dimMetricJson, \"dimensions\");\n            JsonElement metrics = LLMsResultUtil.getJsonValue(dimMetricJson, \"metrics\");\n\n            ResponseVo responseVo = new ResponseVo();\n            responseVo.setName(\"dimensions\");\n            responseVo.setValue(dimensions);\n\n            responseVo.setName(\"metrics\");\n            responseVo.setValue(metrics);\n            return Result.success().withResponse(responseVo);\n        } catch (Exception e) {\n            LOG.error(\"用户查询大模型维度指标解析异常：\", e);\n            return Result.fail(ErrorCode.FAIL_LLMs).withErrorMsg(e.getMessage());\n        }\n    }\n\n    @Override\n    public Result getSql(String queryContent) {\n        LOG.info(\"chat query content: {}\",  queryContent);\n        try {\n            //TODO： 待补充数据库类型，基于解析的元数据信息\n            String schemaInfo = \"{\\n\" +\n                    \"    \\\"schema\\\":\\\"report_db\\\",\\n\" +\n                    \"    \\\"tables\\\":[\\n\" +\n                    \"        \\\"dim_table\\\",\\n\" +\n                    \"        \\\"metric_table\\\"\\n\" +\n                    \"    ],\\n\" +\n                    \"    \\\"dim_table\\\":[\\n\" +\n                    \"        {\\n\" +\n                    \"            \\\"dim_date\\\":\\\"date\\\",\\n\" +\n                    \"            \\\"dim_app_id\\\":\\\"int\\\",\\n\" +\n                    \"            \\\"dim_app_name\\\":\\\"varchar\\\"\\n\" +\n                    \"        },\\n\" +\n                    \"        {\\n\" +\n                    \"            \\\"count_date\\\":\\\"date\\\",\\n\" +\n                    \"            \\\"app_id\\\":\\\"int\\\",\\n\" +\n                    \"            \\\"app_pv\\\":\\\"bigint\\\",\\n\" +\n                    \"            \\\"app_uv\\\":\\\"bigint\\\"\\n\" +\n                    \"        }\\n\" +\n                    \"    ]\\n\" +\n                    \"}\";\n\n            String sqlPrompt = PromptUtil.getSqlPrompt(queryContent,\"postgresql\",schemaInfo, null);\n            LOG.info(\"LLMs sql prompt content: {}\",  sqlPrompt);\n            String sqlResult = AliLLMsUtil.getResult(sqlPrompt);\n            String result = LLMsResultUtil.getSqlResult(sqlResult);\n\n            ResponseVo responseVo = new ResponseVo();\n            responseVo.setName(\"result\");\n            responseVo.setValue(result);\n\n            return Result.success().withResponse(responseVo);\n        } catch (Exception e) {\n            LOG.error(\"用户查询大模型生成sql异常：\", e);\n            return Result.fail(ErrorCode.FAIL_LLMs).withErrorMsg(e.getMessage());\n        }\n    }\n}\n"
  },
  {
    "path": "chat_rest/src/main/resources/application-dev.yml",
    "content": "server:\n  port: 8498\n\nsecurity:\n  basic:\n    enabled=false:\n\nspring:\n  datasource:\n    name: dev\n    url: jdbc:mysql://127.0.0.1:3306/chat_bi?characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true\n    username: root\n    password: 123456\n"
  },
  {
    "path": "chat_rest/src/main/resources/application.yml",
    "content": "server:\n  context-path: /chatBI\n  tomcat:\n    accesslog:\n      enabled: false\n      buffered: false\n      directory:\n      pattern: common\n    awaitTerminationInSec: 30\n\nspring:\n  profiles:\n    ## dev, test, prod\n    active: dev\n  datasource:\n    type: com.alibaba.druid.pool.DruidDataSource\n    driver-class-name: com.mysql.jdbc.Driver\n    druid:\n      filters:\n      # 初始化大小，最小，最大\n      initial-size: 1\n      max-active: 20\n      min-idle: 1\n      # 配置获取连接等待超时的时间\n      max-wait: 5000\n      # 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒\n      time-between-eviction-runs-millis: 60000\n      # 配置一个连接在池中最小生存的时间，单位是毫秒\n      min-evictable-idle-time-millis: 30000\n      validation-query: select 'x'\n      test-while-idle: true\n      test-on-borrow: false\n      test-on-return: false\n      pool-prepared-statements: true\n      max-open-prepared-statements: 20\n      # 配置监控页面密码登录\n#      stat-view-servlet:\n#        login-password: druid\n#        login-username: druid\n  http:\n    multipart:\n      max-file-size: 1024MB\n      max-request-size: 1024MB\n\nmybatis:\n  mapperLocations: classpath:mapper/*.xml\n  configuration:\n    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl\n\npagehelper:\n  helperDialect: mysql\n  reasonable: true\n\nmanagement:\n  health:\n    redis:\n      enabled: false"
  },
  {
    "path": "chat_rest/src/main/resources/assembly.xml",
    "content": "<assembly xmlns=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd\nhttp://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 \">\n  <id>${project.version}</id>\n  <!-- 最终打包成一个用于发布的tar.gz文件 -->\n  <formats>\n    <format>tar.gz</format>\n  </formats>\n\n  <includeBaseDirectory>true</includeBaseDirectory>\n\n  <!-- Adds dependencies to zip package under lib directory -->\n  <dependencySets>\n    <dependencySet>\n      <!-- 不使用项目的artifact，第三方jar不要解压，打包进zip文件的lib目录 -->\n      <!-- <useProjectArtifact>false</useProjectArtifact> -->\n      <outputDirectory>lib</outputDirectory>\n      <unpack>false</unpack>\n    </dependencySet>\n  </dependencySets>\n\n  <fileSets>\n    <!-- 把项目相关的说明文件，打包进zip文件的根目录 -->\n    <fileSet>\n      <directory>${project.basedir}</directory>\n      <outputDirectory>/</outputDirectory>\n      <includes>\n        <include>README*</include>\n        <include>LICENSE*</include>\n        <include>NOTICE*</include>\n      </includes>\n    </fileSet>\n\n    <!-- 把项目的配置文件，打包进zip文件的config目录 -->\n    <fileSet>\n      <directory>src/main/resources</directory>\n      <outputDirectory>config/</outputDirectory>\n      <!-- <fileMode>644</fileMode> 修改权限 -->\n      <includes>\n        <include>*.xml</include>\n        <include>*.yml</include>\n        <include>static/</include>\n        <include>templates/</include>\n        <include>mapper/</include>\n      </includes>\n      <excludes>\n        <exclude>logback-test.xml</exclude>\n        <exclude>generatorConfig.xml</exclude>\n        <exclude>application-*.yml</exclude>\n      </excludes>\n    </fileSet>\n\n    <fileSet>\n      <directory>src/main/resources</directory>\n      <outputDirectory>config/</outputDirectory>\n      <includes>\n        <include>application-${env}.yml</include>\n      </includes>\n    </fileSet>\n\n    <!-- 把项目的脚本文件目录（ src/main/shell ）中的启动脚本文件，打包进zip文件的跟目录 -->\n    <fileSet>\n      <directory>${project.build.scriptSourceDirectory}</directory>\n      <outputDirectory>bin</outputDirectory>\n      <includes>\n        <include>*.*</include>\n      </includes>\n      <filtered>true</filtered>\n      <fileMode>0755</fileMode>\n    </fileSet>\n\n    <fileSet>\n      <directory>src/main/resources/${env}</directory>\n      <outputDirectory>bin</outputDirectory>\n      <includes>\n        <include>setenv.sh</include>\n      </includes>\n    </fileSet>\n\n    <!-- 把项目自己编译出来的jar文件，打包进zip文件的根目录 -->\n    <fileSet>\n      <directory>${project.build.directory}</directory>\n      <outputDirectory></outputDirectory>\n      <includes>\n        <include>*.jar</include>\n      </includes>\n    </fileSet>\n  </fileSets>\n</assembly>\n"
  },
  {
    "path": "chat_rest/src/main/resources/dev/setenv.sh",
    "content": "#!/bin/sh\nPRG=\"$0\"\nPRGDIR=`dirname \"$PRG\"`\nBASE_HOME=`cd \"$PRGDIR/..\" >/dev/null; pwd`\n\n#server内存配置\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -server -Xms1G -Xmx1G -Xmn512M -XX:PermSize=128M -XX:MaxPermSize=256M -Xss512k -XX:SurvivorRatio=8\"\n\n#gc\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -XX:MaxTenuringThreshold=4 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=2 -XX:+ExplicitGCInvokesConcurrent  -XX:+CMSScavengeBeforeRemark\"\n\n#gc日志\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -Xloggc:$BASE_HOME/logs/jvm/gc.log.`date +%Y-%m-%d_%H_%M_%S` \\\n -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:PrintFLSStatistics=1\"\n\n#内存溢出\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$BASE_HOME/logs/heapdump.hprof\"\n"
  },
  {
    "path": "chat_rest/src/main/resources/logback-dev.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration scan=\"true\" scanPeriod=\"60 seconds\" debug=\"false\">\n\t<property name=\"log.home\" value=\"${log.home:-logs}\" />\n\n\t<appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n\t\t<!-- 对日志进行格式化 -->\n\t\t<encoder>\n\t\t\t<charset>UTF-8</charset>\n\t\t\t<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>\n\t\t</encoder>\n\t</appender>\n\n\t<logger name=\"com.am.chat.bi\" additivity=\"FALSE\" level=\"INFO\">\n\t\t<appender-ref ref=\"STDOUT\"/>\n\t</logger>\n\n\t<!-- root级别 WARN -->\n\t<root level=\"WARN\">\n\t\t<!-- 控制台输出 -->\n\t\t<appender-ref ref=\"STDOUT\" />\n\t</root>\n\n</configuration>"
  },
  {
    "path": "chat_rest/src/main/resources/logback.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration scan=\"true\" scanPeriod=\"60 seconds\" debug=\"false\">\n\t<property name=\"log.home\" value=\"${PLATFORM_HOME:-}/logs\" />\n\n\t<appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n\t\t<!-- 对日志进行格式化 -->\n\t\t<encoder>\n\t\t\t<charset>UTF-8</charset>\n\t\t\t<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>\n\t\t</encoder>\n\t</appender>\n\n\t<appender name=\"ALL\" class=\"ch.qos.logback.core.rolling.RollingFileAppender\">\n\t\t<filter class=\"ch.qos.logback.classic.filter.ThresholdFilter\">\n\t\t\t<springProfile name=\"prod\">\n\t\t\t\t<level>INFO</level>\n\t\t\t</springProfile>\n\t\t\t<springProfile name=\"test,dev\">\n\t\t\t\t<level>DEBUG</level>\n\t\t\t</springProfile>\n\t\t</filter>\n\t\t<rollingPolicy class=\"ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy\">\n\t\t\t<!-- rollover daily -->\n\t\t\t<fileNamePattern>${log.home}/label_%d{yyyy-MM-dd}_%i.log</fileNamePattern>\n\t\t\t<!-- each file should be at most 100MB, keep 15 days worth of history, but at most 10GB -->\n\t\t\t<maxFileSize>100MB</maxFileSize>\n\t\t\t<maxHistory>7</maxHistory>\n\t\t\t<totalSizeCap>10GB</totalSizeCap>\n\t\t</rollingPolicy>\n\t\t<encoder>\n\t\t\t<charset>UTF-8</charset>\n\t\t\t<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n\t\t</encoder>\n\t</appender>\n\n\t<springProfile name=\"dev\">\n\t\t<logger name=\"com.am.chat.bi\" additivity=\"FALSE\" level=\"DEBUG\">\n\t\t\t<appender-ref ref=\"ALL\"/>\n\t\t</logger>\n\n\t\t<logger name=\"com.am.chat.bi\" additivity=\"FALSE\" level=\"INFO\">\n\t\t\t<appender-ref ref=\"ALL\"/>\n\t\t</logger>\n\t</springProfile>\n\n\t<springProfile name=\"test,press\">\n\t\t<logger name=\"com.am.chat.bi\" additivity=\"FALSE\" level=\"DEBUG\">\n\t\t\t<appender-ref ref=\"ALL\"/>\n\t\t</logger>\n\n\t\t<logger name=\"com.am.chat.bi\" additivity=\"FALSE\" level=\"INFO\">\n\t\t\t<appender-ref ref=\"ALL\"/>\n\t\t</logger>\n\t</springProfile>\n\n\t<springProfile name=\"prod\">\n\t\t<logger name=\"com.am.chat.bi\" additivity=\"FALSE\" level=\"INFO\">\n\t\t\t<appender-ref ref=\"ALL\"/>\n\t\t</logger>\n\t</springProfile>\n\n\t<!-- root级别 WARN -->\n\t<root level=\"WARN\">\n\t\t<appender-ref ref=\"ALL\" />\n\t</root>\n\n</configuration>"
  },
  {
    "path": "chat_rest/src/main/resources/press/setenv.sh",
    "content": "#!/bin/sh\nPRG=\"$0\"\nPRGDIR=`dirname \"$PRG\"`\nBASE_HOME=`cd \"$PRGDIR/..\" >/dev/null; pwd`\n\n#server内存配置\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -server -Xms4G -Xmx4G -Xmn2G -XX:PermSize=256M -XX:MaxPermSize=512M -Xss1M -XX:SurvivorRatio=8\"\n\n#gc\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -XX:MaxTenuringThreshold=4 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=2 -XX:+ExplicitGCInvokesConcurrent  -XX:+CMSScavengeBeforeRemark\"\n\n#gc日志\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -Xloggc:$BASE_HOME/logs/jvm/gc.log.`date +%Y-%m-%d_%H_%M_%S` \\\n -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:PrintFLSStatistics=1\"\n\n#内存溢出\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$BASE_HOME/logs/heapdump.hprof\"\n"
  },
  {
    "path": "chat_rest/src/main/resources/prod/setenv.sh",
    "content": "#!/bin/sh\nPRG=\"$0\"\nPRGDIR=`dirname \"$PRG\"`\nBASE_HOME=`cd \"$PRGDIR/..\" >/dev/null; pwd`\n\n#server内存配置\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS  -server -Xms4G -Xmx4G -Xmn2G -XX:PermSize=256M -XX:MaxPermSize=512M -Xss1M -XX:SurvivorRatio=8\"\n\n#gc\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -XX:MaxTenuringThreshold=4 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=2 -XX:+ExplicitGCInvokesConcurrent  -XX:+CMSScavengeBeforeRemark\"\n\n#gc日志\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -Xloggc:$BASE_HOME/logs/jvm/gc.log.`date +%Y-%m-%d_%H_%M_%S` \\\n -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:PrintFLSStatistics=1\"\n\n#内存溢出\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$BASE_HOME/logs/heapdump.hprof\"\n"
  },
  {
    "path": "chat_rest/src/main/resources/sql/mysql.sql",
    "content": "USE chat_bi;\nDROP TABLE IF EXISTS `scheam_meta_info`;\nCREATE TABLE `scheam_meta_info` (\n  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',\n  `meta_name` varchar(64) NOT NULL COMMENT '维度，指标名称',\n  `meta_zh_name` varchar(128) NOT NULL COMMENT '维度，指标中文名称',\n  `meta_type` int(1) NOT NULL DEFAULT '1' COMMENT '维度1，指标2',\n  `meta_expression` varchar(128) DEFAULT NULL COMMENT '维度，指标表达式',\n  `meta_table_name` varchar(64) DEFAULT NULL COMMENT '维度，指标来源表名称',\n  `meta_state` int(1) NOT NULL DEFAULT '0' COMMENT '操作类型，0:新增，1:更新，2:删除',\n  `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',\n  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='维度指标元数据信息表';\n"
  },
  {
    "path": "chat_rest/src/main/resources/test/setenv.sh",
    "content": "#!/bin/sh\nPRG=\"$0\"\nPRGDIR=`dirname \"$PRG\"`\nBASE_HOME=`cd \"$PRGDIR/..\" >/dev/null; pwd`\n\n#server内存配置\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -d64 -server -Xms4G -Xmx4G -Xmn2G -XX:PermSize=256M -XX:MaxPermSize=512M -Xss1M -XX:SurvivorRatio=8\"\n\n#gc\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -XX:MaxTenuringThreshold=4 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=2 -XX:+ExplicitGCInvokesConcurrent  -XX:+CMSScavengeBeforeRemark\"\n\n#gc日志\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -Xloggc:$BASE_HOME/logs/jvm/gc.log.`date +%Y-%m-%d_%H_%M_%S` \\\n -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:PrintFLSStatistics=1\"\n\n#内存溢出\nexport JAVA_MEM_OPTS=\"$JAVA_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$BASE_HOME/logs/heapdump.hprof\"\n"
  },
  {
    "path": "chat_rest/src/main/shell/comm.sh",
    "content": "#!/bin/sh\n\n# resolve links - $0 may be a softlink\nPRG=\"$0\"\n\nwhile [ -h \"$PRG\" ]; do\n  ls=`ls -ld \"$PRG\"`\n  link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n  if expr \"$link\" : '/.*' > /dev/null; then\n    PRG=\"$link\"\n  else\n    PRG=`dirname \"$PRG\"`/\"$link\"\n  fi\ndone\n\nCOMMAND=\"$1\"\n\n# Get standard environment variables\nPRG_DIR=`dirname \"$PRG\"`\nPLATFORM_HOME=`cd \"$PRG_DIR/..\" >/dev/null; pwd`\nexport PLATFORM_HOME\n\nPLATFORM_CONF_DIR=\"$PLATFORM_HOME/config\"\nPLATFORM_LIB_DIR=\"$PLATFORM_HOME/lib\"\nexport PLATFORM_LIB_DIR\n\nLIB_JARS=`ls $PLATFORM_LIB_DIR | grep -E '.jar$' | awk '{print \"'$PLATFORM_LIB_DIR'/\"$0}' | tr \"\\n\" \":\"`\n\nPRO_NAME=${project.artifactId}\nPIDFILE=\"$PLATFORM_HOME/$(basename $PRO_NAME).pid\"\nPID=0\nif [[ -f $PIDFILE ]]; then\n  PID=`cat $PIDFILE`\nfi\n\nJAVA_OPTS=\"\"\nJAVA_MEM_OPTS=\"\"\nJAVA_SPRING_OPTS=\" --spring.profiles.active=${env}\"\n\nPLATFORM_MAIN_CLASS=${start-class}\n\n\nrunning() {\n  if [[ -z $1 || $1 == 0 ]]; then\n    echo 0\n    return\n  fi\n  if ps -p $1 > /dev/null; then\n    echo 1\n    return\n  fi\n  echo 0\n  return\n}\n\nset_env() {\n    if [ -r \"$PLATFORM_HOME/bin/setenv.sh\" ]; then\n      source \"$PLATFORM_HOME/bin/setenv.sh\"\n    else\n      JAVA_MEM_OPTS=\" -server -Xms4g -Xmx4g -XX:SurvivorRatio=2 -XX:+UseParallelGC \"\n    fi\n}\n\nstart() {\n  if [[ $(running $PID) != 0 ]]; then\n    echo \"$PRO_NAME is running\"\n    return\n  fi\n  echo \"### starting $PRO_NAME `date '+%Y-%m-%d %H:%M:%S'` ###\" >> /dev/null 2>&1 &\n  set_env\n  echo \"$JAVA_HOME/bin/java $JAVA_OPTS $JAVA_MEM_OPTS -classpath $PLATFORM_CONF_DIR:$LIB_JARS $PLATFORM_MAIN_CLASS $JAVA_SPRING_OPTS\"\n  START_CMD=\"$JAVA_HOME/bin/java $JAVA_OPTS $JAVA_MEM_OPTS -classpath $PLATFORM_CONF_DIR:$LIB_JARS $PLATFORM_MAIN_CLASS $JAVA_SPRING_OPTS\"\n  print_env\n  nohup $START_CMD >> $PLATFORM_HOME/server.log 2>&1 &\n  if [[ $(running $!) == 0 ]]; then\n    echo \"failed to start $PRO_NAME\"\n    exit 1\n  fi\n  PID=$!\n  echo $! > $PIDFILE\n#  echo \"new pid $!\"\n}\n\nstop() {\n  if [[ $(running $PID) == 0 ]]; then\n    echo \"no $PRO_NAME is running\"\n    return\n  fi\n  echo \"stopping $PID of $PRO_NAME ...\"\n  kill $PID\n}\n\nrestart() {\n  stop\n  start\n}\n\nprint_env() {\n  echo \"JRE_HOME:               $JAVA_HOME\"\n  echo \"ENV:                    ${env}\"\n  echo \"JAVA_OPTS:              $JAVA_OPTS\"\n  echo \"JAVA_MEM_OPTS:          $JAVA_MEM_OPTS\"\n  echo \"JAVA_SPRING_OPTS:       $JAVA_SPRING_OPTS\"\n  echo \"START_CMD:              $START_CMD\"\n}\n\nprint_usage() {\n  echo \"Usage: label.sh (start|stop)\"\n}\n\ncase $COMMAND in\n\n(start)\n  start\n  ;;\n\n(stop)\n  stop\n  ;;\n\n(*)\n  print_usage\n  exit 1\n  ;;\nesac"
  },
  {
    "path": "chat_rest/src/main/shell/start.sh",
    "content": "#!/bin/sh\nPRG=\"$0\"\nPRGDIR=`dirname \"$PRG\"`\nPLATFORM_HOME=`cd \"$PRGDIR/..\" >/dev/null; pwd`\nEXECUTABLE=comm.sh\nexec \"$PRGDIR\"/\"$EXECUTABLE\" start \"$@\"\n"
  },
  {
    "path": "chat_rest/src/main/shell/stop.sh",
    "content": "#!/bin/sh\nPRG=\"$0\"\nPRGDIR=`dirname \"$PRG\"`\nPLATFORM_HOME=`cd \"$PRGDIR/..\" >/dev/null; pwd`\nEXECUTABLE=comm.sh\nexec \"$PRGDIR\"/\"$EXECUTABLE\" stop \"$@\"\n"
  },
  {
    "path": "chat_ui/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>chatBI</artifactId>\n        <groupId>com.am</groupId>\n        <version>1.0-SNAPSHOT</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>chat_ui</artifactId>\n\n\n</project>"
  },
  {
    "path": "plugins/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>chatBI</artifactId>\n        <groupId>com.am</groupId>\n        <version>1.0-SNAPSHOT</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>plugins</artifactId>\n\n    <name>plugins</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>com.google.code.gson</groupId>\n            <artifactId>gson</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>com.alibaba</groupId>\n            <artifactId>dashscope-sdk-java</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-core</artifactId>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "plugins/src/main/java/com/am/chat/bi/utils/AliLLMsUtil.java",
    "content": "package com.am.chat.bi.utils;\n\n\nimport com.alibaba.dashscope.aigc.generation.Generation;\nimport com.alibaba.dashscope.aigc.generation.GenerationResult;\nimport com.alibaba.dashscope.aigc.generation.models.QwenParam;\nimport com.alibaba.dashscope.common.ResultCallback;\nimport com.alibaba.dashscope.utils.Constants;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.concurrent.Semaphore;\n\n\npublic class AliLLMsUtil {\n    private static final Logger LOG = LoggerFactory.getLogger(AliLLMsUtil.class);\n\n    static {\n        Constants.apiKey = \"sk-547\";\n    }\n\n    public static String getResult(String prompt) throws Exception {\n        Generation gen = new Generation();\n        QwenParam param = QwenParam.builder().model(Generation.Models.QWEN_TURBO).prompt(prompt)\n                .topP(0.8).build();\n        Semaphore semaphore = new Semaphore(0);\n\n        final String[] result = {null};\n        gen.call(param, new ResultCallback<GenerationResult>() {\n\n            @Override\n            public void onEvent(GenerationResult message) {\n                System.out.println(message);\n\n                result[0] = message.getOutput().getText();\n                LOG.info(\"阿里大模型返回结果：{}\",message);\n            }\n            @Override\n            public void onError(Exception ex){\n                System.out.println(ex.getMessage());\n                semaphore.release();\n            }\n            @Override\n            public void onComplete(){\n                System.out.println(\"onComplete\");\n                semaphore.release();\n            }\n\n        });\n        semaphore.acquire();\n\n        return result[0];\n    }\n}\n"
  },
  {
    "path": "plugins/src/main/java/com/am/chat/bi/utils/LLMsResultUtil.java",
    "content": "package com.am.chat.bi.utils;\n\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class LLMsResultUtil {\n\n    public static String getIntentionResult(String result){\n        String intentionResult = null;\n\n        Pattern pattern = Pattern.compile(\"(\\\\d+)\");\n        Matcher matcher = pattern.matcher(result);\n        if (matcher.find()) {\n            intentionResult = matcher.group();\n        }\n\n        return intentionResult;\n    }\n\n    public static JsonElement getJsonValue(String result, String name) {\n        JsonParser parser = new JsonParser();\n        JsonObject jsonObject = parser.parse(result).getAsJsonObject();\n        return jsonObject.get(name);\n    }\n\n    public static String getDimMetricJson(String result){\n        String sqlResult = null;\n//        Pattern pattern = Pattern.compile(\"```json(.*?)```\");\n        Pattern pattern = Pattern.compile(\"\\\\{.*\\\\}\");\n        Matcher matcher = pattern.matcher(result);\n        if (matcher.find()) {\n            sqlResult = matcher.group();\n        }\n\n        return sqlResult;\n    }\n\n    public static String getSqlResult(String result){\n        String sqlResult = null;\n\n        Pattern pattern = Pattern.compile(\"querySql: \\\"(.*?)\\\"}\");\n        Matcher matcher = pattern.matcher(result);\n        if (matcher.find()) {\n            sqlResult = matcher.group();\n        }\n\n        return sqlResult;\n    }\n\n\n}\n"
  },
  {
    "path": "plugins/src/main/java/com/am/chat/bi/utils/PromptUtil.java",
    "content": "package com.am.chat.bi.utils;\n\npublic class PromptUtil {\n\n    /**\n     * 查询意图\n     * @param queryContent\n     * @return\n     */\n    public static String getIntentionPrompt(String queryContent) {\n        String intentionPrompt = \"“\" + queryContent + \"” 请帮忙判断这句话的意图是需要\" +\n                \"知识库还是数据查询。如果意图是知识库的话result返回值是1，是数据查询的话result返回值是2。\" +\n                \"最后返回值采用json数据格式，返回值格式为{result:result_$返回值}\"\n                ;\n\n        return intentionPrompt;\n\n    }\n\n    public static String getDimensionMetricPrompt(String queryContent) {\n        String dimMetricPrompt = \"“\" + queryContent + \"” 请帮忙解析这句话中含有的维度与指标。解析要求：\" +\n                \"1，语句中除了指标名词外，默认其他名词为维度。\" +\n                \"2，最后的返回结果采用json数据格式，指定返回格式为{dimensions:array[$维度名称]，metrics:array[$指标名称]}。\";\n\n        return dimMetricPrompt;\n    }\n\n    public static String getSqlPrompt(String queryContent, String dbType, String schemaInfo, String dbDialect) {\n        String sqlPrompt = \"假设你是\"+dbType+\"的专家，需要通过问题描述和指令语句两部分内容帮忙生成对应查询SQL语句。第一部分问题说明：\\n\" +\n                \"“\" + queryContent + \"” \\n\" +\n                \"第二部分指令内容：\\n\" +\n                \"1，不能幻觉出现新的字段，schema字段、表名称、表字段名称必须使用提供的元数据内容信息，元数据信息json格式数据 \" + schemaInfo + \" \\n\" +\n                \"2，可能需要关联表的查询SQL才满足问题内容的要求，关联的表和表字段一定存在已经提供的元数据内容。\\n\" +\n                \"3，生产的sql语句使用json格式返回，返回数据格式要求{querySQL: $生成的结果SQL}。\";\n\n        return sqlPrompt;\n    }\n\n}\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>com.am</groupId>\n    <artifactId>chatBI</artifactId>\n    <packaging>pom</packaging>\n    <version>1.0-SNAPSHOT</version>\n\n    <modules>\n        <module>chat_rest</module>\n        <module>chat_ui</module>\n        <module>plugins</module>\n    </modules>\n\n    <properties>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <maven.compiler.source>8</maven.compiler.source>\n        <maven.compiler.target>8</maven.compiler.target>\n        <spring-boot-starter-parent>1.5.9.RELEASE</spring-boot-starter-parent>\n        <spring-content.version>4.3.13.RELEASE</spring-content.version>\n        <mybatis-spring-boot-starter>1.3.2</mybatis-spring-boot-starter>\n        <druid>1.1.10</druid>\n        <pagehelper>1.1.1</pagehelper>\n        <commons-lang3>3.7</commons-lang3>\n        <fastjson>1.2.47</fastjson>\n        <swagger.version>2.7.0</swagger.version>\n        <logback.version>1.2.3</logback.version>\n        <lombok.version>1.18.0</lombok.version>\n        <redis.version>2.7.2</redis.version>\n        <mysql.version>5.1.46</mysql.version>\n    </properties>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-starter</artifactId>\n                <version>${spring-boot-starter-parent}</version>\n                <exclusions>\n                    <exclusion>\n                        <artifactId>logback-classic</artifactId>\n                        <groupId>ch.qos.logback</groupId>\n                    </exclusion>\n                </exclusions>\n            </dependency>\n            <dependency>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-starter-web</artifactId>\n                <version>${spring-boot-starter-parent}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>org.springframework</groupId>\n                <artifactId>spring-context-support</artifactId>\n                <version>${spring-content.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-starter-websocket</artifactId>\n                <version>${spring-boot-starter-parent}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-configuration-processor</artifactId>\n                <version>${spring-boot-starter-parent}</version>\n                <optional>true</optional>\n            </dependency>\n\n            <dependency>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-starter-test</artifactId>\n                <version>${spring-boot-starter-parent}</version>\n                <scope>test</scope>\n            </dependency>\n\n            <dependency>\n                <groupId>io.springfox</groupId>\n                <artifactId>springfox-swagger2</artifactId>\n                <version>${swagger.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>io.springfox</groupId>\n                <artifactId>springfox-swagger-ui</artifactId>\n                <version>${swagger.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>com.github.pagehelper</groupId>\n                <artifactId>pagehelper-spring-boot-starter</artifactId>\n                <version>${pagehelper}</version>\n                <exclusions>\n                    <exclusion>\n                        <artifactId>mybatis-spring-boot-starter</artifactId>\n                        <groupId>org.mybatis.spring.boot</groupId>\n                    </exclusion>\n                </exclusions>\n            </dependency>\n            <!-- db -->\n            <dependency>\n                <groupId>org.mybatis.spring.boot</groupId>\n                <artifactId>mybatis-spring-boot-starter</artifactId>\n                <version>${mybatis-spring-boot-starter}</version>\n                <exclusions>\n                    <exclusion>\n                        <groupId>org.springframework.boot</groupId>\n                        <artifactId>spring-boot-starter</artifactId>\n                    </exclusion>\n                </exclusions>\n            </dependency>\n\n            <dependency>\n                <groupId>com.alibaba</groupId>\n                <artifactId>druid-spring-boot-starter</artifactId>\n                <version>${druid}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>mysql</groupId>\n                <artifactId>mysql-connector-java</artifactId>\n                <version>${mysql.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>org.mybatis.spring.boot</groupId>\n                <artifactId>mybatis-spring-boot-starter-test</artifactId>\n                <version>${mybatis-spring-boot-starter}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>org.projectlombok</groupId>\n                <artifactId>lombok</artifactId>\n                <version>${lombok.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>org.apache.commons</groupId>\n                <artifactId>commons-lang3</artifactId>\n                <version>${commons-lang3}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>ch.qos.logback</groupId>\n                <artifactId>logback-classic</artifactId>\n                <version>${logback.version}</version>\n                <exclusions>\n                    <exclusion>\n                        <artifactId>logback-core</artifactId>\n                        <groupId>ch.qos.logback</groupId>\n                    </exclusion>\n                </exclusions>\n            </dependency>\n            <dependency>\n                <groupId>ch.qos.logback</groupId>\n                <artifactId>logback-core</artifactId>\n                <version>${logback.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>com.google.code.gson</groupId>\n                <artifactId>gson</artifactId>\n                <version>2.10.1</version>\n            </dependency>\n\n            <dependency>\n                <groupId>com.alibaba</groupId>\n                <artifactId>dashscope-sdk-java</artifactId>\n                <version>2.6.1</version>\n            </dependency>\n\n            <dependency>\n                <groupId>redis.clients</groupId>\n                <artifactId>jedis</artifactId>\n                <version>${redis.version}</version>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n\n</project>"
  }
]