提交 a5dd1e36 authored 作者: taojinlong's avatar taojinlong

feat: sqlserver

上级 4ec3cdb6
package io.dataease.commons.constants;
public class DeTypeConstants {
public final static Integer DE_STRING = 0;
public final static Integer DE_TIME = 1;
public final static Integer DE_INT = 2;
public final static Integer DE_FLOAT = 3;
public final static Integer DE_BOOL = 4;
public final static Integer DE_Binary = 5;
}
......@@ -68,7 +68,6 @@ public class SqlFilter implements Filter {
}
br.close();
} catch (IOException e) {
System.out.println("IOException: " + e);
}
return str;
......
......@@ -32,7 +32,6 @@ public class LicenseController {
return ResultHolder.success(null);
}
F2CLicenseResponse f2CLicenseResponse = defaultLicenseService.validateLicense();
System.out.println(new Gson().toJson(f2CLicenseResponse));
switch (f2CLicenseResponse.getStatus()) {
case no_record:
return ResultHolder.success(f2CLicenseResponse);
......
......@@ -42,25 +42,20 @@ public class JdbcProvider extends DatasourceProvider {
public List<String[]> getData(DatasourceRequest dsr) throws Exception {
List<String[]> list = new LinkedList<>();
Connection connection = null;
connection = getConnectionFromPool(dsr);
Statement stat = connection.createStatement();
ResultSet rs = stat.executeQuery(dsr.getQuery());
System.out.println(rs == null);
list = fetchResult(rs);
// try {
// connection = getConnectionFromPool(dsr);
// Statement stat = connection.createStatement();
// ResultSet rs = stat.executeQuery(dsr.getQuery());
// list = fetchResult(rs);
// } catch (SQLException e) {
// DataEaseException.throwException(e);
// } catch (Exception e) {
// DataEaseException.throwException(e);
// } finally {
// if(connection != null){
// connection.close();
// }
// }
try {
connection = getConnectionFromPool(dsr);
Statement stat = connection.createStatement();
ResultSet rs = stat.executeQuery(dsr.getQuery());
list = fetchResult(rs);
} catch (SQLException e) {
DataEaseException.throwException(e);
} catch (Exception e) {
DataEaseException.throwException(e);
} finally {
if(connection != null){
connection.close();
}
}
return list;
}
......@@ -107,12 +102,10 @@ public class JdbcProvider extends DatasourceProvider {
List<String[]> list = new LinkedList<>();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
System.out.println("columnCount: " + columnCount);
while (rs.next()) {
String[] row = new String[columnCount];
for (int j = 0; j < columnCount; j++) {
int columType = metaData.getColumnType(j + 1);
switch (columType) {
case Types.DATE:
if(rs.getDate(j + 1) != null){
......@@ -123,7 +116,6 @@ public class JdbcProvider extends DatasourceProvider {
row[j] = rs.getString(j + 1);
break;
}
System.out.println(j + " " + columType + " " + row[j]);
}
list.add(row);
}
......
package io.dataease.provider;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.base.domain.Datasource;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.dto.chart.ChartCustomFilterDTO;
import io.dataease.dto.chart.ChartViewFieldDTO;
......@@ -12,17 +13,18 @@ import java.util.List;
* @Date 2021/5/17 2:42 下午
*/
public abstract class QueryProvider {
public abstract Integer transFieldType(String field);
public abstract String createSQLPreview(String sql, String orderBy);
public abstract String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup);
public abstract String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup, Datasource ds);
public abstract String createQuerySQLAsTmp(String sql, List<DatasetTableField> fields, boolean isGroup);
public abstract String createQuerySQLWithPage(String table, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup);
public abstract String createQuerySQLWithPage(String table, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds);
public abstract String createQueryTableWithLimit(String table, List<DatasetTableField> fields, Integer limit, boolean isGroup);
public abstract String createQueryTableWithLimit(String table, List<DatasetTableField> fields, Integer limit, boolean isGroup, Datasource ds);
public abstract String createQuerySqlWithLimit(String sql, List<DatasetTableField> fields, Integer limit, boolean isGroup);
......
......@@ -2,6 +2,7 @@ package io.dataease.provider.doris;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.base.domain.DatasetTableFieldExample;
import io.dataease.base.domain.Datasource;
import io.dataease.base.mapper.DatasetTableFieldMapper;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.dto.chart.ChartCustomFilterDTO;
......@@ -76,7 +77,7 @@ public class DorisQueryProvider extends QueryProvider {
}
@Override
public String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup) {
public String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup, Datasource ds) {
SQLObj tableObj = SQLObj.builder()
.tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(DorisConstants.KEYWORD_TABLE, table))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 0))
......@@ -149,17 +150,17 @@ public class DorisQueryProvider extends QueryProvider {
@Override
public String createQuerySQLAsTmp(String sql, List<DatasetTableField> fields, boolean isGroup) {
return createQuerySQL("(" + sql + ")", fields, isGroup);
return createQuerySQL("(" + sql + ")", fields, isGroup, null);
}
@Override
public String createQuerySQLWithPage(String table, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup) {
return createQuerySQL(table, fields, isGroup) + " LIMIT " + (page - 1) * pageSize + "," + realSize;
public String createQuerySQLWithPage(String table, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds) {
return createQuerySQL(table, fields, isGroup, null) + " LIMIT " + (page - 1) * pageSize + "," + realSize;
}
@Override
public String createQueryTableWithLimit(String table, List<DatasetTableField> fields, Integer limit, boolean isGroup) {
return createQuerySQL(table, fields, isGroup) + " LIMIT 0," + limit;
public String createQueryTableWithLimit(String table, List<DatasetTableField> fields, Integer limit, boolean isGroup, Datasource ds) {
return createQuerySQL(table, fields, isGroup, null) + " LIMIT 0," + limit;
}
@Override
......
......@@ -2,6 +2,7 @@ package io.dataease.provider.mysql;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.base.domain.DatasetTableFieldExample;
import io.dataease.base.domain.Datasource;
import io.dataease.base.mapper.DatasetTableFieldMapper;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.dto.chart.ChartCustomFilterDTO;
......@@ -76,7 +77,7 @@ public class MysqlQueryProvider extends QueryProvider {
}
@Override
public String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup) {
public String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup, Datasource ds) {
SQLObj tableObj = SQLObj.builder()
.tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(MySQLConstants.KEYWORD_TABLE, table))
.tableAlias(String.format(TABLE_ALIAS_PREFIX, 0))
......@@ -140,17 +141,17 @@ public class MysqlQueryProvider extends QueryProvider {
@Override
public String createQuerySQLAsTmp(String sql, List<DatasetTableField> fields, boolean isGroup) {
return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup);
return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null);
}
@Override
public String createQuerySQLWithPage(String table, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup) {
return createQuerySQL(table, fields, isGroup) + " LIMIT " + (page - 1) * pageSize + "," + realSize;
public String createQuerySQLWithPage(String table, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds) {
return createQuerySQL(table, fields, isGroup, null) + " LIMIT " + (page - 1) * pageSize + "," + realSize;
}
@Override
public String createQueryTableWithLimit(String table, List<DatasetTableField> fields, Integer limit, boolean isGroup) {
return createQuerySQL(table, fields, isGroup) + " LIMIT 0," + limit;
public String createQueryTableWithLimit(String table, List<DatasetTableField> fields, Integer limit, boolean isGroup, Datasource ds) {
return createQuerySQL(table, fields, isGroup, null) + " LIMIT 0," + limit;
}
@Override
......
......@@ -2,6 +2,7 @@ package io.dataease.provider.oracle;
import io.dataease.base.domain.DatasetTableField;
import io.dataease.base.domain.DatasetTableFieldExample;
import io.dataease.base.domain.Datasource;
import io.dataease.base.mapper.DatasetTableFieldMapper;
import io.dataease.controller.request.chart.ChartExtFilterRequest;
import io.dataease.dto.chart.ChartCustomFilterDTO;
......@@ -88,7 +89,7 @@ public class OracleQueryProvider extends QueryProvider {
}
@Override
public String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup) {
public String createQuerySQL(String table, List<DatasetTableField> fields, boolean isGroup, Datasource ds) {
SQLObj tableObj = SQLObj.builder()
.tableName((table.startsWith("(") && table.endsWith(")")) ? table : String.format(OracleConstants.KEYWORD_TABLE, table))
.tableAlias(String.format(OracleConstants.ALIAS_FIX, String.format(TABLE_ALIAS_PREFIX, 0)))
......@@ -169,19 +170,19 @@ public class OracleQueryProvider extends QueryProvider {
@Override
public String createQuerySQLAsTmp(String sql, List<DatasetTableField> fields, boolean isGroup) {
return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup);
return createQuerySQL("(" + sqlFix(sql) + ")", fields, isGroup, null);
}
@Override
public String createQuerySQLWithPage(String table, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup) {
public String createQuerySQLWithPage(String table, List<DatasetTableField> fields, Integer page, Integer pageSize, Integer realSize, boolean isGroup, Datasource ds) {
List<SQLObj> xFields = xFields(table, fields);
return MessageFormat.format("SELECT {0} FROM ( SELECT DE_TMP.*, rownum r FROM ( {1} ) DE_TMP WHERE rownum <= {2} ) WHERE r > {3} ",
sqlColumn(xFields), createQuerySQL(table, fields, isGroup), Integer.valueOf(page * realSize).toString(), Integer.valueOf((page - 1) * pageSize).toString());
sqlColumn(xFields), createQuerySQL(table, fields, isGroup, null), Integer.valueOf(page * realSize).toString(), Integer.valueOf((page - 1) * pageSize).toString());
}
@Override
public String createQueryTableWithLimit(String table, List<DatasetTableField> fields, Integer limit, boolean isGroup) {
public String createQueryTableWithLimit(String table, List<DatasetTableField> fields, Integer limit, boolean isGroup, Datasource ds) {
return String.format("SELECT %s.* from %s WHERE rownum <= %s ", table, table, limit.toString());
}
......
......@@ -13,7 +13,7 @@ public class SqlServerSQLConstants extends SQLConstants {
public static final String KEYWORD_FIX = "%s." + sqlServer.getKeywordPrefix() + "%s" + sqlServer.getKeywordSuffix();
public static final String UNIX_TIMESTAMP = "(CAST(DATEDIFF(SS, '1970-01-01 00:00:00', s ) as bigint) - 8 * 3600 ) * 1000";
public static final String UNIX_TIMESTAMP = "CAST(DATEDIFF(ss,'1970-01-01 08:00:00', %s) as bigint ) * 1000 ";
public static final String DATE_FORMAT = "CONVERT(varchar(100), %s, %s)";
......@@ -22,9 +22,8 @@ public class SqlServerSQLConstants extends SQLConstants {
public static final String CONVERT = "CONVERT(%s, %s)";
public static final String LONG_TO_DATE = "DATEADD(second,%s,'1970-01-01 08:00:00')";
public static final String STRING_TO_DATE = "CONVERT(datetime, %s ,120)";
public static final String DEFAULT_DATE_FORMAT = "%Y-%m-%d %H:%i:%S";
public static final String STRING_TO_DATE = "CONVERT(datetime, %s ,120)";
public static final String DEFAULT_INT_FORMAT = "DECIMAL(20,0)";
......
......@@ -377,8 +377,7 @@ public class DataSetTableService {
datasourceRequest.setDatasource(ds);
String table = dataTableInfoDTO.getTable();
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false));
System.out.println(datasourceRequest.getQuery());
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false, ds));
map.put("sql", datasourceRequest.getQuery());
try {
data.addAll(datasourceProvider.getData(datasourceRequest));
......@@ -387,7 +386,7 @@ public class DataSetTableService {
DEException.throwException(e.getMessage());
}
try {
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false));
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false, ds));
dataSetPreviewPage.setTotal(datasourceProvider.getData(datasourceRequest).size());
} catch (Exception e) {
e.printStackTrace();
......@@ -404,7 +403,7 @@ public class DataSetTableService {
datasourceRequest.setDatasource(ds);
String table = DorisTableUtils.dorisName(dataSetTableRequest.getId());
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false));
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false, ds));
map.put("sql", datasourceRequest.getQuery());
try {
data.addAll(jdbcProvider.getData(datasourceRequest));
......@@ -413,7 +412,7 @@ public class DataSetTableService {
DEException.throwException(e.getMessage());
}
try {
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false));
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false, ds));
dataSetPreviewPage.setTotal(jdbcProvider.getData(datasourceRequest).size());
} catch (Exception e) {
e.printStackTrace();
......@@ -459,7 +458,7 @@ public class DataSetTableService {
datasourceRequest.setDatasource(ds);
String table = DorisTableUtils.dorisName(dataSetTableRequest.getId());
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false));
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false, ds));
map.put("sql", datasourceRequest.getQuery());
try {
data.addAll(jdbcProvider.getData(datasourceRequest));
......@@ -468,7 +467,7 @@ public class DataSetTableService {
DEException.throwException(e.getMessage());
}
try {
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false));
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false, ds));
dataSetPreviewPage.setTotal(jdbcProvider.getData(datasourceRequest).size());
} catch (Exception e) {
e.printStackTrace();
......@@ -486,7 +485,7 @@ public class DataSetTableService {
datasourceRequest.setDatasource(ds);
String table = DorisTableUtils.dorisName(dataSetTableRequest.getId());
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false));
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false, ds));
map.put("sql", datasourceRequest.getQuery());
try {
data.addAll(jdbcProvider.getData(datasourceRequest));
......@@ -495,7 +494,7 @@ public class DataSetTableService {
DEException.throwException(e.getMessage());
}
try {
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false));
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false, ds));
dataSetPreviewPage.setTotal(jdbcProvider.getData(datasourceRequest).size());
} catch (Exception e) {
e.printStackTrace();
......@@ -538,7 +537,7 @@ public class DataSetTableService {
datasourceRequest.setDatasource(ds);
String table = DorisTableUtils.dorisName(dataSetTableRequest.getId());
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false));
datasourceRequest.setQuery(qp.createQuerySQLWithPage(table, fields, page, pageSize, realSize, false, ds));
map.put("sql", datasourceRequest.getQuery());
try {
data.addAll(jdbcProvider.getData(datasourceRequest));
......@@ -548,7 +547,7 @@ public class DataSetTableService {
}
try {
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false));
datasourceRequest.setQuery(qp.createQueryTableWithLimit(table, fields, Integer.valueOf(dataSetTableRequest.getRow()), false, ds));
dataSetPreviewPage.setTotal(jdbcProvider.getData(datasourceRequest).size());
} catch (Exception e) {
e.printStackTrace();
......
......@@ -865,7 +865,7 @@ public class ExtractDataService {
textFileOutputMeta.setSeparator(separator);
textFileOutputMeta.setExtension(extention);
if (datasource.getType().equalsIgnoreCase(DatasourceTypes.oracle.name())) {
if (datasource.getType().equalsIgnoreCase(DatasourceTypes.oracle.name()) ) {
TextFileField[] outputFields = new TextFileField[datasetTableFields.size() + 1];
for(int i=0;i< datasetTableFields.size();i++){
TextFileField textFileField = new TextFileField();
......@@ -878,6 +878,20 @@ public class ExtractDataService {
textFileField.setType("String");
outputFields[datasetTableFields.size()] = textFileField;
textFileOutputMeta.setOutputFields(outputFields);
}else if (datasource.getType().equalsIgnoreCase(DatasourceTypes.sqlServer.name())){
TextFileField[] outputFields = new TextFileField[datasetTableFields.size() + 1];
for(int i=0;i< datasetTableFields.size();i++){
TextFileField textFileField = new TextFileField();
textFileField.setName(datasetTableFields.get(i).getDataeaseName());
textFileField.setType("String");
outputFields[i] = textFileField;
}
TextFileField textFileField = new TextFileField();
textFileField.setName("dataease_uuid");
textFileField.setType("String");
outputFields[datasetTableFields.size()] = textFileField;
textFileOutputMeta.setOutputFields(outputFields);
}else {
textFileOutputMeta.setOutputFields(new TextFileField[0]);
......@@ -891,6 +905,14 @@ public class ExtractDataService {
private StepMeta udjc(List<DatasetTableField> datasetTableFields, DatasourceTypes datasourceType) {
String needToChangeColumnType = "";
String handleBinaryTypeCode = "";
for (DatasetTableField datasetTableField : datasetTableFields) {
if(datasetTableField.getDeExtractType() == 5){
handleBinaryTypeCode = handleBinaryTypeCode + "\n" + this.handleBinaryType.replace("FEILD", datasetTableField.getDataeaseName());
}
}
UserDefinedJavaClassMeta userDefinedJavaClassMeta = new UserDefinedJavaClassMeta();
List<UserDefinedJavaClassMeta.FieldInfo> fields = new ArrayList<>();
UserDefinedJavaClassMeta.FieldInfo fieldInfo = new UserDefinedJavaClassMeta.FieldInfo("dataease_uuid", ValueMetaInterface.TYPE_STRING, -1, -1);
......@@ -906,11 +928,15 @@ public class ExtractDataService {
} else {
Column_Fields = String.join(",", datasetTableFields.stream().map(DatasetTableField::getDataeaseName).collect(Collectors.toList()));
}
if (datasourceType.equals(DatasourceTypes.excel)) {
tmp_code = tmp_code.replace("handleExcelIntColumn", handleExcelIntColumn).replace("Column_Fields", Column_Fields);
} else {
tmp_code = tmp_code.replace("handleExcelIntColumn", "").replace("Column_Fields", Column_Fields);
}
tmp_code = tmp_code.replace("handleBinaryType", handleBinaryTypeCode);
UserDefinedJavaClassDef userDefinedJavaClassDef = new UserDefinedJavaClassDef(UserDefinedJavaClassDef.ClassType.TRANSFORM_CLASS, "Processor", tmp_code);
userDefinedJavaClassDef.setActive(true);
......@@ -993,6 +1019,12 @@ public class ExtractDataService {
}
}
private static String handleBinaryType = " \t\tif(\"FEILD\".equalsIgnoreCase(filed)){\n" +
" get(Fields.Out, filed).setValue(r, \"\");\n" +
" get(Fields.Out, filed).getValueMeta().setType(2);\n" +
" \t}";
private static String alterColumnTypeCode = " if(\"FILED\".equalsIgnoreCase(filed)){\n" +
"\t if(tmp != null && tmp.equalsIgnoreCase(\"Y\")){\n" +
" get(Fields.Out, filed).setValue(r, 1);\n" +
......@@ -1049,6 +1081,7 @@ public class ExtractDataService {
" String tmp = get(Fields.In, filed).getString(r);\n" +
"handleWraps \n" +
"alterColumnTypeCode \n" +
"handleBinaryType \n" +
"handleExcelIntColumn \n" +
" str = str + tmp;\n" +
" }\n" +
......
......@@ -67,7 +67,7 @@ public class DirectFieldService implements DataSetFieldService {
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "db")) {
datasourceRequest.setTable(dataTableInfoDTO.getTable());
datasourceRequest.setQuery(qp.createQuerySQL(dataTableInfoDTO.getTable(), Collections.singletonList(field), true));
datasourceRequest.setQuery(qp.createQuerySQL(dataTableInfoDTO.getTable(), Collections.singletonList(field), true, ds));
} else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql")) {
datasourceRequest.setQuery(qp.createQuerySQLAsTmp(dataTableInfoDTO.getSql(), Collections.singletonList(field), true));
} else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "custom")) {
......@@ -85,7 +85,7 @@ public class DirectFieldService implements DataSetFieldService {
tableName = "ds_" + datasetTable.getId().replaceAll("-", "_");
datasourceRequest.setTable(tableName);
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
datasourceRequest.setQuery(qp.createQuerySQL(tableName, Collections.singletonList(field), true));
datasourceRequest.setQuery(qp.createQuerySQL(tableName, Collections.singletonList(field), true, null));
}
try {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论