合并扩展插件到主工程
58
extensions/.gitignore
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
#*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
/.idea/
|
||||
target/
|
||||
*.iml
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
node/
|
||||
static/
|
||||
# local env files
|
||||
.env.demo
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
*.lock
|
||||
*.classpath
|
||||
*.project
|
||||
*.factorypath
|
||||
.settings/
|
||||
.lh
|
||||
|
||||
|
||||
package-lock.json
|
19
extensions/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# DateEase 官方插件
|
||||
|
||||
此仓库用于放置 DataEase 官方插件,插件分为两种类型:数据源插件和视图插件。
|
||||
|
||||
当前以插件方式支持的数据源包括:
|
||||
|
||||
- 达梦数据库
|
||||
- Apache Kylin
|
||||
- 阿里云 MaxCompute
|
||||
- MongoDB
|
||||
- Presto
|
||||
|
||||
当前已插件方式支持的视图包括:
|
||||
|
||||
- 3dpie
|
||||
- bubblemap
|
||||
- symbolmap
|
||||
|
||||
更多插件持续开发中,敬请期待。
|
35
extensions/dataease-extensions-datasource/dm/.gitignore
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
.DS_Store
|
||||
node_modules
|
||||
node/
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.iml
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
|
||||
src/main/resources/static
|
||||
src/main/resources/templates
|
||||
src/test/
|
||||
target
|
||||
.settings
|
||||
.project
|
||||
.classpath
|
||||
.factorypath
|
||||
src/main/resources/jmeter/lib/
|
6
extensions/dataease-extensions-datasource/dm/build.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
mvn clean package -U -Dmaven.test.skip=true
|
||||
|
||||
cp dm-backend/target/dm-backend-1.18.0.jar .
|
||||
|
||||
zip -r dm.zip ./dm-backend-1.18.0.jar ./dmDriver ./plugin.json
|
109
extensions/dataease-extensions-datasource/dm/dm-backend/pom.xml
Normal file
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>dm</artifactId>
|
||||
<groupId>io.dataease</groupId>
|
||||
<version>${dataease.version}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>dm-backend</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>dataease-plugin-datasource</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/server/**</exclude>
|
||||
<exclude>**/*.properties</exclude>
|
||||
<exclude>**/Application*</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>src/main/resources/static</directory>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
<followSymlinks>false</followSymlinks>
|
||||
</fileset>
|
||||
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>main-class-placement</id>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<target>
|
||||
<move todir="src/main/resources/static">
|
||||
<fileset dir="../dm-frontend/static">
|
||||
<include name="*.*"/>
|
||||
</fileset>
|
||||
</move>
|
||||
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
@ -0,0 +1,21 @@
|
||||
package io.dataease.plugins.datasource.dm.provider;
|
||||
|
||||
import io.dataease.plugins.datasource.entity.JdbcConfiguration;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class DmConfig extends JdbcConfiguration {
|
||||
|
||||
private String driver = "dm.jdbc.driver.DmDriver";
|
||||
private String extraParams;
|
||||
|
||||
|
||||
public String getJdbc() {
|
||||
return "jdbc:dm://HOST:PORT/DATABASE"
|
||||
.replace("HOST", getHost().trim())
|
||||
.replace("PORT", getPort().toString())
|
||||
.replace("DATABASE", getDataBase().trim());
|
||||
}
|
||||
}
|
@ -0,0 +1,226 @@
|
||||
package io.dataease.plugins.datasource.dm.provider;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.plugins.common.base.domain.DeDriver;
|
||||
import io.dataease.plugins.common.base.mapper.DeDriverMapper;
|
||||
import io.dataease.plugins.common.constants.DatasourceTypes;
|
||||
import io.dataease.plugins.common.dto.datasource.TableDesc;
|
||||
import io.dataease.plugins.common.dto.datasource.TableField;
|
||||
import io.dataease.plugins.common.exception.DataEaseException;
|
||||
import io.dataease.plugins.common.request.datasource.DatasourceRequest;
|
||||
import io.dataease.plugins.datasource.entity.JdbcConfiguration;
|
||||
import io.dataease.plugins.datasource.provider.DefaultJdbcProvider;
|
||||
import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
@Component()
|
||||
public class DmDsProvider extends DefaultJdbcProvider {
|
||||
@Resource
|
||||
private DeDriverMapper deDriverMapper;
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "dm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseDatasourcePool() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(DatasourceRequest datasourceRequest) throws Exception {
|
||||
DmConfig dmConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), DmConfig.class);
|
||||
|
||||
String defaultDriver = dmConfig.getDriver();
|
||||
String customDriver = dmConfig.getCustomDriver();
|
||||
|
||||
String url = dmConfig.getJdbc();
|
||||
Properties props = new Properties();
|
||||
DeDriver deDriver = null;
|
||||
if (StringUtils.isNotEmpty(dmConfig.getAuthMethod()) && dmConfig.getAuthMethod().equalsIgnoreCase("kerberos")) {
|
||||
System.setProperty("java.security.krb5.conf", "/opt/dataease/conf/krb5.conf");
|
||||
ExtendedJdbcClassLoader classLoader;
|
||||
if (isDefaultClassLoader(customDriver)) {
|
||||
classLoader = extendedJdbcClassLoader;
|
||||
} else {
|
||||
deDriver = deDriverMapper.selectByPrimaryKey(customDriver);
|
||||
classLoader = getCustomJdbcClassLoader(deDriver);
|
||||
}
|
||||
Class<?> ConfigurationClass = classLoader.loadClass("org.apache.hadoop.conf.Configuration");
|
||||
Method set = ConfigurationClass.getMethod("set", String.class, String.class);
|
||||
Object obj = ConfigurationClass.newInstance();
|
||||
set.invoke(obj, "hadoop.security.authentication", "Kerberos");
|
||||
|
||||
Class<?> UserGroupInformationClass = classLoader.loadClass("org.apache.hadoop.security.UserGroupInformation");
|
||||
Method setConfiguration = UserGroupInformationClass.getMethod("setConfiguration", ConfigurationClass);
|
||||
Method loginUserFromKeytab = UserGroupInformationClass.getMethod("loginUserFromKeytab", String.class, String.class);
|
||||
setConfiguration.invoke(null, obj);
|
||||
loginUserFromKeytab.invoke(null, dmConfig.getUsername(), "/opt/dataease/conf/" + dmConfig.getPassword());
|
||||
} else {
|
||||
if (StringUtils.isNotBlank(dmConfig.getUsername())) {
|
||||
props.setProperty("user", dmConfig.getUsername());
|
||||
if (StringUtils.isNotBlank(dmConfig.getPassword())) {
|
||||
props.setProperty("password", dmConfig.getPassword());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connection conn;
|
||||
String driverClassName;
|
||||
ExtendedJdbcClassLoader jdbcClassLoader;
|
||||
if (isDefaultClassLoader(customDriver)) {
|
||||
driverClassName = defaultDriver;
|
||||
jdbcClassLoader = extendedJdbcClassLoader;
|
||||
} else {
|
||||
if (deDriver == null) {
|
||||
deDriver = deDriverMapper.selectByPrimaryKey(customDriver);
|
||||
}
|
||||
driverClassName = deDriver.getDriverClass();
|
||||
jdbcClassLoader = getCustomJdbcClassLoader(deDriver);
|
||||
}
|
||||
|
||||
Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance();
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(jdbcClassLoader);
|
||||
conn = driverClass.connect(url, props);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TableDesc> getTables(DatasourceRequest datasourceRequest) throws Exception {
|
||||
List<TableDesc> tables = new ArrayList<>();
|
||||
String queryStr = getTablesSql(datasourceRequest);
|
||||
JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class);
|
||||
int queryTimeout = jdbcConfiguration.getQueryTimeout() > 0 ? jdbcConfiguration.getQueryTimeout() : 0;
|
||||
try (Connection con = getConnectionFromPool(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) {
|
||||
while (resultSet.next()) {
|
||||
tables.add(getTableDesc(datasourceRequest, resultSet));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
DataEaseException.throwException(e);
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
private TableDesc getTableDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException {
|
||||
TableDesc tableDesc = new TableDesc();
|
||||
tableDesc.setName(resultSet.getString(1));
|
||||
return tableDesc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TableField> getTableFields(DatasourceRequest datasourceRequest) throws Exception {
|
||||
List<TableField> list = new LinkedList<>();
|
||||
try (Connection connection = getConnectionFromPool(datasourceRequest)) {
|
||||
DatabaseMetaData databaseMetaData = connection.getMetaData();
|
||||
ResultSet resultSet = databaseMetaData.getColumns(null, "%", datasourceRequest.getTable(), "%");
|
||||
while (resultSet.next()) {
|
||||
String tableName = resultSet.getString("TABLE_NAME");
|
||||
String database;
|
||||
database = resultSet.getString("TABLE_CAT");
|
||||
if (database != null) {
|
||||
if (tableName.equals(datasourceRequest.getTable()) && database.equalsIgnoreCase(getDatabase(datasourceRequest))) {
|
||||
TableField tableField = getTableFiled(resultSet, datasourceRequest);
|
||||
list.add(tableField);
|
||||
}
|
||||
} else {
|
||||
if (tableName.equals(datasourceRequest.getTable())) {
|
||||
TableField tableField = getTableFiled(resultSet, datasourceRequest);
|
||||
list.add(tableField);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultSet.close();
|
||||
} catch (SQLException e) {
|
||||
DataEaseException.throwException(e);
|
||||
} catch (Exception e) {
|
||||
DataEaseException.throwException("Data source connection exception: " + e.getMessage());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private String getDatabase(DatasourceRequest datasourceRequest) {
|
||||
JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class);
|
||||
return jdbcConfiguration.getDataBase();
|
||||
}
|
||||
|
||||
|
||||
private TableField getTableFiled(ResultSet resultSet, DatasourceRequest datasourceRequest) throws SQLException {
|
||||
TableField tableField = new TableField();
|
||||
String colName = resultSet.getString("COLUMN_NAME");
|
||||
tableField.setFieldName(colName);
|
||||
String remarks = resultSet.getString("REMARKS");
|
||||
if (remarks == null || remarks.equals("")) {
|
||||
remarks = colName;
|
||||
}
|
||||
tableField.setRemarks(remarks);
|
||||
String dbType = resultSet.getString("TYPE_NAME").toUpperCase();
|
||||
tableField.setFieldType(dbType);
|
||||
if (dbType.equalsIgnoreCase("LONG")) {
|
||||
tableField.setFieldSize(65533);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(dbType) && dbType.toLowerCase().contains("date") && tableField.getFieldSize() < 50) {
|
||||
tableField.setFieldSize(50);
|
||||
}
|
||||
|
||||
if (datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.hive.name()) && tableField.getFieldType().equalsIgnoreCase("BOOLEAN")) {
|
||||
tableField.setFieldSize(1);
|
||||
} else {
|
||||
String size = resultSet.getString("COLUMN_SIZE");
|
||||
if (size == null) {
|
||||
tableField.setFieldSize(1);
|
||||
} else {
|
||||
tableField.setFieldSize(Integer.valueOf(size));
|
||||
}
|
||||
}
|
||||
return tableField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String checkStatus(DatasourceRequest datasourceRequest) throws Exception {
|
||||
String queryStr = getTablesSql(datasourceRequest);
|
||||
JdbcConfiguration jdbcConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class);
|
||||
int queryTimeout = jdbcConfiguration.getQueryTimeout() > 0 ? jdbcConfiguration.getQueryTimeout() : 0;
|
||||
try (Connection con = getConnection(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
DataEaseException.throwException(e.getMessage());
|
||||
}
|
||||
return "Success";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTablesSql(DatasourceRequest datasourceRequest) throws Exception {
|
||||
DmConfig dmConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), DmConfig.class);
|
||||
if (StringUtils.isEmpty(dmConfig.getSchema())) {
|
||||
throw new Exception("Database schema is empty.");
|
||||
}
|
||||
return "select table_name from all_tab_comments where owner='OWNER' AND table_type = 'TABLE' ".replaceAll("OWNER", dmConfig.getSchema());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchemaSql(DatasourceRequest datasourceRequest) {
|
||||
return "select OBJECT_NAME from dba_objects where object_type='SCH'";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package io.dataease.plugins.datasource.dm.query;
|
||||
|
||||
|
||||
|
||||
import io.dataease.plugins.common.constants.datasource.SQLConstants;
|
||||
|
||||
import static io.dataease.plugins.common.constants.DatasourceTypes.oracle;
|
||||
|
||||
public class DmConstants extends SQLConstants {
|
||||
|
||||
public static final String KEYWORD_TABLE = oracle.getKeywordPrefix() + "%s" + oracle.getKeywordSuffix();
|
||||
|
||||
public static final String KEYWORD_FIX = "%s." + oracle.getKeywordPrefix() + "%s" + oracle.getKeywordSuffix();
|
||||
|
||||
public static final String ALIAS_FIX = oracle.getAliasPrefix() + "%s" + oracle.getAliasSuffix();
|
||||
|
||||
public static final String UNIX_TIMESTAMP = "UNIX_TIMESTAMP(%s)";
|
||||
|
||||
public static final String DATE_FORMAT = "to_timestamp(%s,'%s')";
|
||||
|
||||
public static final String FROM_UNIXTIME = "FROM_UNIXTIME(%s,'%s')";
|
||||
|
||||
public static final String CAST = "CAST(%s AS %s)";
|
||||
|
||||
public static final String DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH24:MI:SS";
|
||||
|
||||
public static final String DEFAULT_INT_FORMAT = "DECIMAL(20,0)";
|
||||
|
||||
public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(20,8)";
|
||||
|
||||
public static final String WHERE_VALUE_NULL = "(NULL,'')";
|
||||
|
||||
public static final String WHERE_VALUE_VALUE = "'%s'";
|
||||
|
||||
public static final String AGG_COUNT = "COUNT(*)";
|
||||
|
||||
public static final String AGG_FIELD = "%s(%s)";
|
||||
|
||||
public static final String WHERE_BETWEEN = "'%s' AND '%s'";
|
||||
|
||||
public static final String BRACKETS = "(%s)";
|
||||
|
||||
public static final String TO_NUMBER = "TO_NUMBER(%s)";
|
||||
|
||||
public static final String TO_DATE = "TO_DATE(%s,'%s')";
|
||||
|
||||
public static final String TO_CHAR = "TO_CHAR(%s,'%s')";
|
||||
|
||||
public static final String DEFAULT_START_DATE = "'1970-01-01 8:0:0'";
|
||||
|
||||
public static final String TO_MS = " * 24 * 60 * 60 * 100";
|
||||
|
||||
public static final String CALC_SUB = "%s - %s";
|
||||
|
||||
// public static final String GROUP_CONCAT = "vm_concat(%s)";
|
||||
public static final String GROUP_CONCAT = "to_char(listagg(%s,',' ) within GROUP (order by (%s)))";
|
||||
|
||||
public static final String NAME = "oracle";
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package io.dataease.plugins.datasource.dm.service;
|
||||
|
||||
import io.dataease.plugins.common.constants.DatabaseClassification;
|
||||
import io.dataease.plugins.common.constants.DatasourceCalculationMode;
|
||||
import io.dataease.plugins.common.dto.StaticResource;
|
||||
import io.dataease.plugins.common.dto.datasource.DataSourceType;
|
||||
import io.dataease.plugins.datasource.service.DatasourceService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class DmService extends DatasourceService {
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> components() {
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add("dm");
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
protected InputStream readContent(String s) {
|
||||
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/" + s);
|
||||
return resourceAsStream;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<StaticResource> staticResources() {
|
||||
List<StaticResource> results = new ArrayList<>();
|
||||
StaticResource staticResource = new StaticResource();
|
||||
staticResource.setName("dm");
|
||||
staticResource.setSuffix("jpg");
|
||||
results.add(staticResource);
|
||||
results.add(pluginSvg());
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceType getDataSourceType() {
|
||||
DataSourceType dataSourceType = new DataSourceType("dm", "DM" , true , "", DatasourceCalculationMode.DIRECT, true);
|
||||
dataSourceType.setKeywordPrefix("\"");
|
||||
dataSourceType.setKeywordSuffix("\"");
|
||||
dataSourceType.setAliasPrefix("\"");
|
||||
dataSourceType.setAliasSuffix("\"");
|
||||
dataSourceType.setDatabaseClassification(DatabaseClassification.OLTP);
|
||||
return dataSourceType;
|
||||
}
|
||||
|
||||
private StaticResource pluginSvg() {
|
||||
StaticResource staticResource = new StaticResource();
|
||||
staticResource.setName("dm-backend");
|
||||
staticResource.setSuffix("svg");
|
||||
return staticResource;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"modules": false,
|
||||
"targets": {
|
||||
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
|
||||
}
|
||||
}],
|
||||
"stage-2"
|
||||
],
|
||||
"plugins": ["transform-vue-jsx", "transform-runtime"]
|
||||
}
|
14
extensions/dataease-extensions-datasource/dm/dm-frontend/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
/dist/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
@ -0,0 +1,21 @@
|
||||
# deplugin-view-frontend
|
||||
|
||||
> A Vue.js project
|
||||
|
||||
## Build Setup
|
||||
|
||||
``` bash
|
||||
# install dependencies
|
||||
npm install
|
||||
|
||||
# serve with hot reload at localhost:8080
|
||||
npm run dev
|
||||
|
||||
# build for production with minification
|
||||
npm run build
|
||||
|
||||
# build for production and view the bundle analyzer report
|
||||
npm run build --report
|
||||
```
|
||||
|
||||
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
|
@ -0,0 +1,35 @@
|
||||
'use strict'
|
||||
require('./check-versions')()
|
||||
|
||||
process.env.NODE_ENV = 'production'
|
||||
|
||||
const ora = require('ora')
|
||||
const chalk = require('chalk')
|
||||
const webpack = require('webpack')
|
||||
const webpackConfig = require('./webpack.async-plugins')
|
||||
|
||||
const spinner = ora('building for sync-plugins...')
|
||||
spinner.start()
|
||||
|
||||
webpack(webpackConfig, function (err, stats) {
|
||||
spinner.stop()
|
||||
if (err) throw err
|
||||
process.stdout.write(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
}) + '\n\n')
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
console.log(chalk.red(' Build failed with errors.\n'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(chalk.cyan(' Build complete.\n'))
|
||||
console.log(chalk.yellow(
|
||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
||||
' Opening index.html over file:// won\'t work.\n'
|
||||
))
|
||||
})
|
@ -0,0 +1,41 @@
|
||||
'use strict'
|
||||
require('./check-versions')()
|
||||
|
||||
process.env.NODE_ENV = 'production'
|
||||
|
||||
const ora = require('ora')
|
||||
const rm = require('rimraf')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const webpackConfig = require('./webpack.prod.conf')
|
||||
|
||||
const spinner = ora('building for production...')
|
||||
spinner.start()
|
||||
|
||||
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
|
||||
if (err) throw err
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
spinner.stop()
|
||||
if (err) throw err
|
||||
process.stdout.write(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
}) + '\n\n')
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
console.log(chalk.red(' Build failed with errors.\n'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(chalk.cyan(' Build complete.\n'))
|
||||
console.log(chalk.yellow(
|
||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
||||
' Opening index.html over file:// won\'t work.\n'
|
||||
))
|
||||
})
|
||||
})
|
@ -0,0 +1,54 @@
|
||||
'use strict'
|
||||
const chalk = require('chalk')
|
||||
const semver = require('semver')
|
||||
const packageConfig = require('../package.json')
|
||||
const shell = require('shelljs')
|
||||
|
||||
function exec (cmd) {
|
||||
return require('child_process').execSync(cmd).toString().trim()
|
||||
}
|
||||
|
||||
const versionRequirements = [
|
||||
{
|
||||
name: 'node',
|
||||
currentVersion: semver.clean(process.version),
|
||||
versionRequirement: packageConfig.engines.node
|
||||
}
|
||||
]
|
||||
|
||||
if (shell.which('npm')) {
|
||||
versionRequirements.push({
|
||||
name: 'npm',
|
||||
currentVersion: exec('npm --version'),
|
||||
versionRequirement: packageConfig.engines.npm
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
const warnings = []
|
||||
|
||||
for (let i = 0; i < versionRequirements.length; i++) {
|
||||
const mod = versionRequirements[i]
|
||||
|
||||
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
|
||||
warnings.push(mod.name + ': ' +
|
||||
chalk.red(mod.currentVersion) + ' should be ' +
|
||||
chalk.green(mod.versionRequirement)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (warnings.length) {
|
||||
console.log('')
|
||||
console.log(chalk.yellow('To use this template, you must update following to modules:'))
|
||||
console.log()
|
||||
|
||||
for (let i = 0; i < warnings.length; i++) {
|
||||
const warning = warnings[i]
|
||||
console.log(' ' + warning)
|
||||
}
|
||||
|
||||
console.log()
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 6.7 KiB |
@ -0,0 +1,101 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const config = require('../config')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const packageConfig = require('../package.json')
|
||||
|
||||
exports.assetsPath = function (_path) {
|
||||
const assetsSubDirectory = process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsSubDirectory
|
||||
: config.dev.assetsSubDirectory
|
||||
|
||||
return path.posix.join(assetsSubDirectory, _path)
|
||||
}
|
||||
|
||||
exports.cssLoaders = function (options) {
|
||||
options = options || {}
|
||||
|
||||
const cssLoader = {
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
const postcssLoader = {
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
// generate loader string to be used with extract text plugin
|
||||
function generateLoaders (loader, loaderOptions) {
|
||||
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
|
||||
|
||||
if (loader) {
|
||||
loaders.push({
|
||||
loader: loader + '-loader',
|
||||
options: Object.assign({}, loaderOptions, {
|
||||
sourceMap: options.sourceMap
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Extract CSS when that option is specified
|
||||
// (which is the case during production build)
|
||||
if (options.extract) {
|
||||
return ExtractTextPlugin.extract({
|
||||
use: loaders,
|
||||
fallback: 'vue-style-loader'
|
||||
})
|
||||
} else {
|
||||
return ['vue-style-loader'].concat(loaders)
|
||||
}
|
||||
}
|
||||
|
||||
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
|
||||
return {
|
||||
css: generateLoaders(),
|
||||
postcss: generateLoaders(),
|
||||
less: generateLoaders('less'),
|
||||
sass: generateLoaders('sass', { indentedSyntax: true }),
|
||||
scss: generateLoaders('sass'),
|
||||
stylus: generateLoaders('stylus'),
|
||||
styl: generateLoaders('stylus')
|
||||
}
|
||||
}
|
||||
|
||||
// Generate loaders for standalone style files (outside of .vue)
|
||||
exports.styleLoaders = function (options) {
|
||||
const output = []
|
||||
const loaders = exports.cssLoaders(options)
|
||||
|
||||
for (const extension in loaders) {
|
||||
const loader = loaders[extension]
|
||||
output.push({
|
||||
test: new RegExp('\\.' + extension + '$'),
|
||||
use: loader
|
||||
})
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
exports.createNotifierCallback = () => {
|
||||
const notifier = require('node-notifier')
|
||||
|
||||
return (severity, errors) => {
|
||||
if (severity !== 'error') return
|
||||
|
||||
const error = errors[0]
|
||||
const filename = error.file && error.file.split('!').pop()
|
||||
|
||||
notifier.notify({
|
||||
title: packageConfig.name,
|
||||
message: severity + ': ' + error.name,
|
||||
subtitle: filename || '',
|
||||
icon: path.join(__dirname, 'logo.png')
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
const sourceMapEnabled = isProduction
|
||||
? config.build.productionSourceMap
|
||||
: config.dev.cssSourceMap
|
||||
|
||||
module.exports = {
|
||||
loaders: utils.cssLoaders({
|
||||
sourceMap: sourceMapEnabled,
|
||||
extract: isProduction
|
||||
}),
|
||||
cssSourceMap: sourceMapEnabled,
|
||||
cacheBusting: config.dev.cacheBusting,
|
||||
transformToRequire: {
|
||||
video: ['src', 'poster'],
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: 'xlink:href'
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
const webpack = require('webpack')
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '..', dir)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
entry: {
|
||||
'dm': resolve('/src/views/dm.vue')
|
||||
},
|
||||
output: {
|
||||
path: resolve('/static/'),
|
||||
filename: '[name].js'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js',
|
||||
'@': resolve('src')
|
||||
}
|
||||
},
|
||||
externals: {
|
||||
vue: 'vue'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
transformAssetUrls: {
|
||||
video: 'src',
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: 'xlink:href'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /.(sa|sc|c)ss$/,
|
||||
use: [
|
||||
{loader: 'vue-style-loader'},
|
||||
'css-loader',
|
||||
'sass-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
include: [resolve('src'), resolve('test')]
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('img/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('media/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': '"production"'
|
||||
}),
|
||||
new CopyPlugin([
|
||||
{from: 'src/icons/svg/'}
|
||||
]),
|
||||
]
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const vueLoaderConfig = require('./vue-loader.conf')
|
||||
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '..', dir)
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
context: path.resolve(__dirname, '../'),
|
||||
entry: {
|
||||
app: './src/main.js'
|
||||
},
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: '[name].js',
|
||||
publicPath: process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsPublicPath
|
||||
: config.dev.assetsPublicPath
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js',
|
||||
'@': resolve('src'),
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderConfig
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
loader: 'svg-sprite-loader',
|
||||
include: [resolve('src/icons')],
|
||||
options: {
|
||||
symbolId: 'icon-[name]'
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
exclude: [resolve('src/icons')],
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('img/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('media/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
include: [path.resolve('src/icons')],
|
||||
use: [
|
||||
{
|
||||
loader: 'svg-sprite-loader',
|
||||
options: {
|
||||
symbolId: 'icon-[name]',
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
node: {
|
||||
// prevent webpack from injecting useless setImmediate polyfill because Vue
|
||||
// source contains it (although only uses it if it's native).
|
||||
setImmediate: false,
|
||||
// prevent webpack from injecting mocks to Node native modules
|
||||
// that does not make sense for the client
|
||||
dgram: 'empty',
|
||||
fs: 'empty',
|
||||
net: 'empty',
|
||||
tls: 'empty',
|
||||
child_process: 'empty'
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const path = require('path')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||
const portfinder = require('portfinder')
|
||||
|
||||
const HOST = process.env.HOST
|
||||
const PORT = process.env.PORT && Number(process.env.PORT)
|
||||
|
||||
const devWebpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
|
||||
},
|
||||
// cheap-module-eval-source-map is faster for development
|
||||
devtool: config.dev.devtool,
|
||||
|
||||
// these devServer options should be customized in /config/index.js
|
||||
devServer: {
|
||||
clientLogLevel: 'warning',
|
||||
historyApiFallback: {
|
||||
rewrites: [
|
||||
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
|
||||
],
|
||||
},
|
||||
hot: true,
|
||||
contentBase: false, // since we use CopyWebpackPlugin.
|
||||
compress: true,
|
||||
host: HOST || config.dev.host,
|
||||
port: PORT || config.dev.port,
|
||||
open: config.dev.autoOpenBrowser,
|
||||
overlay: config.dev.errorOverlay
|
||||
? { warnings: false, errors: true }
|
||||
: false,
|
||||
publicPath: config.dev.assetsPublicPath,
|
||||
proxy: config.dev.proxyTable,
|
||||
quiet: true, // necessary for FriendlyErrorsPlugin
|
||||
watchOptions: {
|
||||
poll: config.dev.poll,
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': require('../config/dev.env')
|
||||
}),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
// https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: 'index.html',
|
||||
template: 'index.html',
|
||||
inject: true
|
||||
}),
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.dev.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
module.exports = new Promise((resolve, reject) => {
|
||||
portfinder.basePort = process.env.PORT || config.dev.port
|
||||
portfinder.getPort((err, port) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
// publish the new Port, necessary for e2e tests
|
||||
process.env.PORT = port
|
||||
// add port to devServer config
|
||||
devWebpackConfig.devServer.port = port
|
||||
|
||||
// Add FriendlyErrorsPlugin
|
||||
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
|
||||
compilationSuccessInfo: {
|
||||
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
|
||||
},
|
||||
onErrors: config.dev.notifyOnErrors
|
||||
? utils.createNotifierCallback()
|
||||
: undefined
|
||||
}))
|
||||
|
||||
resolve(devWebpackConfig)
|
||||
}
|
||||
})
|
||||
})
|
@ -0,0 +1,145 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
|
||||
const env = require('../config/prod.env')
|
||||
|
||||
const webpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
extract: true,
|
||||
usePostCSS: true
|
||||
})
|
||||
},
|
||||
devtool: config.build.productionSourceMap ? config.build.devtool : false,
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: utils.assetsPath('js/[name].[chunkhash].js'),
|
||||
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
|
||||
},
|
||||
plugins: [
|
||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': env
|
||||
}),
|
||||
new UglifyJsPlugin({
|
||||
uglifyOptions: {
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
},
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
parallel: true
|
||||
}),
|
||||
// extract css into its own file
|
||||
new ExtractTextPlugin({
|
||||
filename: utils.assetsPath('css/[name].[contenthash].css'),
|
||||
// Setting the following option to `false` will not extract CSS from codesplit chunks.
|
||||
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
|
||||
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
|
||||
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
|
||||
allChunks: true,
|
||||
}),
|
||||
// Compress extracted CSS. We are using this plugin so that possible
|
||||
// duplicated CSS from different components can be deduped.
|
||||
new OptimizeCSSPlugin({
|
||||
cssProcessorOptions: config.build.productionSourceMap
|
||||
? { safe: true, map: { inline: false } }
|
||||
: { safe: true }
|
||||
}),
|
||||
// generate dist index.html with correct asset hash for caching.
|
||||
// you can customize output by editing /index.html
|
||||
// see https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: config.build.index,
|
||||
template: 'index.html',
|
||||
inject: true,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
collapseWhitespace: true,
|
||||
removeAttributeQuotes: true
|
||||
// more options:
|
||||
// https://github.com/kangax/html-minifier#options-quick-reference
|
||||
},
|
||||
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
|
||||
chunksSortMode: 'dependency'
|
||||
}),
|
||||
// keep module.id stable when vendor modules does not change
|
||||
new webpack.HashedModuleIdsPlugin(),
|
||||
// enable scope hoisting
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
// split vendor js into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'vendor',
|
||||
minChunks (module) {
|
||||
// any required modules inside node_modules are extracted to vendor
|
||||
return (
|
||||
module.resource &&
|
||||
/\.js$/.test(module.resource) &&
|
||||
module.resource.indexOf(
|
||||
path.join(__dirname, '../node_modules')
|
||||
) === 0
|
||||
)
|
||||
}
|
||||
}),
|
||||
// extract webpack runtime and module manifest to its own file in order to
|
||||
// prevent vendor hash from being updated whenever app bundle is updated
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'manifest',
|
||||
minChunks: Infinity
|
||||
}),
|
||||
// This instance extracts shared chunks from code split chunks and bundles them
|
||||
// in a separate chunk, similar to the vendor chunk
|
||||
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'app',
|
||||
async: 'vendor-async',
|
||||
children: true,
|
||||
minChunks: 3
|
||||
}),
|
||||
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.build.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
if (config.build.productionGzip) {
|
||||
const CompressionWebpackPlugin = require('compression-webpack-plugin')
|
||||
|
||||
webpackConfig.plugins.push(
|
||||
new CompressionWebpackPlugin({
|
||||
asset: '[path].gz[query]',
|
||||
algorithm: 'gzip',
|
||||
test: new RegExp(
|
||||
'\\.(' +
|
||||
config.build.productionGzipExtensions.join('|') +
|
||||
')$'
|
||||
),
|
||||
threshold: 10240,
|
||||
minRatio: 0.8
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (config.build.bundleAnalyzerReport) {
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
||||
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
|
||||
}
|
||||
|
||||
module.exports = webpackConfig
|
@ -0,0 +1,7 @@
|
||||
'use strict'
|
||||
const merge = require('webpack-merge')
|
||||
const prodEnv = require('./prod.env')
|
||||
|
||||
module.exports = merge(prodEnv, {
|
||||
NODE_ENV: '"development"'
|
||||
})
|
@ -0,0 +1,69 @@
|
||||
'use strict'
|
||||
// Template version: 1.3.1
|
||||
// see http://vuejs-templates.github.io/webpack for documentation.
|
||||
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
dev: {
|
||||
|
||||
// Paths
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
proxyTable: {},
|
||||
|
||||
// Various Dev Server settings
|
||||
host: 'localhost', // can be overwritten by process.env.HOST
|
||||
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
|
||||
autoOpenBrowser: false,
|
||||
errorOverlay: true,
|
||||
notifyOnErrors: true,
|
||||
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
|
||||
|
||||
|
||||
/**
|
||||
* Source Maps
|
||||
*/
|
||||
|
||||
// https://webpack.js.org/configuration/devtool/#development
|
||||
devtool: 'cheap-module-eval-source-map',
|
||||
|
||||
// If you have problems debugging vue-files in devtools,
|
||||
// set this to false - it *may* help
|
||||
// https://vue-loader.vuejs.org/en/options.html#cachebusting
|
||||
cacheBusting: true,
|
||||
|
||||
cssSourceMap: true
|
||||
},
|
||||
|
||||
build: {
|
||||
// Template for index.html
|
||||
index: path.resolve(__dirname, '../dist/index.html'),
|
||||
|
||||
// Paths
|
||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
|
||||
/**
|
||||
* Source Maps
|
||||
*/
|
||||
|
||||
productionSourceMap: true,
|
||||
// https://webpack.js.org/configuration/devtool/#production
|
||||
devtool: '#source-map',
|
||||
|
||||
// Gzip off by default as many popular static hosts such as
|
||||
// Surge or Netlify already gzip all static assets for you.
|
||||
// Before setting to `true`, make sure to:
|
||||
// npm install --save-dev compression-webpack-plugin
|
||||
productionGzip: false,
|
||||
productionGzipExtensions: ['js', 'css'],
|
||||
|
||||
// Run the build command with an extra argument to
|
||||
// View the bundle analyzer report after build finishes:
|
||||
// `npm run build --report`
|
||||
// Set to `true` or `false` to always turn it on or off
|
||||
bundleAnalyzerReport: process.env.npm_config_report
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
'use strict'
|
||||
module.exports = {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>deplugin-view-frontend</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "deplugin-datasource-frontend",
|
||||
"version": "1.0.0",
|
||||
"description": "A Vue.js project",
|
||||
"author": "",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
|
||||
"start": "npm run dev",
|
||||
"build": "node build/build.js",
|
||||
"buildPlugin": "node build/build-async-plugins.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@riophae/vue-treeselect": "0.4.0",
|
||||
"highcharts": "^10.0.0",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"svgo": "1.2.2",
|
||||
"svgo-loader": "^3.0.1",
|
||||
"vue": "^2.5.2",
|
||||
"vue-i18n": "7.3.2",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-uuid": "2.0.2",
|
||||
"vuedraggable": "^2.24.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^7.1.2",
|
||||
"babel-core": "^6.22.1",
|
||||
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
||||
"babel-loader": "^7.1.1",
|
||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
||||
"babel-plugin-transform-runtime": "^6.22.0",
|
||||
"babel-plugin-transform-vue-jsx": "^3.5.0",
|
||||
"babel-preset-env": "^1.3.2",
|
||||
"babel-preset-stage-2": "^6.22.0",
|
||||
"chalk": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.6.0",
|
||||
"css-loader": "^0.28.0",
|
||||
"element-ui": "2.15.7",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"file-loader": "^1.1.4",
|
||||
"friendly-errors-webpack-plugin": "^1.6.1",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"js-cookie": "2.2.0",
|
||||
"node-notifier": "^8.0.1",
|
||||
"optimize-css-assets-webpack-plugin": "^3.2.0",
|
||||
"ora": "^1.2.0",
|
||||
"portfinder": "^1.0.13",
|
||||
"postcss-import": "^11.0.0",
|
||||
"postcss-loader": "^2.0.8",
|
||||
"postcss-url": "^7.2.1",
|
||||
"rimraf": "^2.6.0",
|
||||
"sass": "^1.33.0",
|
||||
"sass-loader": "^7.3.1",
|
||||
"semver": "^5.3.0",
|
||||
"shelljs": "^0.8.5",
|
||||
"uglifyjs-webpack-plugin": "^1.1.1",
|
||||
"url-loader": "^0.5.8",
|
||||
"vue-loader": "^15.6.4",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
"vue-template-compiler": "^2.5.2",
|
||||
"webpack": "^4.8.1",
|
||||
"webpack-bundle-analyzer": "^3.3.2",
|
||||
"webpack-dev-server": "^3.1.11",
|
||||
"webpack-merge": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>dm</artifactId>
|
||||
<version>${dataease.version}</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>dm-frontend</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<frontend-maven-plugin.version>1.9.1</frontend-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>static</directory>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
<followSymlinks>false</followSymlinks>
|
||||
</fileset>
|
||||
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>${frontend-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install node and npm</id>
|
||||
<goals>
|
||||
<goal>install-node-and-npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- See https://nodejs.org/en/download/ for latest node and npm (lts) versions -->
|
||||
<nodeVersion>v16.20.2</nodeVersion>
|
||||
<npmVersion>7.6.3</npmVersion>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>npm install</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<!-- Optional configuration which provides for running any npm command -->
|
||||
<configuration>
|
||||
<arguments>install --force</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>npm run buildPlugin</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>run buildPlugin</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
</style>
|
After Width: | Height: | Size: 6.7 KiB |
@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<h2>Essential Links</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="https://vuejs.org"
|
||||
target="_blank"
|
||||
>
|
||||
Core Docs
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://forum.vuejs.org"
|
||||
target="_blank"
|
||||
>
|
||||
Forum
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://chat.vuejs.org"
|
||||
target="_blank"
|
||||
>
|
||||
Community Chat
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://twitter.com/vuejs"
|
||||
target="_blank"
|
||||
>
|
||||
Twitter
|
||||
</a>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<a
|
||||
href="http://vuejs-templates.github.io/webpack/"
|
||||
target="_blank"
|
||||
>
|
||||
Docs for This Template
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Ecosystem</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="http://router.vuejs.org/"
|
||||
target="_blank"
|
||||
>
|
||||
vue-router
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="http://vuex.vuejs.org/"
|
||||
target="_blank"
|
||||
>
|
||||
vuex
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="http://vue-loader.vuejs.org/"
|
||||
target="_blank"
|
||||
>
|
||||
vue-loader
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/awesome-vue"
|
||||
target="_blank"
|
||||
>
|
||||
awesome-vue
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
data () {
|
||||
return {
|
||||
msg: 'Welcome to Your Vue.js App'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h1, h2 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,16 @@
|
||||
export default {
|
||||
plugin_view_3d_pie: {
|
||||
type_title: '3D-PIE',
|
||||
label: 'Label',
|
||||
angle: 'Angle'
|
||||
},
|
||||
host: 'Host',
|
||||
port: 'Port',
|
||||
dataBase: 'Catalog',
|
||||
schema: 'Schema',
|
||||
username: 'User',
|
||||
password: 'Password',
|
||||
get_schema: 'Get Schema',
|
||||
please_choose_schema: 'Please select Schema',
|
||||
query_timeout: 'Query timeout (seconds)'
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import Cookies from 'js-cookie'
|
||||
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
|
||||
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
|
||||
import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang
|
||||
|
||||
import localMessages from './messages'
|
||||
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const messages = {
|
||||
en_US: {
|
||||
...localMessages['en_US'],
|
||||
...elementEnLocale
|
||||
},
|
||||
zh_CN: {
|
||||
...localMessages['zh_CN'],
|
||||
...elementZhLocale
|
||||
},
|
||||
zh_TW: {
|
||||
...localMessages['zh_TW'],
|
||||
...elementTWLocale
|
||||
}
|
||||
}
|
||||
export function getLanguage () {
|
||||
const chooseLanguage = Cookies.get('language')
|
||||
if (chooseLanguage) return chooseLanguage
|
||||
|
||||
// if has not choose language
|
||||
const language = (navigator.language || navigator.browserLanguage).toLowerCase()
|
||||
const locales = Object.keys(messages)
|
||||
for (const locale of locales) {
|
||||
if (language.indexOf(locale) > -1) {
|
||||
return locale
|
||||
}
|
||||
}
|
||||
return 'zh_CN'
|
||||
}
|
||||
const i18n = new VueI18n({
|
||||
// set locale
|
||||
// options: en | zh | es
|
||||
locale: getLanguage(),
|
||||
// set locale messages
|
||||
messages
|
||||
})
|
||||
|
||||
export default i18n
|
@ -0,0 +1,17 @@
|
||||
import enLocale from './en'
|
||||
import zhLocale from './zh'
|
||||
import twLocale from './tw'
|
||||
|
||||
const messages = {
|
||||
en_US: {
|
||||
...enLocale
|
||||
},
|
||||
zh_CN: {
|
||||
...zhLocale
|
||||
},
|
||||
zh_TW: {
|
||||
...twLocale
|
||||
}
|
||||
}
|
||||
|
||||
export default messages
|
@ -0,0 +1,16 @@
|
||||
export default {
|
||||
plugin_view_3d_pie: {
|
||||
type_title: '3D餅圖',
|
||||
label: '標籤',
|
||||
angle: '角度'
|
||||
},
|
||||
host: '主機名',
|
||||
port: '端口',
|
||||
dataBase: '數據庫',
|
||||
schema: 'Schema',
|
||||
username: '用戶名',
|
||||
password: '密碼',
|
||||
get_schema: '获取 Schema',
|
||||
please_choose_schema: '请选择 Schema',
|
||||
query_timeout: '査詢超時(秒)'
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
export default {
|
||||
plugin_view_3d_pie: {
|
||||
type_title: '3D饼图',
|
||||
label: '标签',
|
||||
angle: '角度'
|
||||
},
|
||||
host: '主机名',
|
||||
port: '端口',
|
||||
dataBase: '数据库',
|
||||
schema: 'Schema',
|
||||
username: '用户名',
|
||||
password: '密码',
|
||||
get_schema: '获取 Schema',
|
||||
please_choose_schema: '请选择 Schema',
|
||||
second: '秒',
|
||||
enter_the_port: '请输入端口',
|
||||
one_user_name: '请输入用户名',
|
||||
input_a_password: '请输入密码',
|
||||
please_select: '请选择',
|
||||
query_timeout: '查询超时'
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
import Vue from 'vue'
|
||||
import SvgIcon from '@/components/SvgIcon'// svg component
|
||||
|
||||
// register globally
|
||||
Vue.component('svg-icon', SvgIcon)
|
||||
|
||||
const req = require.context('./svg', false, /\.svg$/)
|
||||
const requireAll = requireContext => requireContext.keys().map(requireContext)
|
||||
requireAll(req)
|
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.00022 9.99975C7.56203 9.99975 7.13323 9.96523 6.71734 9.89921L6.38535 11.1382C6.33771 11.316 6.15493 11.4216 5.9771 11.3739L5.33315 11.2014C5.15533 11.1537 5.0498 10.9709 5.09745 10.7931L5.42255 9.57985C4.88013 9.39561 4.37096 9.15494 3.90491 8.86629L2.8454 9.9258C2.71522 10.056 2.50417 10.056 2.37399 9.9258L1.90259 9.4544C1.77242 9.32422 1.77242 9.11317 1.90259 8.98299L2.83565 8.04994C2.35424 7.59918 1.95209 7.0852 1.64812 6.52421C1.64492 6.51832 1.64162 6.51215 1.63823 6.50575C1.5136 6.27038 1.56023 5.97574 1.75709 5.79635C1.92051 5.64743 2.03596 5.5461 2.13639 5.44567C2.14538 5.43669 2.15521 5.42666 2.16569 5.41583C2.31108 5.2656 2.55902 5.32152 2.64417 5.51246C3.47427 7.37398 5.46211 8.66641 8.00022 8.66641C10.4321 8.66641 12.4664 7.40872 13.2829 5.68239C13.3042 5.63747 13.328 5.5809 13.3519 5.52084C13.4276 5.33064 13.6741 5.27325 13.8188 5.41801C13.9259 5.52508 14.0687 5.66784 14.2471 5.8463C14.4235 6.0227 14.4713 6.29211 14.356 6.51334C14.3279 6.56715 14.3006 6.61785 14.2774 6.65816C13.9638 7.20109 13.5572 7.69751 13.0754 8.1321L13.9263 8.98299C14.0565 9.11317 14.0565 9.32422 13.9263 9.4544L13.4549 9.9258C13.3247 10.056 13.1136 10.056 12.9835 9.9258L11.9888 8.93112C11.5521 9.19111 11.0792 9.40958 10.5779 9.57985L10.903 10.7931C10.9506 10.9709 10.8451 11.1537 10.6673 11.2014L10.0233 11.3739C9.84552 11.4216 9.66274 11.316 9.61509 11.1382L9.2831 9.89921C8.86721 9.96523 8.43842 9.99975 8.00022 9.99975Z" fill="#BBBFC4"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.98994 12.333C10.1486 12.333 12.1472 10.9599 14.0001 7.99101C12.1949 5.03272 10.2008 3.66634 7.98994 3.66634C5.77984 3.66634 3.7929 5.0321 2.00009 7.99099C3.84053 10.9605 5.83206 12.333 7.98994 12.333ZM1.00172 8.59304C0.787049 8.22763 0.785596 7.77336 0.995302 7.40508C1.00277 7.39196 1.00993 7.37945 1.01672 7.36768C2.9521 4.01123 5.27627 2.33301 7.98923 2.33301C10.7133 2.33301 13.0518 4.02495 15.0049 7.40884C15.0107 7.41898 15.0168 7.42969 15.0232 7.44089C15.2208 7.7869 15.2193 8.21401 15.0172 8.55738C13.0127 11.9634 10.67 13.6663 7.98923 13.6663C5.31784 13.6663 2.98867 11.9752 1.00172 8.59304ZM8.00009 10.6663C6.52733 10.6663 5.33342 9.47243 5.33342 7.99967C5.33342 6.52692 6.52733 5.33301 8.00009 5.33301C9.47285 5.33301 10.6668 6.52692 10.6668 7.99967C10.6668 9.47243 9.47285 10.6663 8.00009 10.6663ZM8.00009 9.33301C8.73647 9.33301 9.33342 8.73605 9.33342 7.99967C9.33342 7.26329 8.73647 6.66634 8.00009 6.66634C7.26371 6.66634 6.66675 7.26329 6.66675 7.99967C6.66675 8.73605 7.26371 9.33301 8.00009 9.33301Z" fill="#BBBFC4"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{isolation:isolate;}.cls-2{fill:#f2f4f5;}.cls-3{fill:#0a7be0;}.cls-4{fill:#53baf9;}.cls-5,.cls-6{fill:#a2a2ba;}.cls-6{mix-blend-mode:multiply;}.cls-7{fill:#fff;}</style></defs><title>【icon】插件管理-导出</title><g class="cls-1"><g id="图层_1" data-name="图层 1"><circle class="cls-2" cx="31.9" cy="32" r="32"/><path class="cls-3" d="M25.94,44.24l6.49-11H43.74V13.26A2.26,2.26,0,0,0,41.49,11H14.6a2.46,2.46,0,0,0-2.46,2.46V44.12a3.5,3.5,0,0,0,3.5,3.5H27.93Z"/><path class="cls-4" d="M25.94,44.24l1.18-2H14.83a2.7,2.7,0,0,0-2.69,2.69h0a2.7,2.7,0,0,0,2.69,2.69h13.1Z"/><polygon class="cls-5" points="33.78 53 28.63 44.24 33.78 35.47 51.67 35.47 51.67 53 33.78 53"/><polygon class="cls-6" points="33.78 53 28.63 44.24 51.67 44.17 51.67 53 33.78 53"/><path class="cls-7" d="M38.59,43.4a4.27,4.27,0,0,1-.88-2.7c-.27.19-.53.38-.78.58a3.21,3.21,0,0,0,.67,2.33c.91.82,1.69.35,2.76,1.16.79.6.46,2,.16,2.87.27-.1.55-.21.83-.34.25-1,.51-2.4-.05-2.89C40.42,43.64,39.3,44.08,38.59,43.4Z"/><path class="cls-7" d="M40.14,45.11c-.87-.77-2.12-.54-2.86-1.3a3.5,3.5,0,0,1-.82-2.13c-1.86,1.71-2.71,3.73-1.94,5.12s3.07,1.74,5.59,1C40.4,46.86,40.68,45.58,40.14,45.11Z"/><path class="cls-7" d="M43.72,43.66c-.88-.77-2.37-.86-2.93-1.44-.72-.73-.48-2.17-.29-2.93-.31.11-.63.23-1,.38-.1.73-.24,2.4.46,3,.92.81,1.7.27,2.77,1.09a2.48,2.48,0,0,1,.71,2.3c.24-.17.46-.34.68-.52A2.39,2.39,0,0,0,43.72,43.66Z"/><path class="cls-7" d="M46.49,40.13c-.78-1.38-3-1.73-5.38-1-.29.83-.7,2.36,0,2.94.91.82,2,.54,3.09,1.3a1.84,1.84,0,0,1,.6,1.71C46.47,43.38,47.23,41.46,46.49,40.13Z"/><path class="cls-7" d="M42.62,44c-.88-.77-2.2-.44-2.88-1.16a4.22,4.22,0,0,1-.66-3l-.44.23-.43.25c0,.67,0,2.18.56,2.77.87.87,1.62.21,2.69,1,.81.61.65,2,.47,2.86l.43-.23c.19-.1.37-.21.55-.32C43.06,45.7,43.18,44.52,42.62,44Z"/><rect class="cls-7" x="18.81" y="15.56" width="18.8" height="3.02" rx="1.51"/><rect class="cls-4" x="18.81" y="21.05" width="9.39" height="3.02" rx="1.51"/><rect class="cls-7" x="18.81" y="25.84" width="20.18" height="3.02" rx="1.51"/><circle class="cls-7" cx="15.85" cy="17.07" r="1.51"/><circle class="cls-4" cx="15.85" cy="22.56" r="1.51"/><circle class="cls-7" cx="15.85" cy="27.35" r="1.51"/></g></g></svg>
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 51 KiB |
@ -0,0 +1,22 @@
|
||||
# replace default config
|
||||
|
||||
# multipass: true
|
||||
# full: true
|
||||
|
||||
plugins:
|
||||
|
||||
# - name
|
||||
#
|
||||
# or:
|
||||
# - name: false
|
||||
# - name: true
|
||||
#
|
||||
# or:
|
||||
# - name:
|
||||
# param1: 1
|
||||
# param2: 2
|
||||
|
||||
- removeAttrs:
|
||||
attrs:
|
||||
- 'fill'
|
||||
- 'fill-rule'
|
@ -0,0 +1,33 @@
|
||||
// The Vue build version to load with the `import` command
|
||||
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import router from './router'
|
||||
import ElementUI from 'element-ui'
|
||||
import Cookies from 'js-cookie'
|
||||
import i18n from './de-base/lang'
|
||||
import draggable from 'vuedraggable'
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
Vue.config.productionTip = false
|
||||
Vue.use(ElementUI, {
|
||||
size: Cookies.get('size') || 'medium',
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
})
|
||||
Vue.component('Treeselect', Treeselect)
|
||||
Vue.component('draggable', draggable)
|
||||
Vue.prototype.hasDataPermission = function(pTarget, pSource) {
|
||||
|
||||
if (pSource && pTarget) {
|
||||
return pSource.indexOf(pTarget) > -1
|
||||
}
|
||||
return false
|
||||
}
|
||||
/* eslint-disable no-new */
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
i18n,
|
||||
components: { App },
|
||||
template: '<App/>'
|
||||
})
|
@ -0,0 +1,21 @@
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import HelloWorld from '@/components/HelloWorld'
|
||||
import maxcompute from '@/views/maxcompute'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'HelloWorld',
|
||||
component: HelloWorld
|
||||
},
|
||||
{
|
||||
path: '/maxcompute',
|
||||
name: 'maxcompute',
|
||||
component: maxcompute
|
||||
}
|
||||
]
|
||||
})
|
@ -0,0 +1,29 @@
|
||||
export const compareItem = {
|
||||
type: 'none', // year-yoy/month-yoy等
|
||||
resultData: 'percent', // 对比差sub,百分比percent等
|
||||
field: '',
|
||||
custom: {
|
||||
field: '',
|
||||
calcType: '0', // 0-增长值,1-增长率
|
||||
timeType: '0', // 0-固定日期,1-日期区间
|
||||
currentTime: '',
|
||||
compareTime: '',
|
||||
currentTimeRange: [],
|
||||
compareTimeRange: []
|
||||
}
|
||||
}
|
||||
|
||||
export const compareYearList = [
|
||||
{ name: 'year_mom', value: 'year_mom' }
|
||||
]
|
||||
|
||||
export const compareMonthList = [
|
||||
{ name: 'month_mom', value: 'month_mom' },
|
||||
{ name: 'year_yoy', value: 'year_yoy' }
|
||||
]
|
||||
|
||||
export const compareDayList = [
|
||||
{ name: 'day_mom', value: 'day_mom' },
|
||||
{ name: 'month_yoy', value: 'month_yoy' },
|
||||
{ name: 'year_yoy', value: 'year_yoy' }
|
||||
]
|
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Created by PanJiaChen on 16/11/18.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo')
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<el-input
|
||||
:value="value"
|
||||
:placeholder="placeholder"
|
||||
:type="type"
|
||||
:disabled="disabled"
|
||||
class="de-pwd-input"
|
||||
@input="handleInput"
|
||||
@change="handleChange"
|
||||
>
|
||||
<svg-icon
|
||||
@click="handleClick"
|
||||
v-if="!showPwd || buttonDisabled"
|
||||
slot="suffix"
|
||||
icon-class="de_pwd_invisible"
|
||||
/>
|
||||
<svg-icon
|
||||
@click="handleClick"
|
||||
v-else
|
||||
slot="suffix"
|
||||
icon-class="de_pwd_visible"
|
||||
/>
|
||||
</el-input>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "DePwd",
|
||||
inject: {
|
||||
elForm: {
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
props: {
|
||||
disabled: Boolean,
|
||||
placeholder: String,
|
||||
value: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showPwd: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
buttonDisabled() {
|
||||
return this.$options.propsData.hasOwnProperty("disabled")
|
||||
? this.disabled
|
||||
: (this.elForm || {}).disabled;
|
||||
},
|
||||
type() {
|
||||
return !this.showPwd || this.buttonDisabled ? "password" : "text";
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
if (this.buttonDisabled) return;
|
||||
this.showPwd = !this.showPwd;
|
||||
},
|
||||
handleInput(val) {
|
||||
this.$emit("input", val);
|
||||
},
|
||||
handleChange(val) {
|
||||
this.$emit("change", val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.de-pwd-input {
|
||||
.el-input__suffix {
|
||||
right: 12px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,202 @@
|
||||
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col>
|
||||
|
||||
<el-form
|
||||
ref="DsForm"
|
||||
:model="form"
|
||||
:rules="rule"
|
||||
size="small"
|
||||
:disabled="disabled"
|
||||
label-width="180px"
|
||||
label-position="right"
|
||||
>
|
||||
<el-form-item :label="$t('host')" prop="configuration.host">
|
||||
<el-input v-model="form.configuration.host" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('port')" prop="configuration.port">
|
||||
<el-input :placeholder="$t('enter_the_port')" v-model="form.configuration.port" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('dataBase')" prop="configuration.dataBase">
|
||||
<el-input v-model="form.configuration.dataBase" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('username')" prop="configuration.username">
|
||||
<el-input :placeholder="$t('one_user_name')" v-model="form.configuration.username" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('password')" prop="configuration.password">
|
||||
<dePwd :placeholder="$t('input_a_password')" v-model="form.configuration.password" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="schema-label" :label="$t('schema')">
|
||||
<template slot="label">
|
||||
{{ $t("schema") }}
|
||||
<el-button type="text" icon="el-icon-plus" size="small" @click="getSchema()">{{ $t('get_schema') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<el-select v-model="form.configuration.schema" filterable
|
||||
:placeholder="$t('please_select')"
|
||||
class="de-select">
|
||||
<el-option v-for="item in schemas" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('query_timeout')">
|
||||
<el-input
|
||||
v-model="form.configuration.queryTimeout"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
:min="0"
|
||||
>
|
||||
<template slot="append">{{ $t("second") }}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import messages from '@/de-base/lang/messages'
|
||||
import dePwd from "./dePwd.vue";
|
||||
|
||||
export default {
|
||||
name: "dm",
|
||||
components: { dePwd },
|
||||
props: {
|
||||
method: String,
|
||||
request: {},
|
||||
response: {},
|
||||
editApiItem: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
showScript: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
obj: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
configuration: {
|
||||
initialPoolSize: 5,
|
||||
extraParams: '',
|
||||
minPoolSize: 5,
|
||||
maxPoolSize: 50,
|
||||
maxIdleTime: 30,
|
||||
acquireIncrement: 5,
|
||||
idleConnectionTestPeriod: 5,
|
||||
queryTimeout: 30,
|
||||
connectTimeout: 5
|
||||
},
|
||||
apiConfiguration: []
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
rule: {
|
||||
'configuration.host': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}],
|
||||
'configuration.port': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}],
|
||||
'configuration.dataBase': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}],
|
||||
'configuration.username': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}],
|
||||
'configuration.password': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}]
|
||||
},
|
||||
canEdit: false,
|
||||
originConfiguration: {},
|
||||
height: 500,
|
||||
disabledNext: false,
|
||||
schemas: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
form() {
|
||||
return this.obj.form
|
||||
},
|
||||
disabled() {
|
||||
return this.obj.disabled
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$emit('on-add-languages', messages)
|
||||
},
|
||||
watch: {},
|
||||
methods: {
|
||||
executeAxios(url, type, data, callBack) {
|
||||
const param = {
|
||||
url: url,
|
||||
type: type,
|
||||
data: data,
|
||||
callBack: callBack
|
||||
}
|
||||
this.$emit('execute-axios', param)
|
||||
},
|
||||
getSchema() {
|
||||
this.$refs["DsForm"].validate(valid => {
|
||||
if (valid) {
|
||||
const data = JSON.parse(JSON.stringify(this.form))
|
||||
data.configuration = JSON.stringify(data.configuration)
|
||||
this.executeAxios('/datasource/getSchema/', 'post', data, res => {
|
||||
this.schemas = res.data
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
validate() {
|
||||
let status = null;
|
||||
this.$refs["DsForm"].validate((val) => {
|
||||
if (val) {
|
||||
status = true
|
||||
} else {
|
||||
status = false
|
||||
}
|
||||
})
|
||||
|
||||
if (!this.form.configuration.schema ) {
|
||||
this.$message.error(this.$t('please_choose_schema'))
|
||||
status = false
|
||||
}
|
||||
return status
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-query {
|
||||
background: #409EFF;
|
||||
color: white;
|
||||
height: 18px;
|
||||
border-radius: 42%;
|
||||
}
|
||||
|
||||
.ms-header {
|
||||
background: #409EFF;
|
||||
color: white;
|
||||
height: 18px;
|
||||
border-radius: 42%;
|
||||
}
|
||||
|
||||
.request-tabs {
|
||||
margin: 20px;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.ms-el-link {
|
||||
float: right;
|
||||
margin-right: 45px;
|
||||
}
|
||||
</style>
|
13
extensions/dataease-extensions-datasource/dm/plugin.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name":"达梦数据源插件",
|
||||
"free":0,
|
||||
"store":"default",
|
||||
"cost":0,
|
||||
"category":"datasource",
|
||||
"descript":"达梦插件,值得拥有",
|
||||
"version":"1.18.0",
|
||||
"creator":"DATAEASE",
|
||||
"moduleName":"dm-backend",
|
||||
"require":"1.12.0",
|
||||
"dsType":"dm"
|
||||
}
|
19
extensions/dataease-extensions-datasource/dm/pom.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>dataease-extensions-datasource</artifactId>
|
||||
<groupId>io.dataease</groupId>
|
||||
<version>${dataease.version}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>dm</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>dm-frontend</module>
|
||||
<module>dm-backend</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
6
extensions/dataease-extensions-datasource/kingbase/build.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
mvn clean package -U -Dmaven.test.skip=true
|
||||
|
||||
cp kingbase-backend/target/kingbase-backend-1.18.0.jar .
|
||||
|
||||
zip -r kingbase.zip ./kingbase-backend-1.18.0.jar ./kingbaseDriver ./plugin.json
|
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>kingbase</artifactId>
|
||||
<groupId>io.dataease</groupId>
|
||||
<version>${dataease.version}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>kingbase-backend</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>dataease-plugin-datasource</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/server/**</exclude>
|
||||
<exclude>**/*.properties</exclude>
|
||||
<exclude>**/Application*</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>src/main/resources/static</directory>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
<followSymlinks>false</followSymlinks>
|
||||
</fileset>
|
||||
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>main-class-placement</id>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<target>
|
||||
<move todir="src/main/resources/static">
|
||||
<fileset dir="../kingbase-frontend/static">
|
||||
<include name="*.*"/>
|
||||
</fileset>
|
||||
</move>
|
||||
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
@ -0,0 +1,27 @@
|
||||
package io.dataease.plugins.datasource.kingbase.provider;
|
||||
|
||||
import io.dataease.plugins.datasource.entity.JdbcConfiguration;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 连接配置信息
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class KingbaseConfig extends JdbcConfiguration {
|
||||
|
||||
private String driver = "com.kingbase8.Driver";//驱动类名
|
||||
private String extraParams;
|
||||
|
||||
|
||||
/**
|
||||
* JDBC 拼接
|
||||
*/
|
||||
public String getJdbc() {
|
||||
return "jdbc:kingbase8://HOST:PORT/DATABASE"
|
||||
.replace("HOST", getHost().trim())
|
||||
.replace("PORT", getPort().toString())
|
||||
.replace("DATABASE", getDataBase().trim());
|
||||
}
|
||||
}
|
@ -0,0 +1,264 @@
|
||||
package io.dataease.plugins.datasource.kingbase.provider;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.plugins.common.base.domain.DeDriver;
|
||||
import io.dataease.plugins.common.base.mapper.DeDriverMapper;
|
||||
import io.dataease.plugins.common.constants.DatasourceTypes;
|
||||
import io.dataease.plugins.common.dto.datasource.TableDesc;
|
||||
import io.dataease.plugins.common.dto.datasource.TableField;
|
||||
import io.dataease.plugins.common.exception.DataEaseException;
|
||||
import io.dataease.plugins.common.request.datasource.DatasourceRequest;
|
||||
import io.dataease.plugins.datasource.entity.JdbcConfiguration;
|
||||
import io.dataease.plugins.datasource.provider.DefaultJdbcProvider;
|
||||
import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
@Component()
|
||||
public class KingbaseDsProvider extends DefaultJdbcProvider {
|
||||
@Resource
|
||||
private DeDriverMapper deDriverMapper;
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "kingbase";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseDatasourcePool() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接数据源
|
||||
*/
|
||||
@Override
|
||||
public Connection getConnection(DatasourceRequest datasourceRequest) throws Exception {
|
||||
KingbaseConfig kingbaseConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(),
|
||||
KingbaseConfig.class);
|
||||
|
||||
String defaultDriver = kingbaseConfig.getDriver();
|
||||
String customDriver = kingbaseConfig.getCustomDriver();
|
||||
|
||||
String url = kingbaseConfig.getJdbc();
|
||||
Properties props = new Properties();
|
||||
DeDriver deDriver = null;
|
||||
if (StringUtils.isNotEmpty(kingbaseConfig.getAuthMethod()) && kingbaseConfig.getAuthMethod().equalsIgnoreCase("kerberos")) {
|
||||
System.setProperty("java.security.krb5.conf", "/opt/dataease/conf/krb5.conf");
|
||||
ExtendedJdbcClassLoader classLoader;
|
||||
if (isDefaultClassLoader(customDriver)) {
|
||||
classLoader = extendedJdbcClassLoader;
|
||||
} else {
|
||||
deDriver = deDriverMapper.selectByPrimaryKey(customDriver);
|
||||
classLoader = getCustomJdbcClassLoader(deDriver);
|
||||
}
|
||||
Class<?> ConfigurationClass = classLoader.loadClass("org.apache.hadoop.conf.Configuration");
|
||||
Method set = ConfigurationClass.getMethod("set", String.class, String.class);
|
||||
Object obj = ConfigurationClass.newInstance();
|
||||
set.invoke(obj, "hadoop.security.authentication", "Kerberos");
|
||||
|
||||
Class<?> UserGroupInformationClass = classLoader.loadClass("org.apache.hadoop.security" +
|
||||
".UserGroupInformation");
|
||||
Method setConfiguration = UserGroupInformationClass.getMethod("setConfiguration", ConfigurationClass);
|
||||
Method loginUserFromKeytab = UserGroupInformationClass.getMethod("loginUserFromKeytab", String.class,
|
||||
String.class);
|
||||
setConfiguration.invoke(null, obj);
|
||||
loginUserFromKeytab.invoke(null, kingbaseConfig.getUsername(),
|
||||
"/opt/dataease/conf/" + kingbaseConfig.getPassword());
|
||||
} else {
|
||||
if (StringUtils.isNotBlank(kingbaseConfig.getUsername())) {
|
||||
props.setProperty("user", kingbaseConfig.getUsername());
|
||||
if (StringUtils.isNotBlank(kingbaseConfig.getPassword())) {
|
||||
props.setProperty("password", kingbaseConfig.getPassword());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connection conn;
|
||||
String driverClassName;
|
||||
ExtendedJdbcClassLoader jdbcClassLoader;
|
||||
if (isDefaultClassLoader(customDriver)) {
|
||||
driverClassName = defaultDriver;
|
||||
jdbcClassLoader = extendedJdbcClassLoader;
|
||||
} else {
|
||||
if (deDriver == null) {
|
||||
deDriver = deDriverMapper.selectByPrimaryKey(customDriver);
|
||||
}
|
||||
driverClassName = deDriver.getDriverClass();
|
||||
jdbcClassLoader = getCustomJdbcClassLoader(deDriver);
|
||||
}
|
||||
|
||||
Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance();
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(jdbcClassLoader);
|
||||
conn = driverClass.connect(url, props);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表名称
|
||||
*/
|
||||
@Override
|
||||
public List<TableDesc> getTables(DatasourceRequest datasourceRequest) throws Exception {
|
||||
List<TableDesc> tables = new ArrayList<>();
|
||||
String queryStr = getTablesSql(datasourceRequest);
|
||||
JdbcConfiguration jdbcConfiguration =
|
||||
new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class);
|
||||
int queryTimeout = Math.max(jdbcConfiguration.getQueryTimeout(), 0);
|
||||
try (Connection con = getConnectionFromPool(datasourceRequest); Statement statement = getStatement(con,
|
||||
queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) {
|
||||
while (resultSet.next()) {
|
||||
tables.add(getTableDesc(datasourceRequest, resultSet));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
DataEaseException.throwException(e);
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表名称
|
||||
*/
|
||||
private TableDesc getTableDesc(DatasourceRequest datasourceRequest, ResultSet resultSet) throws SQLException {
|
||||
TableDesc tableDesc = new TableDesc();
|
||||
tableDesc.setName(resultSet.getString(1));
|
||||
return tableDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表字段信息
|
||||
*/
|
||||
@Override
|
||||
public List<TableField> getTableFields(DatasourceRequest datasourceRequest) throws Exception {
|
||||
List<TableField> list = new LinkedList<>();
|
||||
try (Connection connection = getConnectionFromPool(datasourceRequest)) {
|
||||
DatabaseMetaData databaseMetaData = connection.getMetaData();
|
||||
ResultSet resultSet = databaseMetaData.getColumns(null, null, datasourceRequest.getTable(), "%");
|
||||
while (resultSet.next()) {
|
||||
String tableName = resultSet.getString("TABLE_NAME").toUpperCase();
|
||||
String database;
|
||||
database = resultSet.getString("TABLE_CAT");
|
||||
if (database != null) {
|
||||
if (tableName.equals(datasourceRequest.getTable()) && database.equalsIgnoreCase(getDatabase(datasourceRequest))) {
|
||||
TableField tableField = getTableFiled(resultSet, datasourceRequest);
|
||||
list.add(tableField);
|
||||
}
|
||||
} else {
|
||||
if (tableName.equals(datasourceRequest.getTable())) {
|
||||
TableField tableField = getTableFiled(resultSet, datasourceRequest);
|
||||
list.add(tableField);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultSet.close();
|
||||
} catch (SQLException e) {
|
||||
DataEaseException.throwException(e);
|
||||
} catch (Exception e) {
|
||||
DataEaseException.throwException("Data source connection exception: " + e.getMessage());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据源
|
||||
*/
|
||||
private String getDatabase(DatasourceRequest datasourceRequest) {
|
||||
JdbcConfiguration jdbcConfiguration =
|
||||
new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class);
|
||||
return jdbcConfiguration.getDataBase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表字段
|
||||
*/
|
||||
private TableField getTableFiled(ResultSet resultSet, DatasourceRequest datasourceRequest) throws SQLException {
|
||||
TableField tableField = new TableField();
|
||||
String colName = resultSet.getString("COLUMN_NAME");
|
||||
tableField.setFieldName(colName);
|
||||
String remarks = resultSet.getString("REMARKS");
|
||||
if (remarks == null || remarks.equals("")) {
|
||||
remarks = colName;
|
||||
}
|
||||
tableField.setRemarks(remarks);
|
||||
String dbType = resultSet.getString("TYPE_NAME").toUpperCase();
|
||||
tableField.setFieldType(dbType);
|
||||
if (dbType.equalsIgnoreCase("LONG")) {
|
||||
tableField.setFieldSize(65533);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(dbType) && dbType.toLowerCase().contains("date") && tableField.getFieldSize() < 50) {
|
||||
tableField.setFieldSize(50);
|
||||
}
|
||||
|
||||
if (datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.hive.name()) && tableField.getFieldType().equalsIgnoreCase("BOOLEAN")) {
|
||||
tableField.setFieldSize(1);
|
||||
} else {
|
||||
String size = resultSet.getString("COLUMN_SIZE");
|
||||
if (size == null) {
|
||||
tableField.setFieldSize(1);
|
||||
} else {
|
||||
tableField.setFieldSize(Integer.valueOf(size));
|
||||
}
|
||||
}
|
||||
return tableField;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验数据源状态
|
||||
*/
|
||||
@Override
|
||||
public String checkStatus(DatasourceRequest datasourceRequest) throws Exception {
|
||||
String queryStr = getTablesSql(datasourceRequest);
|
||||
JdbcConfiguration jdbcConfiguration =
|
||||
new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), JdbcConfiguration.class);
|
||||
int queryTimeout = Math.max(jdbcConfiguration.getQueryTimeout(), 0);
|
||||
try (Connection con = getConnection(datasourceRequest); Statement statement = getStatement(con, queryTimeout); ResultSet resultSet = statement.executeQuery(queryStr)) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
DataEaseException.throwException(e.getMessage());
|
||||
}
|
||||
return "Success";
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示对应的表的 SQL 语句
|
||||
*/
|
||||
@Override
|
||||
public String getTablesSql(DatasourceRequest datasourceRequest) throws Exception {
|
||||
KingbaseConfig kingbaseConfig = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(),
|
||||
KingbaseConfig.class);
|
||||
if (StringUtils.isEmpty(kingbaseConfig.getSchema())) {
|
||||
throw new Exception("Database schema is empty.");
|
||||
}
|
||||
/*return "select a.table_name, b.comments from all_tables a, user_tab_comments b where a.table_name = b
|
||||
.table_name and owner=upper('OWNER') ".replaceAll("OWNER",
|
||||
kingbaseConfig.getSchema());*/
|
||||
return ("select table_name from all_tables where owner=upper('OWNER') ").replaceAll("OWNER",
|
||||
kingbaseConfig.getSchema());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的用户
|
||||
*/
|
||||
@Override
|
||||
public String getSchemaSql(DatasourceRequest datasourceRequest) {
|
||||
return "select * from all_users";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package io.dataease.plugins.datasource.kingbase.query;
|
||||
|
||||
|
||||
import io.dataease.plugins.common.constants.datasource.SQLConstants;
|
||||
|
||||
import static io.dataease.plugins.common.constants.DatasourceTypes.oracle;
|
||||
|
||||
public class KingbaseConstants extends SQLConstants {
|
||||
|
||||
public static final String KEYWORD_TABLE = oracle.getKeywordPrefix() + "%s" + oracle.getKeywordSuffix();
|
||||
|
||||
public static final String KEYWORD_FIX = "%s." + oracle.getKeywordPrefix() + "%s" + oracle.getKeywordSuffix();
|
||||
|
||||
public static final String ALIAS_FIX = oracle.getAliasPrefix() + "%s" + oracle.getAliasSuffix();
|
||||
|
||||
public static final String UNIX_TIMESTAMP = "UNIX_TIMESTAMP(%s)";
|
||||
|
||||
public static final String DATE_FORMAT = "to_timestamp(%s,'%s')";
|
||||
|
||||
public static final String FROM_UNIXTIME = "FROM_UNIXTIME(%s,'%s')";
|
||||
|
||||
public static final String CAST = "CAST(%s AS %s)";
|
||||
|
||||
public static final String DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH24:MI:SS";
|
||||
|
||||
public static final String DEFAULT_INT_FORMAT = "DECIMAL(20,0)";
|
||||
|
||||
public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(20,8)";
|
||||
|
||||
public static final String WHERE_VALUE_NULL = "(NULL,'')";
|
||||
|
||||
public static final String WHERE_VALUE_VALUE = "'%s'";
|
||||
|
||||
public static final String AGG_COUNT = "COUNT(*)";
|
||||
|
||||
public static final String AGG_FIELD = "%s(%s)";
|
||||
|
||||
public static final String WHERE_BETWEEN = "'%s' AND '%s'";
|
||||
|
||||
public static final String BRACKETS = "(%s)";
|
||||
|
||||
public static final String TO_NUMBER = "TO_NUMBER(%s)";
|
||||
|
||||
public static final String TO_DATE = "TO_DATE(%s,'%s')";
|
||||
|
||||
public static final String TO_CHAR = "TO_CHAR(%s,'%s')";
|
||||
|
||||
public static final String DEFAULT_START_DATE = "'1970-01-01 8:0:0'";
|
||||
|
||||
public static final String TO_MS = " * 24 * 60 * 60 * 100";
|
||||
|
||||
public static final String CALC_SUB = "%s - %s";
|
||||
|
||||
// public static final String GROUP_CONCAT = "vm_concat(%s)";
|
||||
public static final String GROUP_CONCAT = "to_char(listagg(%s,',' ) within GROUP (order by (%s)))";
|
||||
|
||||
public static final String NAME = "oracle";
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package io.dataease.plugins.datasource.kingbase.service;
|
||||
|
||||
import io.dataease.plugins.common.constants.DatabaseClassification;
|
||||
import io.dataease.plugins.common.constants.DatasourceCalculationMode;
|
||||
import io.dataease.plugins.common.dto.StaticResource;
|
||||
import io.dataease.plugins.common.dto.datasource.DataSourceType;
|
||||
import io.dataease.plugins.datasource.service.DatasourceService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class KingbaseService extends DatasourceService {
|
||||
|
||||
|
||||
/**
|
||||
* 添加数据源类型
|
||||
*/
|
||||
@Override
|
||||
public List<String> components() {
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add("kingbase");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取静态资源
|
||||
*/
|
||||
@Override
|
||||
protected InputStream readContent(String s) {
|
||||
return this.getClass().getClassLoader().getResourceAsStream("static/" + s);
|
||||
}
|
||||
|
||||
/**
|
||||
* 映射 Logo 资源
|
||||
*/
|
||||
@Override
|
||||
public List<StaticResource> staticResources() {
|
||||
List<StaticResource> results = new ArrayList<>();
|
||||
StaticResource staticResource = new StaticResource();
|
||||
staticResource.setName("kingbase");
|
||||
staticResource.setSuffix("jpg");
|
||||
results.add(staticResource);
|
||||
results.add(pluginSvg());
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户填写的数据源信息
|
||||
*/
|
||||
@Override
|
||||
public DataSourceType getDataSourceType() {
|
||||
DataSourceType dataSourceType = new DataSourceType("kingbase", "KingBase", true, "",
|
||||
DatasourceCalculationMode.DIRECT_AND_SYNC, true);
|
||||
dataSourceType.setKeywordPrefix("\"");
|
||||
dataSourceType.setKeywordSuffix("\"");
|
||||
dataSourceType.setAliasPrefix("\"");
|
||||
dataSourceType.setAliasSuffix("\"");
|
||||
dataSourceType.setDatabaseClassification(DatabaseClassification.OLTP);
|
||||
return dataSourceType;
|
||||
}
|
||||
|
||||
private StaticResource pluginSvg() {
|
||||
StaticResource staticResource = new StaticResource();
|
||||
staticResource.setName("kingbase-backend");
|
||||
staticResource.setSuffix("svg");
|
||||
return staticResource;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"modules": false,
|
||||
"targets": {
|
||||
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
|
||||
}
|
||||
}],
|
||||
"stage-2"
|
||||
],
|
||||
"plugins": ["transform-vue-jsx", "transform-runtime"]
|
||||
}
|
14
extensions/dataease-extensions-datasource/kingbase/kingbase-frontend/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
/dist/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
@ -0,0 +1,21 @@
|
||||
# deplugin-view-frontend
|
||||
|
||||
> A Vue.js project
|
||||
|
||||
## Build Setup
|
||||
|
||||
``` bash
|
||||
# install dependencies
|
||||
npm install
|
||||
|
||||
# serve with hot reload at localhost:8080
|
||||
npm run dev
|
||||
|
||||
# build for production with minification
|
||||
npm run build
|
||||
|
||||
# build for production and view the bundle analyzer report
|
||||
npm run build --report
|
||||
```
|
||||
|
||||
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
|
@ -0,0 +1,35 @@
|
||||
'use strict'
|
||||
require('./check-versions')()
|
||||
|
||||
process.env.NODE_ENV = 'production'
|
||||
|
||||
const ora = require('ora')
|
||||
const chalk = require('chalk')
|
||||
const webpack = require('webpack')
|
||||
const webpackConfig = require('./webpack.async-plugins')
|
||||
|
||||
const spinner = ora('building for sync-plugins...')
|
||||
spinner.start()
|
||||
|
||||
webpack(webpackConfig, function (err, stats) {
|
||||
spinner.stop()
|
||||
if (err) throw err
|
||||
process.stdout.write(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
}) + '\n\n')
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
console.log(chalk.red(' Build failed with errors.\n'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(chalk.cyan(' Build complete.\n'))
|
||||
console.log(chalk.yellow(
|
||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
||||
' Opening index.html over file:// won\'t work.\n'
|
||||
))
|
||||
})
|
@ -0,0 +1,41 @@
|
||||
'use strict'
|
||||
require('./check-versions')()
|
||||
|
||||
process.env.NODE_ENV = 'production'
|
||||
|
||||
const ora = require('ora')
|
||||
const rm = require('rimraf')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const webpackConfig = require('./webpack.prod.conf')
|
||||
|
||||
const spinner = ora('building for production...')
|
||||
spinner.start()
|
||||
|
||||
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
|
||||
if (err) throw err
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
spinner.stop()
|
||||
if (err) throw err
|
||||
process.stdout.write(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
}) + '\n\n')
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
console.log(chalk.red(' Build failed with errors.\n'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(chalk.cyan(' Build complete.\n'))
|
||||
console.log(chalk.yellow(
|
||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
||||
' Opening index.html over file:// won\'t work.\n'
|
||||
))
|
||||
})
|
||||
})
|
@ -0,0 +1,54 @@
|
||||
'use strict'
|
||||
const chalk = require('chalk')
|
||||
const semver = require('semver')
|
||||
const packageConfig = require('../package.json')
|
||||
const shell = require('shelljs')
|
||||
|
||||
function exec (cmd) {
|
||||
return require('child_process').execSync(cmd).toString().trim()
|
||||
}
|
||||
|
||||
const versionRequirements = [
|
||||
{
|
||||
name: 'node',
|
||||
currentVersion: semver.clean(process.version),
|
||||
versionRequirement: packageConfig.engines.node
|
||||
}
|
||||
]
|
||||
|
||||
if (shell.which('npm')) {
|
||||
versionRequirements.push({
|
||||
name: 'npm',
|
||||
currentVersion: exec('npm --version'),
|
||||
versionRequirement: packageConfig.engines.npm
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
const warnings = []
|
||||
|
||||
for (let i = 0; i < versionRequirements.length; i++) {
|
||||
const mod = versionRequirements[i]
|
||||
|
||||
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
|
||||
warnings.push(mod.name + ': ' +
|
||||
chalk.red(mod.currentVersion) + ' should be ' +
|
||||
chalk.green(mod.versionRequirement)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (warnings.length) {
|
||||
console.log('')
|
||||
console.log(chalk.yellow('To use this template, you must update following to modules:'))
|
||||
console.log()
|
||||
|
||||
for (let i = 0; i < warnings.length; i++) {
|
||||
const warning = warnings[i]
|
||||
console.log(' ' + warning)
|
||||
}
|
||||
|
||||
console.log()
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 6.7 KiB |
@ -0,0 +1,101 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const config = require('../config')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const packageConfig = require('../package.json')
|
||||
|
||||
exports.assetsPath = function (_path) {
|
||||
const assetsSubDirectory = process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsSubDirectory
|
||||
: config.dev.assetsSubDirectory
|
||||
|
||||
return path.posix.join(assetsSubDirectory, _path)
|
||||
}
|
||||
|
||||
exports.cssLoaders = function (options) {
|
||||
options = options || {}
|
||||
|
||||
const cssLoader = {
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
const postcssLoader = {
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
// generate loader string to be used with extract text plugin
|
||||
function generateLoaders (loader, loaderOptions) {
|
||||
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
|
||||
|
||||
if (loader) {
|
||||
loaders.push({
|
||||
loader: loader + '-loader',
|
||||
options: Object.assign({}, loaderOptions, {
|
||||
sourceMap: options.sourceMap
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Extract CSS when that option is specified
|
||||
// (which is the case during production build)
|
||||
if (options.extract) {
|
||||
return ExtractTextPlugin.extract({
|
||||
use: loaders,
|
||||
fallback: 'vue-style-loader'
|
||||
})
|
||||
} else {
|
||||
return ['vue-style-loader'].concat(loaders)
|
||||
}
|
||||
}
|
||||
|
||||
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
|
||||
return {
|
||||
css: generateLoaders(),
|
||||
postcss: generateLoaders(),
|
||||
less: generateLoaders('less'),
|
||||
sass: generateLoaders('sass', { indentedSyntax: true }),
|
||||
scss: generateLoaders('sass'),
|
||||
stylus: generateLoaders('stylus'),
|
||||
styl: generateLoaders('stylus')
|
||||
}
|
||||
}
|
||||
|
||||
// Generate loaders for standalone style files (outside of .vue)
|
||||
exports.styleLoaders = function (options) {
|
||||
const output = []
|
||||
const loaders = exports.cssLoaders(options)
|
||||
|
||||
for (const extension in loaders) {
|
||||
const loader = loaders[extension]
|
||||
output.push({
|
||||
test: new RegExp('\\.' + extension + '$'),
|
||||
use: loader
|
||||
})
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
exports.createNotifierCallback = () => {
|
||||
const notifier = require('node-notifier')
|
||||
|
||||
return (severity, errors) => {
|
||||
if (severity !== 'error') return
|
||||
|
||||
const error = errors[0]
|
||||
const filename = error.file && error.file.split('!').pop()
|
||||
|
||||
notifier.notify({
|
||||
title: packageConfig.name,
|
||||
message: severity + ': ' + error.name,
|
||||
subtitle: filename || '',
|
||||
icon: path.join(__dirname, 'logo.png')
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
const sourceMapEnabled = isProduction
|
||||
? config.build.productionSourceMap
|
||||
: config.dev.cssSourceMap
|
||||
|
||||
module.exports = {
|
||||
loaders: utils.cssLoaders({
|
||||
sourceMap: sourceMapEnabled,
|
||||
extract: isProduction
|
||||
}),
|
||||
cssSourceMap: sourceMapEnabled,
|
||||
cacheBusting: config.dev.cacheBusting,
|
||||
transformToRequire: {
|
||||
video: ['src', 'poster'],
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: 'xlink:href'
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
const webpack = require('webpack')
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '..', dir)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
entry: {
|
||||
'kingbase': resolve('/src/views/kingbase.vue')
|
||||
},
|
||||
output: {
|
||||
path: resolve('/static/'),
|
||||
filename: '[name].js'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js',
|
||||
'@': resolve('src')
|
||||
}
|
||||
},
|
||||
externals: {
|
||||
vue: 'vue'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
transformAssetUrls: {
|
||||
video: 'src',
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: 'xlink:href'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /.(sa|sc|c)ss$/,
|
||||
use: [
|
||||
{loader: 'vue-style-loader'},
|
||||
'css-loader',
|
||||
'sass-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
include: [resolve('src'), resolve('test')]
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('img/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('media/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': '"production"'
|
||||
}),
|
||||
new CopyPlugin([
|
||||
{from: 'src/icons/svg/'}
|
||||
]),
|
||||
]
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const config = require('../config')
|
||||
const vueLoaderConfig = require('./vue-loader.conf')
|
||||
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '..', dir)
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
context: path.resolve(__dirname, '../'),
|
||||
entry: {
|
||||
app: './src/main.js'
|
||||
},
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: '[name].js',
|
||||
publicPath: process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsPublicPath
|
||||
: config.dev.assetsPublicPath
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js',
|
||||
'@': resolve('src'),
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderConfig
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
loader: 'svg-sprite-loader',
|
||||
include: [resolve('src/icons')],
|
||||
options: {
|
||||
symbolId: 'icon-[name]'
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
exclude: [resolve('src/icons')],
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('img/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('media/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
include: [path.resolve('src/icons')],
|
||||
use: [
|
||||
{
|
||||
loader: 'svg-sprite-loader',
|
||||
options: {
|
||||
symbolId: 'icon-[name]',
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
node: {
|
||||
// prevent webpack from injecting useless setImmediate polyfill because Vue
|
||||
// source contains it (although only uses it if it's native).
|
||||
setImmediate: false,
|
||||
// prevent webpack from injecting mocks to Node native modules
|
||||
// that does not make sense for the client
|
||||
dgram: 'empty',
|
||||
fs: 'empty',
|
||||
net: 'empty',
|
||||
tls: 'empty',
|
||||
child_process: 'empty'
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
'use strict'
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const path = require('path')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||
const portfinder = require('portfinder')
|
||||
|
||||
const HOST = process.env.HOST
|
||||
const PORT = process.env.PORT && Number(process.env.PORT)
|
||||
|
||||
const devWebpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
|
||||
},
|
||||
// cheap-module-eval-source-map is faster for development
|
||||
devtool: config.dev.devtool,
|
||||
|
||||
// these devServer options should be customized in /config/index.js
|
||||
devServer: {
|
||||
clientLogLevel: 'warning',
|
||||
historyApiFallback: {
|
||||
rewrites: [
|
||||
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
|
||||
],
|
||||
},
|
||||
hot: true,
|
||||
contentBase: false, // since we use CopyWebpackPlugin.
|
||||
compress: true,
|
||||
host: HOST || config.dev.host,
|
||||
port: PORT || config.dev.port,
|
||||
open: config.dev.autoOpenBrowser,
|
||||
overlay: config.dev.errorOverlay
|
||||
? { warnings: false, errors: true }
|
||||
: false,
|
||||
publicPath: config.dev.assetsPublicPath,
|
||||
proxy: config.dev.proxyTable,
|
||||
quiet: true, // necessary for FriendlyErrorsPlugin
|
||||
watchOptions: {
|
||||
poll: config.dev.poll,
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': require('../config/dev.env')
|
||||
}),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
// https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: 'index.html',
|
||||
template: 'index.html',
|
||||
inject: true
|
||||
}),
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.dev.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
module.exports = new Promise((resolve, reject) => {
|
||||
portfinder.basePort = process.env.PORT || config.dev.port
|
||||
portfinder.getPort((err, port) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
// publish the new Port, necessary for e2e tests
|
||||
process.env.PORT = port
|
||||
// add port to devServer config
|
||||
devWebpackConfig.devServer.port = port
|
||||
|
||||
// Add FriendlyErrorsPlugin
|
||||
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
|
||||
compilationSuccessInfo: {
|
||||
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
|
||||
},
|
||||
onErrors: config.dev.notifyOnErrors
|
||||
? utils.createNotifierCallback()
|
||||
: undefined
|
||||
}))
|
||||
|
||||
resolve(devWebpackConfig)
|
||||
}
|
||||
})
|
||||
})
|
@ -0,0 +1,145 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const utils = require('./utils')
|
||||
const webpack = require('webpack')
|
||||
const config = require('../config')
|
||||
const merge = require('webpack-merge')
|
||||
const baseWebpackConfig = require('./webpack.base.conf')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
|
||||
const env = require('../config/prod.env')
|
||||
|
||||
const webpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
extract: true,
|
||||
usePostCSS: true
|
||||
})
|
||||
},
|
||||
devtool: config.build.productionSourceMap ? config.build.devtool : false,
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: utils.assetsPath('js/[name].[chunkhash].js'),
|
||||
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
|
||||
},
|
||||
plugins: [
|
||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': env
|
||||
}),
|
||||
new UglifyJsPlugin({
|
||||
uglifyOptions: {
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
},
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
parallel: true
|
||||
}),
|
||||
// extract css into its own file
|
||||
new ExtractTextPlugin({
|
||||
filename: utils.assetsPath('css/[name].[contenthash].css'),
|
||||
// Setting the following option to `false` will not extract CSS from codesplit chunks.
|
||||
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
|
||||
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
|
||||
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
|
||||
allChunks: true,
|
||||
}),
|
||||
// Compress extracted CSS. We are using this plugin so that possible
|
||||
// duplicated CSS from different components can be deduped.
|
||||
new OptimizeCSSPlugin({
|
||||
cssProcessorOptions: config.build.productionSourceMap
|
||||
? { safe: true, map: { inline: false } }
|
||||
: { safe: true }
|
||||
}),
|
||||
// generate dist index.html with correct asset hash for caching.
|
||||
// you can customize output by editing /index.html
|
||||
// see https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: config.build.index,
|
||||
template: 'index.html',
|
||||
inject: true,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
collapseWhitespace: true,
|
||||
removeAttributeQuotes: true
|
||||
// more options:
|
||||
// https://github.com/kangax/html-minifier#options-quick-reference
|
||||
},
|
||||
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
|
||||
chunksSortMode: 'dependency'
|
||||
}),
|
||||
// keep module.id stable when vendor modules does not change
|
||||
new webpack.HashedModuleIdsPlugin(),
|
||||
// enable scope hoisting
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
// split vendor js into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'vendor',
|
||||
minChunks (module) {
|
||||
// any required modules inside node_modules are extracted to vendor
|
||||
return (
|
||||
module.resource &&
|
||||
/\.js$/.test(module.resource) &&
|
||||
module.resource.indexOf(
|
||||
path.join(__dirname, '../node_modules')
|
||||
) === 0
|
||||
)
|
||||
}
|
||||
}),
|
||||
// extract webpack runtime and module manifest to its own file in order to
|
||||
// prevent vendor hash from being updated whenever app bundle is updated
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'manifest',
|
||||
minChunks: Infinity
|
||||
}),
|
||||
// This instance extracts shared chunks from code split chunks and bundles them
|
||||
// in a separate chunk, similar to the vendor chunk
|
||||
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'app',
|
||||
async: 'vendor-async',
|
||||
children: true,
|
||||
minChunks: 3
|
||||
}),
|
||||
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.build.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
if (config.build.productionGzip) {
|
||||
const CompressionWebpackPlugin = require('compression-webpack-plugin')
|
||||
|
||||
webpackConfig.plugins.push(
|
||||
new CompressionWebpackPlugin({
|
||||
asset: '[path].gz[query]',
|
||||
algorithm: 'gzip',
|
||||
test: new RegExp(
|
||||
'\\.(' +
|
||||
config.build.productionGzipExtensions.join('|') +
|
||||
')$'
|
||||
),
|
||||
threshold: 10240,
|
||||
minRatio: 0.8
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (config.build.bundleAnalyzerReport) {
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
||||
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
|
||||
}
|
||||
|
||||
module.exports = webpackConfig
|
@ -0,0 +1,7 @@
|
||||
'use strict'
|
||||
const merge = require('webpack-merge')
|
||||
const prodEnv = require('./prod.env')
|
||||
|
||||
module.exports = merge(prodEnv, {
|
||||
NODE_ENV: '"development"'
|
||||
})
|
@ -0,0 +1,69 @@
|
||||
'use strict'
|
||||
// Template version: 1.3.1
|
||||
// see http://vuejs-templates.github.io/webpack for documentation.
|
||||
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
dev: {
|
||||
|
||||
// Paths
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
proxyTable: {},
|
||||
|
||||
// Various Dev Server settings
|
||||
host: 'localhost', // can be overwritten by process.env.HOST
|
||||
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
|
||||
autoOpenBrowser: false,
|
||||
errorOverlay: true,
|
||||
notifyOnErrors: true,
|
||||
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
|
||||
|
||||
|
||||
/**
|
||||
* Source Maps
|
||||
*/
|
||||
|
||||
// https://webpack.js.org/configuration/devtool/#development
|
||||
devtool: 'cheap-module-eval-source-map',
|
||||
|
||||
// If you have problems debugging vue-files in devtools,
|
||||
// set this to false - it *may* help
|
||||
// https://vue-loader.vuejs.org/en/options.html#cachebusting
|
||||
cacheBusting: true,
|
||||
|
||||
cssSourceMap: true
|
||||
},
|
||||
|
||||
build: {
|
||||
// Template for index.html
|
||||
index: path.resolve(__dirname, '../dist/index.html'),
|
||||
|
||||
// Paths
|
||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
|
||||
/**
|
||||
* Source Maps
|
||||
*/
|
||||
|
||||
productionSourceMap: true,
|
||||
// https://webpack.js.org/configuration/devtool/#production
|
||||
devtool: '#source-map',
|
||||
|
||||
// Gzip off by default as many popular static hosts such as
|
||||
// Surge or Netlify already gzip all static assets for you.
|
||||
// Before setting to `true`, make sure to:
|
||||
// npm install --save-dev compression-webpack-plugin
|
||||
productionGzip: false,
|
||||
productionGzipExtensions: ['js', 'css'],
|
||||
|
||||
// Run the build command with an extra argument to
|
||||
// View the bundle analyzer report after build finishes:
|
||||
// `npm run build --report`
|
||||
// Set to `true` or `false` to always turn it on or off
|
||||
bundleAnalyzerReport: process.env.npm_config_report
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
'use strict'
|
||||
module.exports = {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>deplugin-view-frontend</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "deplugin-datasource-frontend",
|
||||
"version": "1.0.0",
|
||||
"description": "A Vue.js project",
|
||||
"author": "",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
|
||||
"start": "npm run dev",
|
||||
"build": "node build/build.js",
|
||||
"buildPlugin": "node build/build-async-plugins.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@riophae/vue-treeselect": "0.4.0",
|
||||
"highcharts": "^10.0.0",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"svgo": "1.2.2",
|
||||
"svgo-loader": "^3.0.1",
|
||||
"vue": "^2.5.2",
|
||||
"vue-i18n": "7.3.2",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-uuid": "2.0.2",
|
||||
"vuedraggable": "^2.24.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^7.1.2",
|
||||
"babel-core": "^6.22.1",
|
||||
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
||||
"babel-loader": "^7.1.1",
|
||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
||||
"babel-plugin-transform-runtime": "^6.22.0",
|
||||
"babel-plugin-transform-vue-jsx": "^3.5.0",
|
||||
"babel-preset-env": "^1.3.2",
|
||||
"babel-preset-stage-2": "^6.22.0",
|
||||
"chalk": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.6.0",
|
||||
"css-loader": "^0.28.0",
|
||||
"element-ui": "2.15.7",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"file-loader": "^1.1.4",
|
||||
"friendly-errors-webpack-plugin": "^1.6.1",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"js-cookie": "2.2.0",
|
||||
"node-notifier": "^8.0.1",
|
||||
"optimize-css-assets-webpack-plugin": "^3.2.0",
|
||||
"ora": "^1.2.0",
|
||||
"portfinder": "^1.0.13",
|
||||
"postcss-import": "^11.0.0",
|
||||
"postcss-loader": "^2.0.8",
|
||||
"postcss-url": "^7.2.1",
|
||||
"rimraf": "^2.6.0",
|
||||
"sass": "^1.33.0",
|
||||
"sass-loader": "^7.3.1",
|
||||
"semver": "^5.3.0",
|
||||
"shelljs": "^0.8.5",
|
||||
"uglifyjs-webpack-plugin": "^1.1.1",
|
||||
"url-loader": "^0.5.8",
|
||||
"vue-loader": "^15.6.4",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
"vue-template-compiler": "^2.5.2",
|
||||
"webpack": "^4.8.1",
|
||||
"webpack-bundle-analyzer": "^3.3.2",
|
||||
"webpack-dev-server": "^3.1.11",
|
||||
"webpack-merge": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>io.dataease</groupId>
|
||||
<artifactId>kingbase</artifactId>
|
||||
<version>${dataease.version}</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>kingbase-frontend</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<frontend-maven-plugin.version>1.9.1</frontend-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>static</directory>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
<followSymlinks>false</followSymlinks>
|
||||
</fileset>
|
||||
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>${frontend-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install node and npm</id>
|
||||
<goals>
|
||||
<goal>install-node-and-npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- See https://nodejs.org/en/download/ for latest node and npm (lts) versions -->
|
||||
<nodeVersion>v16.20.2</nodeVersion>
|
||||
<npmVersion>7.6.3</npmVersion>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>npm install</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<!-- Optional configuration which provides for running any npm command -->
|
||||
<configuration>
|
||||
<arguments>install --force</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>npm run buildPlugin</id>
|
||||
<goals>
|
||||
<goal>npm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>run buildPlugin</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'autoprefixer': { browsers: 'last 5 version' }
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
</style>
|
After Width: | Height: | Size: 6.7 KiB |
@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<h2>Essential Links</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="https://vuejs.org"
|
||||
target="_blank"
|
||||
>
|
||||
Core Docs
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://forum.vuejs.org"
|
||||
target="_blank"
|
||||
>
|
||||
Forum
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://chat.vuejs.org"
|
||||
target="_blank"
|
||||
>
|
||||
Community Chat
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://twitter.com/vuejs"
|
||||
target="_blank"
|
||||
>
|
||||
Twitter
|
||||
</a>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<a
|
||||
href="http://vuejs-templates.github.io/webpack/"
|
||||
target="_blank"
|
||||
>
|
||||
Docs for This Template
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Ecosystem</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="http://router.vuejs.org/"
|
||||
target="_blank"
|
||||
>
|
||||
vue-router
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="http://vuex.vuejs.org/"
|
||||
target="_blank"
|
||||
>
|
||||
vuex
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="http://vue-loader.vuejs.org/"
|
||||
target="_blank"
|
||||
>
|
||||
vue-loader
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/awesome-vue"
|
||||
target="_blank"
|
||||
>
|
||||
awesome-vue
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
data () {
|
||||
return {
|
||||
msg: 'Welcome to Your Vue.js App'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h1, h2 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,31 @@
|
||||
export default {
|
||||
host: 'Host name/IP address',
|
||||
dataBase: 'Database name',
|
||||
connection_mode: 'Connection mode',
|
||||
oracle_sid: 'SID',
|
||||
oracle_service_name: 'Service name',
|
||||
username: 'User name',
|
||||
password: 'Password',
|
||||
port: 'Port',
|
||||
schema: 'Schema',
|
||||
get_schema: 'Get Schema',
|
||||
charset: 'Character set',
|
||||
targetCharset: 'Target character set',
|
||||
priority: 'Advanced settings',
|
||||
initial_pool_size: 'Initial connections',
|
||||
min_pool_size: 'Minimum connections',
|
||||
max_pool_size: 'Maximum connections',
|
||||
query_timeout: 'Query timeout',
|
||||
one_user_name: 'Please enter the user name',
|
||||
input_a_password: 'Please enter the password',
|
||||
enter_the_port: 'Please enter the port',
|
||||
please_choose_schema: 'Please select Schema',
|
||||
please_choose_charset: 'Please select the database character set',
|
||||
please_choose_targetCharset: 'Please select the target character set',
|
||||
please_input_initial_pool_size: 'Please enter the initial number of connections',
|
||||
please_input_min_pool_size: 'Please enter the minimum number of connections',
|
||||
please_input_max_pool_size: 'Please enter the maximum number of connections',
|
||||
please_input_query_timeout: 'Please enter the query timeout',
|
||||
second: 'Second',
|
||||
please_select: 'Please select'
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import Cookies from 'js-cookie'
|
||||
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
|
||||
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
|
||||
import elementTWLocale from 'element-ui/lib/locale/lang/zh-TW'// element-ui lang
|
||||
|
||||
import localMessages from './messages'
|
||||
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const messages = {
|
||||
en_US: {
|
||||
...localMessages['en_US'],
|
||||
...elementEnLocale
|
||||
},
|
||||
zh_CN: {
|
||||
...localMessages['zh_CN'],
|
||||
...elementZhLocale
|
||||
},
|
||||
zh_TW: {
|
||||
...localMessages['zh_TW'],
|
||||
...elementTWLocale
|
||||
}
|
||||
}
|
||||
export function getLanguage () {
|
||||
const chooseLanguage = Cookies.get('language')
|
||||
if (chooseLanguage) return chooseLanguage
|
||||
|
||||
// if has not choose language
|
||||
const language = (navigator.language || navigator.browserLanguage).toLowerCase()
|
||||
const locales = Object.keys(messages)
|
||||
for (const locale of locales) {
|
||||
if (language.indexOf(locale) > -1) {
|
||||
return locale
|
||||
}
|
||||
}
|
||||
return 'zh_CN'
|
||||
}
|
||||
const i18n = new VueI18n({
|
||||
// set locale
|
||||
// options: en | zh | es
|
||||
locale: getLanguage(),
|
||||
// set locale messages
|
||||
messages
|
||||
})
|
||||
|
||||
export default i18n
|
@ -0,0 +1,17 @@
|
||||
import enLocale from './en'
|
||||
import zhLocale from './zh'
|
||||
import twLocale from './tw'
|
||||
|
||||
const messages = {
|
||||
en_US: {
|
||||
...enLocale
|
||||
},
|
||||
zh_CN: {
|
||||
...zhLocale
|
||||
},
|
||||
zh_TW: {
|
||||
...twLocale
|
||||
}
|
||||
}
|
||||
|
||||
export default messages
|
@ -0,0 +1,31 @@
|
||||
export default {
|
||||
host: '主機名/IP地址',
|
||||
dataBase: '數據庫名稱',
|
||||
connection_mode: '連接方式',
|
||||
oracle_sid: 'SID',
|
||||
oracle_service_name: '服務名',
|
||||
username: '用戶名',
|
||||
password: '密碼',
|
||||
port: '端口',
|
||||
schema: 'Schema',
|
||||
get_schema: '獲取 Schema',
|
||||
charset: '字符集',
|
||||
targetCharset: '目標字符集',
|
||||
priority: '高級設置',
|
||||
initial_pool_size: '初始連接數',
|
||||
min_pool_size: '最小連接數',
|
||||
max_pool_size: '最大連接數',
|
||||
query_timeout: '查詢超時',
|
||||
one_user_name: '請輸入用戶名',
|
||||
input_a_password: '請輸入密碼',
|
||||
enter_the_port: '請輸入端口',
|
||||
please_choose_schema: '請選擇 Schema',
|
||||
please_choose_charset: '請選擇數據庫字符集',
|
||||
please_choose_targetCharset: '請選擇目標字符集',
|
||||
please_input_initial_pool_size: '請輸入初始連接數',
|
||||
please_input_min_pool_size: '請輸入最小連接數',
|
||||
please_input_max_pool_size: '請輸入最大連接數',
|
||||
please_input_query_timeout: '請輸入查詢超時',
|
||||
second: '秒',
|
||||
please_select: '請選擇'
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
export default {
|
||||
host: '主机名/IP地址',
|
||||
dataBase: '数据库名称',
|
||||
connection_mode: '连接方式',
|
||||
oracle_sid: 'SID',
|
||||
oracle_service_name: '服务名',
|
||||
username: '用户名',
|
||||
password: '密码',
|
||||
port: '端口',
|
||||
schema: 'Schema',
|
||||
get_schema: '获取 Schema',
|
||||
charset: '字符集',
|
||||
targetCharset: '目标字符集',
|
||||
priority: '高级设置',
|
||||
initial_pool_size: '初始连接数',
|
||||
min_pool_size: '最小连接数',
|
||||
max_pool_size: '最大连接数',
|
||||
query_timeout: '查询超时',
|
||||
one_user_name: '请输入用户名',
|
||||
input_a_password: '请输入密码',
|
||||
enter_the_port: '请输入端口',
|
||||
please_choose_schema: '请选择 Schema',
|
||||
please_choose_charset: '请选择数据库字符集',
|
||||
please_choose_targetCharset: '请选择目标字符集',
|
||||
please_input_initial_pool_size: '请输入初始连接数',
|
||||
please_input_min_pool_size: '请输入最小连接数',
|
||||
please_input_max_pool_size: '请输入最大连接数',
|
||||
please_input_query_timeout: '请输入查询超时',
|
||||
second: '秒',
|
||||
please_select: '请选择'
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
import Vue from 'vue'
|
||||
import SvgIcon from '@/components/SvgIcon'// svg component
|
||||
|
||||
// register globally
|
||||
Vue.component('svg-icon', SvgIcon)
|
||||
|
||||
const req = require.context('./svg', false, /\.svg$/)
|
||||
const requireAll = requireContext => requireContext.keys().map(requireContext)
|
||||
requireAll(req)
|
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.00022 9.99975C7.56203 9.99975 7.13323 9.96523 6.71734 9.89921L6.38535 11.1382C6.33771 11.316 6.15493 11.4216 5.9771 11.3739L5.33315 11.2014C5.15533 11.1537 5.0498 10.9709 5.09745 10.7931L5.42255 9.57985C4.88013 9.39561 4.37096 9.15494 3.90491 8.86629L2.8454 9.9258C2.71522 10.056 2.50417 10.056 2.37399 9.9258L1.90259 9.4544C1.77242 9.32422 1.77242 9.11317 1.90259 8.98299L2.83565 8.04994C2.35424 7.59918 1.95209 7.0852 1.64812 6.52421C1.64492 6.51832 1.64162 6.51215 1.63823 6.50575C1.5136 6.27038 1.56023 5.97574 1.75709 5.79635C1.92051 5.64743 2.03596 5.5461 2.13639 5.44567C2.14538 5.43669 2.15521 5.42666 2.16569 5.41583C2.31108 5.2656 2.55902 5.32152 2.64417 5.51246C3.47427 7.37398 5.46211 8.66641 8.00022 8.66641C10.4321 8.66641 12.4664 7.40872 13.2829 5.68239C13.3042 5.63747 13.328 5.5809 13.3519 5.52084C13.4276 5.33064 13.6741 5.27325 13.8188 5.41801C13.9259 5.52508 14.0687 5.66784 14.2471 5.8463C14.4235 6.0227 14.4713 6.29211 14.356 6.51334C14.3279 6.56715 14.3006 6.61785 14.2774 6.65816C13.9638 7.20109 13.5572 7.69751 13.0754 8.1321L13.9263 8.98299C14.0565 9.11317 14.0565 9.32422 13.9263 9.4544L13.4549 9.9258C13.3247 10.056 13.1136 10.056 12.9835 9.9258L11.9888 8.93112C11.5521 9.19111 11.0792 9.40958 10.5779 9.57985L10.903 10.7931C10.9506 10.9709 10.8451 11.1537 10.6673 11.2014L10.0233 11.3739C9.84552 11.4216 9.66274 11.316 9.61509 11.1382L9.2831 9.89921C8.86721 9.96523 8.43842 9.99975 8.00022 9.99975Z" fill="#BBBFC4"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.98994 12.333C10.1486 12.333 12.1472 10.9599 14.0001 7.99101C12.1949 5.03272 10.2008 3.66634 7.98994 3.66634C5.77984 3.66634 3.7929 5.0321 2.00009 7.99099C3.84053 10.9605 5.83206 12.333 7.98994 12.333ZM1.00172 8.59304C0.787049 8.22763 0.785596 7.77336 0.995302 7.40508C1.00277 7.39196 1.00993 7.37945 1.01672 7.36768C2.9521 4.01123 5.27627 2.33301 7.98923 2.33301C10.7133 2.33301 13.0518 4.02495 15.0049 7.40884C15.0107 7.41898 15.0168 7.42969 15.0232 7.44089C15.2208 7.7869 15.2193 8.21401 15.0172 8.55738C13.0127 11.9634 10.67 13.6663 7.98923 13.6663C5.31784 13.6663 2.98867 11.9752 1.00172 8.59304ZM8.00009 10.6663C6.52733 10.6663 5.33342 9.47243 5.33342 7.99967C5.33342 6.52692 6.52733 5.33301 8.00009 5.33301C9.47285 5.33301 10.6668 6.52692 10.6668 7.99967C10.6668 9.47243 9.47285 10.6663 8.00009 10.6663ZM8.00009 9.33301C8.73647 9.33301 9.33342 8.73605 9.33342 7.99967C9.33342 7.26329 8.73647 6.66634 8.00009 6.66634C7.26371 6.66634 6.66675 7.26329 6.66675 7.99967C6.66675 8.73605 7.26371 9.33301 8.00009 9.33301Z" fill="#BBBFC4"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{isolation:isolate;}.cls-2{fill:#f2f4f5;}.cls-3{fill:#0a7be0;}.cls-4{fill:#53baf9;}.cls-5,.cls-6{fill:#a2a2ba;}.cls-6{mix-blend-mode:multiply;}.cls-7{fill:#fff;}</style></defs><title>【icon】人大金仓</title><g class="cls-1"><g id="图层_1" data-name="图层 1"><circle class="cls-2" cx="32" cy="32" r="32"/><path class="cls-3" d="M25.76,44.82l6.79-11.56H44.4V12.36A2.36,2.36,0,0,0,42,10H13.87a2.58,2.58,0,0,0-2.58,2.57V44.7A3.68,3.68,0,0,0,15,48.37H27.84Z"/><path class="cls-4" d="M25.76,44.82,27,42.73H14.11a2.83,2.83,0,0,0-2.82,2.82h0a2.83,2.83,0,0,0,2.82,2.82H27.84Z"/><polygon class="cls-5" points="33.96 54 28.57 44.82 33.96 35.64 52.71 35.64 52.71 54 33.96 54"/><polygon class="cls-6" points="33.96 54 28.57 44.82 52.71 44.75 52.71 54 33.96 54"/><polygon class="cls-7" points="20.76 13.76 20.76 20.14 16.48 22.22 20.76 24.36 20.76 30.81 24.3 30.81 24.3 26.01 34.36 30.81 34.36 27.03 24.3 22.33 34.49 17.4 34.49 13.64 24.3 18.59 24.3 13.76 20.76 13.76"/><path class="cls-7" d="M42.9,43.06c-3,0-5.5-.76-5.5-1.7v3.39c0,.93,2.47,1.69,5.5,1.69s5.5-.76,5.5-1.69V41.36c0,.94-2.46,1.7-5.5,1.7Zm0,0"/><path class="cls-7" d="M42.9,47.29c-3,0-5.5-.76-5.5-1.7V49c0,.93,2.47,1.69,5.5,1.69s5.5-.76,5.5-1.69V45.59c0,.94-2.46,1.7-5.5,1.7Z"/><path class="cls-7" d="M42.9,42.21c3,0,5.5-.76,5.5-1.69s-2.46-1.69-5.5-1.69-5.5.75-5.5,1.69,2.47,1.69,5.5,1.69Z"/></g></g></svg>
|
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 19 KiB |
@ -0,0 +1,22 @@
|
||||
# replace default config
|
||||
|
||||
# multipass: true
|
||||
# full: true
|
||||
|
||||
plugins:
|
||||
|
||||
# - name
|
||||
#
|
||||
# or:
|
||||
# - name: false
|
||||
# - name: true
|
||||
#
|
||||
# or:
|
||||
# - name:
|
||||
# param1: 1
|
||||
# param2: 2
|
||||
|
||||
- removeAttrs:
|
||||
attrs:
|
||||
- 'fill'
|
||||
- 'fill-rule'
|
@ -0,0 +1,33 @@
|
||||
// The Vue build version to load with the `import` command
|
||||
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import router from './router'
|
||||
import ElementUI from 'element-ui'
|
||||
import Cookies from 'js-cookie'
|
||||
import i18n from './de-base/lang'
|
||||
import draggable from 'vuedraggable'
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
Vue.config.productionTip = false
|
||||
Vue.use(ElementUI, {
|
||||
size: Cookies.get('size') || 'medium',
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
})
|
||||
Vue.component('Treeselect', Treeselect)
|
||||
Vue.component('draggable', draggable)
|
||||
Vue.prototype.hasDataPermission = function(pTarget, pSource) {
|
||||
|
||||
if (pSource && pTarget) {
|
||||
return pSource.indexOf(pTarget) > -1
|
||||
}
|
||||
return false
|
||||
}
|
||||
/* eslint-disable no-new */
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
i18n,
|
||||
components: { App },
|
||||
template: '<App/>'
|
||||
})
|
@ -0,0 +1,21 @@
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import HelloWorld from '@/components/HelloWorld'
|
||||
import kingbase from '@/views/kingbase'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'HelloWorld',
|
||||
component: HelloWorld
|
||||
},
|
||||
{
|
||||
path: '/kingbase',
|
||||
name: 'kingbase',
|
||||
component: kingbase
|
||||
}
|
||||
]
|
||||
})
|
@ -0,0 +1,29 @@
|
||||
export const compareItem = {
|
||||
type: 'none', // year-yoy/month-yoy等
|
||||
resultData: 'percent', // 对比差sub,百分比percent等
|
||||
field: '',
|
||||
custom: {
|
||||
field: '',
|
||||
calcType: '0', // 0-增长值,1-增长率
|
||||
timeType: '0', // 0-固定日期,1-日期区间
|
||||
currentTime: '',
|
||||
compareTime: '',
|
||||
currentTimeRange: [],
|
||||
compareTimeRange: []
|
||||
}
|
||||
}
|
||||
|
||||
export const compareYearList = [
|
||||
{ name: 'year_mom', value: 'year_mom' }
|
||||
]
|
||||
|
||||
export const compareMonthList = [
|
||||
{ name: 'month_mom', value: 'month_mom' },
|
||||
{ name: 'year_yoy', value: 'year_yoy' }
|
||||
]
|
||||
|
||||
export const compareDayList = [
|
||||
{ name: 'day_mom', value: 'day_mom' },
|
||||
{ name: 'month_yoy', value: 'month_yoy' },
|
||||
{ name: 'year_yoy', value: 'year_yoy' }
|
||||
]
|
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Created by PanJiaChen on 16/11/18.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path) || /^(http?:|mailto:|tel:)/.test(path) || path.startsWith('/api/pluginCommon/staticInfo')
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<el-input
|
||||
:value="value"
|
||||
:placeholder="placeholder"
|
||||
:type="type"
|
||||
:disabled="disabled"
|
||||
class="de-pwd-input"
|
||||
@input="handleInput"
|
||||
@change="handleChange"
|
||||
>
|
||||
<svg-icon
|
||||
@click="handleClick"
|
||||
v-if="!showPwd || buttonDisabled"
|
||||
slot="suffix"
|
||||
icon-class="de_pwd_invisible"
|
||||
/>
|
||||
<svg-icon
|
||||
@click="handleClick"
|
||||
v-else
|
||||
slot="suffix"
|
||||
icon-class="de_pwd_visible"
|
||||
/>
|
||||
</el-input>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "DePwd",
|
||||
inject: {
|
||||
elForm: {
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
props: {
|
||||
disabled: Boolean,
|
||||
placeholder: String,
|
||||
value: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showPwd: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
buttonDisabled() {
|
||||
return this.$options.propsData.hasOwnProperty("disabled")
|
||||
? this.disabled
|
||||
: (this.elForm || {}).disabled;
|
||||
},
|
||||
type() {
|
||||
return !this.showPwd || this.buttonDisabled ? "password" : "text";
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
if (this.buttonDisabled) return;
|
||||
this.showPwd = !this.showPwd;
|
||||
},
|
||||
handleInput(val) {
|
||||
this.$emit("input", val);
|
||||
},
|
||||
handleChange(val) {
|
||||
this.$emit("change", val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.de-pwd-input {
|
||||
.el-input__suffix {
|
||||
right: 12px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,202 @@
|
||||
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col>
|
||||
|
||||
<el-form
|
||||
ref="DsForm"
|
||||
:model="form"
|
||||
:rules="rule"
|
||||
size="small"
|
||||
:disabled="disabled"
|
||||
label-width="180px"
|
||||
label-position="right"
|
||||
>
|
||||
<el-form-item :label="$t('host')" prop="configuration.host">
|
||||
<el-input v-model="form.configuration.host" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('port')" prop="configuration.port">
|
||||
<el-input :placeholder="$t('enter_the_port')" v-model="form.configuration.port" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('dataBase')" prop="configuration.dataBase">
|
||||
<el-input v-model="form.configuration.dataBase" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('username')" prop="configuration.username">
|
||||
<el-input :placeholder="$t('one_user_name')" v-model="form.configuration.username" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('password')" prop="configuration.password">
|
||||
<dePwd :placeholder="$t('input_a_password')" v-model="form.configuration.password"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="schema-label" :label="$t('schema')">
|
||||
<template slot="label">
|
||||
{{ $t("schema") }}
|
||||
<el-button type="text" icon="el-icon-plus" size="small" @click="getSchema()">{{ $t('get_schema') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<el-select v-model="form.configuration.schema" filterable
|
||||
:placeholder="$t('please_select')"
|
||||
class="de-select">
|
||||
<el-option v-for="item in schemas" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('query_timeout')">
|
||||
<el-input
|
||||
v-model="form.configuration.queryTimeout"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
:min="0"
|
||||
>
|
||||
<template slot="append">{{ $t("second") }}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import messages from '@/de-base/lang/messages'
|
||||
import dePwd from "./dePwd.vue";
|
||||
|
||||
export default {
|
||||
name: "kingbase",
|
||||
components: {dePwd},
|
||||
props: {
|
||||
method: String,
|
||||
request: {},
|
||||
response: {},
|
||||
editApiItem: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
showScript: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
obj: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
configuration: {
|
||||
initialPoolSize: 5,
|
||||
extraParams: '',
|
||||
minPoolSize: 5,
|
||||
maxPoolSize: 50,
|
||||
maxIdleTime: 30,
|
||||
acquireIncrement: 5,
|
||||
idleConnectionTestPeriod: 5,
|
||||
queryTimeout: 30,
|
||||
connectTimeout: 5
|
||||
},
|
||||
apiConfiguration: []
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
rule: {
|
||||
'configuration.host': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}],
|
||||
'configuration.port': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}],
|
||||
'configuration.dataBase': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}],
|
||||
'configuration.username': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}],
|
||||
'configuration.password': [{required: true, message: this.$t('commons.required'), trigger: 'blur'}]
|
||||
},
|
||||
canEdit: false,
|
||||
originConfiguration: {},
|
||||
height: 500,
|
||||
disabledNext: false,
|
||||
schemas: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
form() {
|
||||
return this.obj.form
|
||||
},
|
||||
disabled() {
|
||||
return this.obj.disabled
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$emit('on-add-languages', messages)
|
||||
},
|
||||
watch: {},
|
||||
methods: {
|
||||
executeAxios(url, type, data, callBack) {
|
||||
const param = {
|
||||
url: url,
|
||||
type: type,
|
||||
data: data,
|
||||
callBack: callBack
|
||||
}
|
||||
this.$emit('execute-axios', param)
|
||||
},
|
||||
getSchema() {
|
||||
this.$refs["DsForm"].validate(valid => {
|
||||
if (valid) {
|
||||
const data = JSON.parse(JSON.stringify(this.form))
|
||||
data.configuration = JSON.stringify(data.configuration)
|
||||
this.executeAxios('/datasource/getSchema/', 'post', data, res => {
|
||||
this.schemas = res.data
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
validate() {
|
||||
let status = null;
|
||||
this.$refs["DsForm"].validate((val) => {
|
||||
if (val) {
|
||||
status = true
|
||||
} else {
|
||||
status = false
|
||||
}
|
||||
})
|
||||
|
||||
if (!this.form.configuration.schema) {
|
||||
this.$message.error(this.$t('please_choose_schema'))
|
||||
status = false
|
||||
}
|
||||
return status
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-query {
|
||||
background: #409EFF;
|
||||
color: white;
|
||||
height: 18px;
|
||||
border-radius: 42%;
|
||||
}
|
||||
|
||||
.ms-header {
|
||||
background: #409EFF;
|
||||
color: white;
|
||||
height: 18px;
|
||||
border-radius: 42%;
|
||||
}
|
||||
|
||||
.request-tabs {
|
||||
margin: 20px;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.ms-el-link {
|
||||
float: right;
|
||||
margin-right: 45px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name":"kingbase-ora 数据源插件",
|
||||
"free":0,
|
||||
"store":"default",
|
||||
"cost":0,
|
||||
"category":"datasource",
|
||||
"descript":"人大金仓插件,值得拥有",
|
||||
"version":"1.18.0",
|
||||
"creator":"DATAEASE",
|
||||
"moduleName":"kingbase-backend",
|
||||
"require":"1.17.0",
|
||||
"dsType":"kingbase"
|
||||
}
|
19
extensions/dataease-extensions-datasource/kingbase/pom.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>dataease-extensions-datasource</artifactId>
|
||||
<groupId>io.dataease</groupId>
|
||||
<version>${dataease.version}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>kingbase</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>kingbase-frontend</module>
|
||||
<module>kingbase-backend</module>
|
||||
</modules>
|
||||
|
||||
</project>
|