forked from github/dataease
Merge branch 'dev-v2' into pr@dev-v2@perf_share
This commit is contained in:
commit
273c8ae275
@ -104,7 +104,7 @@ public class CopilotManage {
|
|||||||
Map<Long, DatasourceSchemaDTO> dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
Map<Long, DatasourceSchemaDTO> dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||||
if (crossDs) {
|
if (crossDs) {
|
||||||
DEException.throwException("跨源数据集不支持该功能");
|
DEException.throwException(Translator.get("i18n_copilot_cross_ds_error"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用copilot service 获取SQL和chart struct,将返回SQL中表名替换成数据集SQL
|
// 调用copilot service 获取SQL和chart struct,将返回SQL中表名替换成数据集SQL
|
||||||
@ -302,7 +302,7 @@ public class CopilotManage {
|
|||||||
if (StringUtils.equalsIgnoreCase(receiveDTO.getChart().getType(), "pie")) {
|
if (StringUtils.equalsIgnoreCase(receiveDTO.getChart().getType(), "pie")) {
|
||||||
AxisFieldDTO column = receiveDTO.getChart().getColumn();
|
AxisFieldDTO column = receiveDTO.getChart().getColumn();
|
||||||
if (fields.size() != 2 || column == null) {
|
if (fields.size() != 2 || column == null) {
|
||||||
DEException.throwException("当前字段不足以构建饼图: " + JsonUtil.toJSONString(receiveDTO));
|
DEException.throwException("build pie error: " + JsonUtil.toJSONString(receiveDTO));
|
||||||
}
|
}
|
||||||
AxisDTO axisDTO = new AxisDTO();
|
AxisDTO axisDTO = new AxisDTO();
|
||||||
AxisFieldDTO x = new AxisFieldDTO();
|
AxisFieldDTO x = new AxisFieldDTO();
|
||||||
@ -318,7 +318,7 @@ public class CopilotManage {
|
|||||||
y.setName(column.getName());
|
y.setName(column.getName());
|
||||||
y.setValue(column.getValue());
|
y.setValue(column.getValue());
|
||||||
} else {
|
} else {
|
||||||
DEException.throwException("当前字段不足以构建饼图: " + JsonUtil.toJSONString(receiveDTO));
|
DEException.throwException("build pie error: " + JsonUtil.toJSONString(receiveDTO));
|
||||||
}
|
}
|
||||||
axisDTO.setX(x);
|
axisDTO.setX(x);
|
||||||
axisDTO.setY(y);
|
axisDTO.setY(y);
|
||||||
|
@ -15,6 +15,7 @@ import io.dataease.api.ds.vo.ExcelSheetData;
|
|||||||
import io.dataease.datasource.dao.auto.entity.CoreDatasource;
|
import io.dataease.datasource.dao.auto.entity.CoreDatasource;
|
||||||
import io.dataease.exception.DEException;
|
import io.dataease.exception.DEException;
|
||||||
import io.dataease.extensions.datasource.dto.DatasetTableDTO;
|
import io.dataease.extensions.datasource.dto.DatasetTableDTO;
|
||||||
|
import io.dataease.extensions.datasource.dto.DatasourceDTO;
|
||||||
import io.dataease.extensions.datasource.dto.DatasourceRequest;
|
import io.dataease.extensions.datasource.dto.DatasourceRequest;
|
||||||
import io.dataease.extensions.datasource.dto.TableField;
|
import io.dataease.extensions.datasource.dto.TableField;
|
||||||
import io.dataease.utils.AuthUtils;
|
import io.dataease.utils.AuthUtils;
|
||||||
@ -40,6 +41,21 @@ public class ExcelUtils {
|
|||||||
private static TypeReference<List<TableField>> TableFieldListTypeReference = new TypeReference<List<TableField>>() {
|
private static TypeReference<List<TableField>> TableFieldListTypeReference = new TypeReference<List<TableField>>() {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static TypeReference<List<ExcelSheetData>> sheets = new TypeReference<List<ExcelSheetData>>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void mergeSheets(CoreDatasource requestDatasource, DatasourceDTO sourceData) {
|
||||||
|
List<ExcelSheetData> newSheets = JsonUtil.parseList(requestDatasource.getConfiguration(), sheets);
|
||||||
|
List<String> tableNames = newSheets.stream().map(ExcelSheetData::getDeTableName).collect(Collectors.toList());
|
||||||
|
List<ExcelSheetData> oldSheets = JsonUtil.parseList(sourceData.getConfiguration(), sheets);
|
||||||
|
for (ExcelSheetData oldSheet : oldSheets) {
|
||||||
|
if (!tableNames.contains(oldSheet.getDeTableName())) {
|
||||||
|
newSheets.add(oldSheet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requestDatasource.setConfiguration(JsonUtil.toJSONString(newSheets).toString());
|
||||||
|
}
|
||||||
|
|
||||||
public static List<DatasetTableDTO> getTables(DatasourceRequest datasourceRequest) throws DEException {
|
public static List<DatasetTableDTO> getTables(DatasourceRequest datasourceRequest) throws DEException {
|
||||||
List<DatasetTableDTO> tableDescs = new ArrayList<>();
|
List<DatasetTableDTO> tableDescs = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
|
@ -404,7 +404,7 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
List<String> tables = ExcelUtils.getTables(datasourceRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList());
|
List<String> tables = ExcelUtils.getTables(datasourceRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList());
|
||||||
if (dataSourceDTO.getEditType() == 0) {
|
if (dataSourceDTO.getEditType() == 0) {
|
||||||
toCreateTables = tables;
|
toCreateTables = tables;
|
||||||
toDeleteTables = sourceTables;
|
toDeleteTables = sourceTables.stream().filter(s -> tables.contains(s)).collect(Collectors.toList());
|
||||||
for (String deleteTable : toDeleteTables) {
|
for (String deleteTable : toDeleteTables) {
|
||||||
try {
|
try {
|
||||||
datasourceSyncManage.dropEngineTable(deleteTable);
|
datasourceSyncManage.dropEngineTable(deleteTable);
|
||||||
@ -422,6 +422,7 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
}
|
}
|
||||||
datasourceSyncManage.extractExcelData(requestDatasource, "all_scope");
|
datasourceSyncManage.extractExcelData(requestDatasource, "all_scope");
|
||||||
dataSourceManage.checkName(dataSourceDTO);
|
dataSourceManage.checkName(dataSourceDTO);
|
||||||
|
ExcelUtils.mergeSheets(requestDatasource, sourceData);
|
||||||
dataSourceManage.innerEdit(requestDatasource);
|
dataSourceManage.innerEdit(requestDatasource);
|
||||||
} else {
|
} else {
|
||||||
datasourceSyncManage.extractExcelData(requestDatasource, "add_scope");
|
datasourceSyncManage.extractExcelData(requestDatasource, "add_scope");
|
||||||
@ -735,11 +736,15 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Integer replace = 0;
|
||||||
|
private static final Integer append = 1;
|
||||||
|
|
||||||
public ExcelFileData excelUpload(@RequestParam("file") MultipartFile file, @RequestParam("id") long datasourceId, @RequestParam("editType") Integer editType) throws DEException {
|
public ExcelFileData excelUpload(@RequestParam("file") MultipartFile file, @RequestParam("id") long datasourceId, @RequestParam("editType") Integer editType) throws DEException {
|
||||||
|
CoreDatasource coreDatasource = datasourceMapper.selectById(datasourceId);
|
||||||
|
|
||||||
ExcelUtils excelUtils = new ExcelUtils();
|
ExcelUtils excelUtils = new ExcelUtils();
|
||||||
ExcelFileData excelFileData = excelUtils.excelSaveAndParse(file);
|
ExcelFileData excelFileData = excelUtils.excelSaveAndParse(file);
|
||||||
if (editType == 1 || editType == 0) { //按照excel sheet 名称匹配
|
if (Objects.equals(editType, append)) { //按照excel sheet 名称匹配,替换:0;追加:1
|
||||||
CoreDatasource coreDatasource = datasourceMapper.selectById(datasourceId);
|
|
||||||
if (coreDatasource != null) {
|
if (coreDatasource != null) {
|
||||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||||
datasourceRequest.setDatasource(transDTO(coreDatasource));
|
datasourceRequest.setDatasource(transDTO(coreDatasource));
|
||||||
@ -757,7 +762,6 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
oldTableFields.sort((o1, o2) -> {
|
oldTableFields.sort((o1, o2) -> {
|
||||||
return o1.getName().compareTo(o2.getName());
|
return o1.getName().compareTo(o2.getName());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isEqual(newTableFields, oldTableFields)) {
|
if (isEqual(newTableFields, oldTableFields)) {
|
||||||
sheet.setDeTableName(datasetTableDTO.getTableName());
|
sheet.setDeTableName(datasetTableDTO.getTableName());
|
||||||
excelSheetDataList.add(sheet);
|
excelSheetDataList.add(sheet);
|
||||||
@ -770,8 +774,21 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
}
|
}
|
||||||
excelFileData.setSheets(excelSheetDataList);
|
excelFileData.setSheets(excelSheetDataList);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
if (coreDatasource != null) {
|
||||||
|
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||||
|
datasourceRequest.setDatasource(transDTO(coreDatasource));
|
||||||
|
List<DatasetTableDTO> datasetTableDTOS = ExcelUtils.getTables(datasourceRequest);
|
||||||
|
for (ExcelSheetData sheet : excelFileData.getSheets()) {
|
||||||
|
for (DatasetTableDTO datasetTableDTO : datasetTableDTOS) {
|
||||||
|
if (excelDataTableName(datasetTableDTO.getTableName()).equals(sheet.getTableName()) || isCsv(file.getOriginalFilename())) {
|
||||||
|
sheet.setDeTableName(datasetTableDTO.getTableName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
for (ExcelSheetData sheet : excelFileData.getSheets()) {
|
for (ExcelSheetData sheet : excelFileData.getSheets()) {
|
||||||
for (int i = 0; i < sheet.getFields().size() - 1; i++) {
|
for (int i = 0; i < sheet.getFields().size() - 1; i++) {
|
||||||
for (int j = i + 1; j < sheet.getFields().size(); j++) {
|
for (int j = i + 1; j < sheet.getFields().size(); j++) {
|
||||||
@ -1155,8 +1172,11 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
if (!Arrays.asList("API", "Excel", "folder").contains(coreDatasource.getType())) {
|
if (!Arrays.asList("API", "Excel", "folder").contains(coreDatasource.getType())) {
|
||||||
calciteProvider.updateDsPoolAfterCheckStatus(datasourceDTO);
|
calciteProvider.updateDsPoolAfterCheckStatus(datasourceDTO);
|
||||||
}
|
}
|
||||||
|
} catch (DEException e) {
|
||||||
|
datasourceDTO.setStatus("Error");
|
||||||
|
DEException.throwException(e.getMessage());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
coreDatasource.setStatus("Error");
|
datasourceDTO.setStatus("Error");
|
||||||
DEException.throwException(e.getMessage());
|
DEException.throwException(e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
coreDatasource.setStatus(datasourceDTO.getStatus());
|
coreDatasource.setStatus(datasourceDTO.getStatus());
|
||||||
|
@ -62,3 +62,45 @@ i18n_day=Day
|
|||||||
i18n_hour=Hour
|
i18n_hour=Hour
|
||||||
i18n_minute=Minute
|
i18n_minute=Minute
|
||||||
i18n_second=Second
|
i18n_second=Second
|
||||||
|
|
||||||
|
i18n_no_datasource_permission_to_create_column=No datasource permission, cannot create column
|
||||||
|
i18n_df_folder_cannot_to_search=Folder cannot for search data
|
||||||
|
i18n_df_no_primary_key=No primary key
|
||||||
|
i18n_df_cannot_operate_folder=Cannot Operate Folder
|
||||||
|
i18n_df_cannot_be_none=[%s] Cannot be null
|
||||||
|
i18n_df_value_cannot_be_none=[%s] value: %s Cannot be null
|
||||||
|
i18n_df_value_exists_in_database=[%s] value: %s Exists in database
|
||||||
|
i18n_df_data=Data
|
||||||
|
i18n_df_start=Start
|
||||||
|
i18n_df_end=End
|
||||||
|
i18n_df_datasource_not_found=datasource not found
|
||||||
|
i18n_df_datasource_does_not_enable_data_filling=function of dataFilling is not enabled
|
||||||
|
i18n_df_builtin_datasource=builtin datasource
|
||||||
|
i18n_df_folder_required=folder required
|
||||||
|
i18n_df_form_not_exists=form not exists
|
||||||
|
i18n_df_name_can_not_empty=name can not empty
|
||||||
|
i18n_df_template=template
|
||||||
|
i18n_df_task_status_is_null_or_finished=task status is null or finished
|
||||||
|
i18n_df_task_need_task_id=task need taskID
|
||||||
|
i18n_df_not_current_task_user=not current task user
|
||||||
|
i18n_df_miss_parameter=miss parameter
|
||||||
|
i18n_df_no_running_instance=no running instance
|
||||||
|
i18n_df_value=value
|
||||||
|
i18n_df_format_error=parse error
|
||||||
|
i18n_df_cannot_earlier_than=cannot earlier than
|
||||||
|
i18n_df_cannot_be_all_null=cannot be all null
|
||||||
|
i18n_df_value_not_in_range=value not in range
|
||||||
|
i18n_df_value_value_not_in_range=value: %s not in range
|
||||||
|
i18n_df_required=required
|
||||||
|
i18n_df_must_unique=must be unique
|
||||||
|
i18n_df_excel_parsing_error=Excel parse error
|
||||||
|
i18n_df_excel_is_empty=Excel is empty
|
||||||
|
i18n_df_excel_template_column_not_fit=count of template columns are not fit
|
||||||
|
i18n_df_selection=selection
|
||||||
|
i18n_df_date_format=date format
|
||||||
|
i18n_df_integer=integer
|
||||||
|
i18n_df_decimal=decimal
|
||||||
|
i18n_df_multiple_value_split=use ';' to split multiple value
|
||||||
|
i18n_df_email_type=email type
|
||||||
|
i18n_df_phone_type=phone type
|
||||||
|
|
||||||
|
@ -81,3 +81,48 @@ i18n_day=\u5929
|
|||||||
i18n_hour=\u5C0F\u65F6
|
i18n_hour=\u5C0F\u65F6
|
||||||
i18n_minute=\u5206\u949F
|
i18n_minute=\u5206\u949F
|
||||||
i18n_second=\u79D2
|
i18n_second=\u79D2
|
||||||
|
|
||||||
|
i18n_no_datasource_permission_to_create_column=\u65E0\u6570\u636E\u6E90\u8BBF\u95EE\u6743\u9650\uFF0C\u65E0\u6CD5\u521B\u5EFA\u8868\u5B57\u6BB5
|
||||||
|
i18n_df_folder_cannot_to_search=\u6587\u4EF6\u5939\u4E0D\u80FD\u67E5\u8BE2\u6570\u636E
|
||||||
|
i18n_df_no_primary_key=\u6CA1\u6709\u4E3B\u952E
|
||||||
|
i18n_df_cannot_operate_folder=\u4E0D\u80FD\u64CD\u4F5C\u6587\u4EF6\u5939
|
||||||
|
i18n_df_cannot_be_none=[%s] \u4E0D\u80FD\u4E3A\u7A7A
|
||||||
|
i18n_df_value_cannot_be_none=[%s] \u503C: %s \u4E0D\u80FD\u4E3A\u7A7A
|
||||||
|
i18n_df_value_exists_in_database=[%s] \u503C: %s \u5728\u6570\u636E\u5E93\u4E2D\u5DF2\u5B58\u5728, \u4E0D\u80FD\u91CD\u590D
|
||||||
|
i18n_df_data=\u6570\u636E
|
||||||
|
i18n_df_start=\u5F00\u59CB
|
||||||
|
i18n_df_end=\u7ED3\u675F
|
||||||
|
i18n_df_datasource_not_found=\u6CA1\u6709\u627E\u5230\u6570\u636E\u6E90
|
||||||
|
i18n_df_datasource_does_not_enable_data_filling=\u8BE5\u6570\u636E\u6E90\u6CA1\u6709\u542F\u7528\u6570\u636E\u586B\u62A5\u914D\u7F6E
|
||||||
|
i18n_df_builtin_datasource=\u5185\u5EFA\u6570\u636E\u5E93
|
||||||
|
i18n_df_folder_required=\u76EE\u5F55\u5FC5\u9009
|
||||||
|
i18n_df_form_not_exists=\u8868\u5355\u4E0D\u5B58\u5728
|
||||||
|
i18n_df_name_can_not_empty=\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A
|
||||||
|
i18n_df_template=\u6A21\u677F
|
||||||
|
i18n_df_task_status_is_null_or_finished=\u4EFB\u52A1\u72B6\u6001\u4E3A\u7A7A\u6216\u5DF2\u5B8C\u6210
|
||||||
|
i18n_df_task_need_task_id=\u9700\u6307\u5B9A\u4EFB\u52A1ID
|
||||||
|
i18n_df_not_current_task_user=\u4E0D\u662F\u5F53\u524D\u4EFB\u52A1\u7684\u76EE\u6807\u7528\u6237
|
||||||
|
i18n_df_miss_parameter=\u7F3A\u5931\u53C2\u6570
|
||||||
|
i18n_df_no_running_instance=\u5F53\u524D\u4EFB\u52A1\u6682\u65F6\u65E0\u8FD0\u884C\u5B9E\u4F8B
|
||||||
|
i18n_df_value=\u503C
|
||||||
|
i18n_df_format_error=\u683C\u5F0F\u89E3\u6790\u9519\u8BEF
|
||||||
|
i18n_df_cannot_earlier_than=\u4E0D\u80FD\u65E9\u4E8E
|
||||||
|
i18n_df_cannot_be_all_null=\u4E0D\u80FD\u53EA\u6709\u4E00\u4E2A\u4E3A\u7A7A
|
||||||
|
i18n_df_value_not_in_range=\u503C\u4E0D\u5728\u8303\u56F4\u5185
|
||||||
|
i18n_df_value_value_not_in_range=\u503C: %s \u4E0D\u5728\u8303\u56F4\u5185
|
||||||
|
i18n_df_required=\u5FC5\u586B
|
||||||
|
i18n_df_must_unique=\u4E0D\u5141\u8BB8\u91CD\u590D\u503C
|
||||||
|
i18n_df_excel_parsing_error=Excel\u89E3\u6790\u9519\u8BEF
|
||||||
|
i18n_df_excel_is_empty=\u8BE5Excel\u6CA1\u6709\u6570\u636E
|
||||||
|
i18n_df_excel_template_column_not_fit=\u6A21\u677F\u5B57\u6BB5\u4E2A\u6570\u4E0D\u5339\u914D
|
||||||
|
i18n_df_selection=\u9009\u9879\u503C\u4E3A
|
||||||
|
i18n_df_date_format=\u65E5\u671F\u683C\u5F0F
|
||||||
|
i18n_df_integer=\u6574\u5F62\u6570\u5B57
|
||||||
|
i18n_df_decimal=\u5C0F\u6570\u6570\u5B57
|
||||||
|
i18n_df_multiple_value_split=\u591A\u4E2A\u503C\u4F7F\u7528\u5206\u53F7";"\u5206\u5272
|
||||||
|
i18n_df_email_type=\u90AE\u7BB1\u683C\u5F0F
|
||||||
|
i18n_df_phone_type=\u624B\u673A\u53F7\u683C\u5F0F
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
i18n_copilot_cross_ds_error=\u8DE8\u6E90\u6570\u636E\u96C6\u4E0D\u652F\u6301\u8BE5\u529F\u80FD
|
||||||
|
@ -2,23 +2,38 @@ login.validator.name1=\u8CEC\u865F/\u90F5\u7BB1/\u624B\u6A5F\u865F\u4E0D\u80FD\u
|
|||||||
login.validator.pwd1=\u5BC6\u78BC\u4E0D\u80FD\u70BA\u7A7A
|
login.validator.pwd1=\u5BC6\u78BC\u4E0D\u80FD\u70BA\u7A7A
|
||||||
|
|
||||||
i18n_menu.home=\u9996\u9801
|
i18n_menu.home=\u9996\u9801
|
||||||
i18n_menu.workbranch=\u5DE5\u4F5C\u81FA
|
i18n_menu.workbranch=\u5DE5\u4F5C\u53F0
|
||||||
i18n_menu.visualized=\u53EF\u8996\u5316
|
i18n_menu.visualized=\u53EF\u8996\u5316
|
||||||
i18n_menu.template=\u6A21\u7248
|
i18n_menu.template=\u6A21\u7248
|
||||||
i18n_menu.application=\u61C9\u7528
|
i18n_menu.application=\u61C9\u7528
|
||||||
i18n_menu.system=\u7CFB\u7D71\u7BA1\u7406
|
i18n_menu.system=\u7CFB\u7D71\u7BA1\u7406
|
||||||
|
i18n_menu.template-market=\u6A21\u677F\u5E02\u5834
|
||||||
|
i18n_menu.template-setting=\u6A21\u677F\u7BA1\u7406
|
||||||
i18n_menu.view=\u6578\u64DA\u5C55\u793A
|
i18n_menu.view=\u6578\u64DA\u5C55\u793A
|
||||||
i18n_menu.data=\u6578\u64DA\u6E96\u5099
|
i18n_menu.data=\u6578\u64DA\u51C6\u5099
|
||||||
i18n_menu.panel=\u5100\u8868\u677F
|
i18n_menu.panel=\u5100\u8868\u677F
|
||||||
|
i18n_menu.data-filling-manage=\u6578\u64DA\u586B\u5831
|
||||||
i18n_menu.screen=\u6578\u64DA\u5927\u5C4F
|
i18n_menu.screen=\u6578\u64DA\u5927\u5C4F
|
||||||
i18n_menu.dataset=\u6578\u64DA\u96C6
|
i18n_menu.dataset=\u6578\u64DA\u96C6
|
||||||
i18n_menu.datasource=\u6578\u64DA\u6E90
|
i18n_menu.datasource=\u6578\u64DA\u6E90
|
||||||
i18n_menu.user=\u7528\u6236\u7BA1\u7406
|
i18n_menu.user=\u7528\u6236\u7BA1\u7406
|
||||||
i18n_menu.org=\u7D44\u7E54\u7BA1\u7406
|
i18n_menu.org=\u7D44\u7E54\u7BA1\u7406
|
||||||
i18n_menu.auth=\u6B0A\u9650\u914D\u7F6E
|
i18n_menu.auth=\u6B0A\u9650\u914D\u7F6E
|
||||||
i18n_menu.sysVariable=\u7CFB\u7EDF\u53D8\u91CF
|
i18n_menu.report=\u5B9A\u6642\u5831\u544A
|
||||||
i18n_field_name_repeat=\u5177\u6709\u91CD\u8907\u7684\u6B04\u4F4D\u540D\u7A31\uFF1A
|
i18n_menu.sync=\u540C\u6B65\u7BA1\u7406
|
||||||
|
i18n_menu.association=\u8840\u7DE3\u5206\u6790
|
||||||
|
i18n_menu.threshold=\u544A\u8B66\u7BA1\u7406
|
||||||
|
i18n_menu.summary=\u6982\u89BD
|
||||||
|
i18n_menu.ds=\u6578\u64DA\u9023\u63A5\u7BA1\u7406
|
||||||
|
i18n_menu.task=\u4EFB\u52D9\u7BA1\u7406
|
||||||
|
i18n_menu.embedded=\u5D4C\u5165\u5F0F\u7BA1\u7406
|
||||||
|
i18n_menu.plugin=\u63D2\u4EF6\u7BA1\u7406
|
||||||
|
i18n_menu.platform=\u5E73\u53F0\u5C0D\u63A5
|
||||||
|
i18n_menu.appearance=\u5916\u89C0\u914D\u7F6E
|
||||||
|
i18n_menu.sysVariable=\u7CFB\u7D71\u8B8A\u91CF
|
||||||
|
i18n_menu.sysTypeface=\u5B57\u9AD4\u7BA1\u7406
|
||||||
|
i18n_menu.font=\u5B57\u9AD4\u7BA1\u7406
|
||||||
|
i18n_field_name_repeat=\u6709\u91CD\u5FA9\u5B57\u6BB5\u540D\uFF1A
|
||||||
i18n_pid_not_eq_id=\u79FB\u52D5\u76EE\u6A19\u4E0D\u80FD\u662F\u81EA\u5DF1\u6216\u5B50\u76EE\u9304
|
i18n_pid_not_eq_id=\u79FB\u52D5\u76EE\u6A19\u4E0D\u80FD\u662F\u81EA\u5DF1\u6216\u5B50\u76EE\u9304
|
||||||
i18n_ds_name_exists=\u8A72\u5206\u7D44\u4E0B\u540D\u7A31\u91CD\u5FA9
|
i18n_ds_name_exists=\u8A72\u5206\u7D44\u4E0B\u540D\u7A31\u91CD\u5FA9
|
||||||
i18n_table_id_can_not_empty=\u67E5\u8A62\u7BC0\u9EDE\u4E0D\u80FD\u70BA\u7A7A
|
i18n_table_id_can_not_empty=\u67E5\u8A62\u7BC0\u9EDE\u4E0D\u80FD\u70BA\u7A7A
|
||||||
@ -32,14 +47,14 @@ i18n_union_field_can_not_empty=\u95DC\u806F\u5B57\u6BB5\u4E0D\u80FD\u70BA\u7A7A
|
|||||||
i18n_table_duplicate=\u76F8\u540C\u7BC0\u9EDE\u9700\u91CD\u65B0\u62D6\u5165\u624D\u80FD\u7E7C\u7E8C\u65B0\u5EFA\u6578\u64DA\u96C6
|
i18n_table_duplicate=\u76F8\u540C\u7BC0\u9EDE\u9700\u91CD\u65B0\u62D6\u5165\u624D\u80FD\u7E7C\u7E8C\u65B0\u5EFA\u6578\u64DA\u96C6
|
||||||
i18n_no_column_permission=\u6C92\u6709\u5217\u6B0A\u9650
|
i18n_no_column_permission=\u6C92\u6709\u5217\u6B0A\u9650
|
||||||
i18n_fetch_error=SQL\u57F7\u884C\u5931\u6557\uFF0C\u8ACB\u6AA2\u67E5\u8868\u3001\u5B57\u6BB5\u3001\u95DC\u806F\u95DC\u7CFB\u7B49\u4FE1\u606F\u662F\u5426\u6B63\u78BA\u4E26\u91CD\u65B0\u7DE8\u8F2F\u3002
|
i18n_fetch_error=SQL\u57F7\u884C\u5931\u6557\uFF0C\u8ACB\u6AA2\u67E5\u8868\u3001\u5B57\u6BB5\u3001\u95DC\u806F\u95DC\u7CFB\u7B49\u4FE1\u606F\u662F\u5426\u6B63\u78BA\u4E26\u91CD\u65B0\u7DE8\u8F2F\u3002
|
||||||
i18n_no_datasource_permission=\u65E0\u6570\u636E\u6E90\u8BBF\u95EE\u6743\u9650
|
i18n_no_datasource_permission=\u7121\u6578\u64DA\u6E90\u8A2A\u554F\u6B0A\u9650
|
||||||
i18n_no_dataset_permission=\u65e0\u6570\u636e\u96c6\u8bbf\u95ee\u6743\u9650
|
i18n_no_dataset_permission=\u7121\u6578\u64DA\u96C6\u8A2A\u554F\u6B0A\u9650
|
||||||
i18n_not_full=\u7576\u524D\u6578\u64DA\u6E90\u4E0D\u652F\u6301\u5168\u9023\u63A5
|
i18n_not_full=\u7576\u524D\u6578\u64DA\u6E90\u4E0D\u652F\u6301\u5168\u9023\u63A5
|
||||||
|
|
||||||
i18n_field_circular_ref=\u5B57\u6BB5\u5B58\u5728\u5FAA\u74B0\u5F15\u7528
|
i18n_field_circular_ref=\u5B57\u6BB5\u5B58\u5728\u5FAA\u74B0\u5F15\u7528
|
||||||
|
|
||||||
i18n_chart_not_handler=\u7121\u6CD5\u8655\u7406\u8A72\u5716\u8868\u985E\u578B
|
i18n_chart_not_handler=\u7121\u6CD5\u8655\u7406\u8A72\u5716\u8868\u985E\u578B
|
||||||
i18n_chart_delete=\u8996\u5716\u4E0D\u5B58\u5728
|
i18n_chart_delete=\u5716\u8868\u4E0D\u5B58\u5728
|
||||||
i18n_no_ds=\u6578\u64DA\u96C6\u4E0D\u5B58\u5728\u6216\u6C92\u6709\u6B0A\u9650
|
i18n_no_ds=\u6578\u64DA\u96C6\u4E0D\u5B58\u5728\u6216\u6C92\u6709\u6B0A\u9650
|
||||||
i18n_datasource_delete=\u6578\u64DA\u6E90\u4E0D\u5B58\u5728
|
i18n_datasource_delete=\u6578\u64DA\u6E90\u4E0D\u5B58\u5728
|
||||||
i18n_gauge_field_change=\u6240\u7528\u5B57\u6BB5\u767C\u751F\u8B8A\u66F4\uFF0C\u8ACB\u91CD\u65B0\u7DE8\u8F2F
|
i18n_gauge_field_change=\u6240\u7528\u5B57\u6BB5\u767C\u751F\u8B8A\u66F4\uFF0C\u8ACB\u91CD\u65B0\u7DE8\u8F2F
|
||||||
@ -53,9 +68,12 @@ i18n_invalid_ds=\u6578\u64DA\u6E90\u7121\u6548
|
|||||||
i18n_user_disable=\u7528\u6236\u5DF2\u88AB\u7981\u7528\uFF0C\u7121\u6CD5\u767B\u9304
|
i18n_user_disable=\u7528\u6236\u5DF2\u88AB\u7981\u7528\uFF0C\u7121\u6CD5\u767B\u9304
|
||||||
i18n_login_name_pwd_err=\u7528\u6236\u540D\u6216\u5BC6\u78BC\u932F\u8AA4
|
i18n_login_name_pwd_err=\u7528\u6236\u540D\u6216\u5BC6\u78BC\u932F\u8AA4
|
||||||
i18n_error_login_type=\u767B\u9304\u985E\u578B\u932F\u8AA4
|
i18n_error_login_type=\u767B\u9304\u985E\u578B\u932F\u8AA4
|
||||||
i18n_schema_is_empty=schema\u70BA\u7A7A\uFF01
|
i18n_schema_is_empty=schema \u70BA\u7A7A\uFF01
|
||||||
i18n_table_name_repeat=\u540D\u7A31\u91CD\u8907:
|
i18n_table_name_repeat=\u540D\u7A31\u91CD\u5FA9:
|
||||||
i18n_sql_not_empty=sql\u4E0D\u80FD\u70BA\u7A7A
|
i18n_sql_not_empty=sql \u4E0D\u80FD\u70BA\u7A7A
|
||||||
|
i18n_menu.parameter=\u7CFB\u7D71\u53C3\u6578
|
||||||
|
i18n_user_old_pwd_error=\u539F\u59CB\u5BC6\u78BC\u932F\u8AA4
|
||||||
|
i18n_menu.toolbox-log=\u64CD\u4F5C\u65E5\u5FD7
|
||||||
|
|
||||||
i18n_year=\u5E74
|
i18n_year=\u5E74
|
||||||
i18n_month=\u6708
|
i18n_month=\u6708
|
||||||
@ -63,3 +81,46 @@ i18n_day=\u5929
|
|||||||
i18n_hour=\u5C0F\u6642
|
i18n_hour=\u5C0F\u6642
|
||||||
i18n_minute=\u5206\u9418
|
i18n_minute=\u5206\u9418
|
||||||
i18n_second=\u79D2
|
i18n_second=\u79D2
|
||||||
|
|
||||||
|
i18n_no_datasource_permission_to_create_column=\u7121\u6578\u64DA\u6E90\u8A2A\u554F\u6B0A\u9650\uFF0C\u7121\u6CD5\u5275\u5EFA\u8868\u5B57\u6BB5
|
||||||
|
i18n_df_folder_cannot_to_search=\u6587\u4EF6\u593E\u4E0D\u80FD\u67E5\u8A62\u6578\u64DA
|
||||||
|
i18n_df_no_primary_key=\u6C92\u6709\u4E3B\u9375
|
||||||
|
i18n_df_cannot_operate_folder=\u4E0D\u80FD\u64CD\u4F5C\u6587\u4EF6\u593E
|
||||||
|
i18n_df_cannot_be_none=[%s] \u4E0D\u80FD\u70BA\u7A7A
|
||||||
|
i18n_df_value_cannot_be_none=[%s] \u503C: %s \u4E0D\u80FD\u70BA\u7A7A
|
||||||
|
i18n_df_value_exists_in_database=[%s] \u503C: %s \u5728\u6578\u64DA\u5EAB\u4E2D\u5DF2\u5B58\u5728, \u4E0D\u80FD\u91CD\u5FA9
|
||||||
|
i18n_df_data=\u6578\u64DA
|
||||||
|
i18n_df_start=\u958B\u59CB
|
||||||
|
i18n_df_end=\u7D50\u675F
|
||||||
|
i18n_df_datasource_not_found=\u6C92\u6709\u627E\u5230\u6578\u64DA\u6E90
|
||||||
|
i18n_df_datasource_does_not_enable_data_filling=\u8A72\u6578\u64DA\u6E90\u6C92\u6709\u555F\u7528\u6578\u64DA\u586B\u5831\u914D\u7F6E
|
||||||
|
i18n_df_builtin_datasource=\u5167\u5EFA\u6578\u64DA\u5EAB
|
||||||
|
i18n_df_folder_required=\u76EE\u9304\u5FC5\u9078
|
||||||
|
i18n_df_form_not_exists=\u8868\u55AE\u4E0D\u5B58\u5728
|
||||||
|
i18n_df_name_can_not_empty=\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A
|
||||||
|
i18n_df_template=\u6A21\u677F
|
||||||
|
i18n_df_task_status_is_null_or_finished=\u4EFB\u52D9\u72C0\u614B\u70BA\u7A7A\u6216\u5DF2\u5B8C\u6210
|
||||||
|
i18n_df_task_need_task_id=\u9700\u6307\u5B9A\u4EFB\u52D9ID
|
||||||
|
i18n_df_not_current_task_user=\u4E0D\u662F\u7576\u524D\u4EFB\u52D9\u7684\u76EE\u6A19\u7528\u6236
|
||||||
|
i18n_df_miss_parameter=\u7F3A\u5931\u53C3\u6578
|
||||||
|
i18n_df_no_running_instance=\u7576\u524D\u4EFB\u52D9\u66AB\u6642\u7121\u904B\u884C\u5BE6\u4F8B
|
||||||
|
i18n_df_value=\u503C
|
||||||
|
i18n_df_format_error=\u683C\u5F0F\u89E3\u6790\u932F\u8AA4
|
||||||
|
i18n_df_cannot_earlier_than=\u4E0D\u80FD\u65E9\u4E8E
|
||||||
|
i18n_df_cannot_be_all_null=\u4E0D\u80FD\u53EA\u6709\u4E00\u500B\u70BA\u7A7A
|
||||||
|
i18n_df_value_not_in_range=\u503C\u4E0D\u5728\u8303\u570D\u5167
|
||||||
|
i18n_df_value_value_not_in_range=\u503C: %s \u4E0D\u5728\u8303\u570D\u5167
|
||||||
|
i18n_df_required=\u5FC5\u586B
|
||||||
|
i18n_df_must_unique=\u4E0D\u5141\u8A31\u91CD\u5FA9\u503C
|
||||||
|
i18n_df_excel_parsing_error=Excel\u89E3\u6790\u932F\u8AA4
|
||||||
|
i18n_df_excel_is_empty=\u8A72Excel\u6C92\u6709\u6578\u64DA
|
||||||
|
i18n_df_excel_template_column_not_fit=\u6A21\u677F\u5B57\u6BB5\u500B\u6578\u4E0D\u5339\u914D
|
||||||
|
i18n_df_selection=\u9078\u9805\u503C\u70BA
|
||||||
|
i18n_df_date_format=\u65E5\u671F\u683C\u5F0F
|
||||||
|
i18n_df_integer=\u6574\u5F62\u6578\u5B57
|
||||||
|
i18n_df_decimal=\u5C0F\u6578\u6578\u5B57
|
||||||
|
i18n_df_multiple_value_split=\u591A\u500B\u503C\u4F7F\u7528\u5206\u865F";"\u5206\u5272
|
||||||
|
i18n_df_email_type=\u90F5\u7BB1\u683C\u5F0F
|
||||||
|
i18n_df_phone_type=\u624B\u6A5F\u865F\u683C\u5F0F
|
||||||
|
|
||||||
|
|
||||||
|
@ -415,5 +415,9 @@ tinymce.addI18n('zh_CN', {
|
|||||||
"Whole words": "\u5168\u5b57\u5339\u914d",
|
"Whole words": "\u5168\u5b57\u5339\u914d",
|
||||||
"Spellcheck": "\u62fc\u5199\u68c0\u67e5",
|
"Spellcheck": "\u62fc\u5199\u68c0\u67e5",
|
||||||
"Caption": "\u6807\u9898",
|
"Caption": "\u6807\u9898",
|
||||||
"Insert template": "\u63d2\u5165\u6a21\u677f"
|
"Insert template": "\u63d2\u5165\u6a21\u677f",
|
||||||
|
"Cut column": "\u526a\u5207\u5217",
|
||||||
|
"Copy column": "\u590d\u5236\u5217",
|
||||||
|
"Paste column before": "\u7c98\u8d34\u5230\u524d\u65b9",
|
||||||
|
"Paste column after": "\u7c98\u8d34\u5230\u540e\u65b9"
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_4327_361639)">
|
||||||
|
<path d="M6 11.5C9.03757 11.5 11.5 9.03757 11.5 6C11.5 2.96243 9.03757 0.5 6 0.5C2.96243 0.5 0.5 2.96243 0.5 6C0.5 9.03757 2.96243 11.5 6 11.5Z" fill="#F54A45"/>
|
||||||
|
<path d="M5.75 3.5C5.61193 3.5 5.5 3.61193 5.5 3.75V6.75C5.5 6.88807 5.61193 7 5.75 7H6.25C6.38807 7 6.5 6.88807 6.5 6.75V3.75C6.5 3.61193 6.38807 3.5 6.25 3.5H5.75Z" fill="white"/>
|
||||||
|
<path d="M5.75 7.5C5.61193 7.5 5.5 7.61193 5.5 7.75V8.25C5.5 8.38807 5.61193 8.5 5.75 8.5H6.25C6.38807 8.5 6.5 8.38807 6.5 8.25V7.75C6.5 7.61193 6.38807 7.5 6.25 7.5H5.75Z" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_4327_361639">
|
||||||
|
<rect width="12" height="12" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 785 B |
@ -56,6 +56,7 @@ import treemapOrigin from '@/assets/svg/treemap-origin.svg'
|
|||||||
import waterfallOrigin from '@/assets/svg/waterfall-origin.svg'
|
import waterfallOrigin from '@/assets/svg/waterfall-origin.svg'
|
||||||
import wordCloudOrigin from '@/assets/svg/word-cloud-origin.svg'
|
import wordCloudOrigin from '@/assets/svg/word-cloud-origin.svg'
|
||||||
import tHeatmapOrigin from '@/assets/svg/t-heatmap-origin.svg'
|
import tHeatmapOrigin from '@/assets/svg/t-heatmap-origin.svg'
|
||||||
|
import pictureGroupOrigin from '@/assets/svg/picture-group-origin.svg'
|
||||||
import dvMore from '@/assets/svg/dv-more.svg'
|
import dvMore from '@/assets/svg/dv-more.svg'
|
||||||
import dvExpandDown from '@/assets/svg/dv-expand-down.svg'
|
import dvExpandDown from '@/assets/svg/dv-expand-down.svg'
|
||||||
import dvExpandRight from '@/assets/svg/dv-expand-right.svg'
|
import dvExpandRight from '@/assets/svg/dv-expand-right.svg'
|
||||||
@ -324,6 +325,7 @@ const iconMap = {
|
|||||||
'waterfall-origin': waterfallOrigin,
|
'waterfall-origin': waterfallOrigin,
|
||||||
'word-cloud-origin': wordCloudOrigin,
|
'word-cloud-origin': wordCloudOrigin,
|
||||||
't-heatmap-origin': tHeatmapOrigin,
|
't-heatmap-origin': tHeatmapOrigin,
|
||||||
|
'picture-group-origin': pictureGroupOrigin,
|
||||||
group: group
|
group: group
|
||||||
}
|
}
|
||||||
const getIconName = item => {
|
const getIconName = item => {
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, toRefs } from 'vue'
|
import { computed, nextTick, PropType, ref, toRefs } from 'vue'
|
||||||
import { ElIcon } from 'element-plus-secondary'
|
import { ElIcon, ElMessage } from 'element-plus-secondary'
|
||||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||||
const dvMainStore = dvMainStoreWithOut()
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
const { canvasCollapse } = storeToRefs(dvMainStore)
|
const { canvasCollapse } = storeToRefs(dvMainStore)
|
||||||
|
let componentNameEdit = ref(false)
|
||||||
|
let inputComponentName = ref('')
|
||||||
|
let componentNameInputAttr = ref(null)
|
||||||
|
const snapshotStore = snapshotStoreWithOut()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
scrollWidth: {
|
scrollWidth: {
|
||||||
required: false,
|
required: false,
|
||||||
@ -32,18 +36,64 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'defaultSide'
|
default: 'defaultSide'
|
||||||
},
|
},
|
||||||
|
view: {
|
||||||
|
type: Object as PropType<ChartObj>,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
slideIndex: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
themes: {
|
||||||
|
type: String as PropType<EditorTheme>,
|
||||||
|
default: 'light'
|
||||||
|
},
|
||||||
title: String
|
title: String
|
||||||
})
|
})
|
||||||
|
|
||||||
const { width, asidePosition, sideName, themeInfo } = toRefs(props)
|
const { width, asidePosition, sideName, themeInfo, view, themes } = toRefs(props)
|
||||||
const collapseChange = () => {
|
const collapseChange = () => {
|
||||||
canvasCollapse.value[sideName.value] = !canvasCollapse.value[sideName.value]
|
canvasCollapse.value[sideName.value] = !canvasCollapse.value[sideName.value]
|
||||||
}
|
}
|
||||||
const widthShow = computed(() => `${canvasCollapse.value[sideName.value] ? 36 : width.value}px`)
|
const widthShow = computed(() => `${canvasCollapse.value[sideName.value] ? 36 : width.value}px`)
|
||||||
|
|
||||||
|
const isViewTitle = computed(() => view.value && ['picture-group'].includes(view.value.type))
|
||||||
|
|
||||||
const slideStyle = computed(() => {
|
const slideStyle = computed(() => {
|
||||||
return { '--de-scroll-width': props.scrollWidth + 'px', width: widthShow.value }
|
return { '--de-scroll-width': props.scrollWidth + 'px', width: widthShow.value }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const closeEditComponentName = () => {
|
||||||
|
componentNameEdit.value = false
|
||||||
|
if (!inputComponentName.value || !inputComponentName.value.trim()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (inputComponentName.value.trim() === view.value.title) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (inputComponentName.value.trim().length > 64 || inputComponentName.value.trim().length < 2) {
|
||||||
|
ElMessage.warning('名称字段长度2-64个字符')
|
||||||
|
editComponentName()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
view.value.title = inputComponentName.value
|
||||||
|
inputComponentName.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const editComponentName = () => {
|
||||||
|
if (isViewTitle.value) {
|
||||||
|
componentNameEdit.value = true
|
||||||
|
inputComponentName.value = view.value.title
|
||||||
|
nextTick(() => {
|
||||||
|
componentNameInputAttr.value.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onComponentNameChange = () => {
|
||||||
|
snapshotStore.recordSnapshotCache()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -55,7 +105,17 @@ const slideStyle = computed(() => {
|
|||||||
:style="slideStyle"
|
:style="slideStyle"
|
||||||
>
|
>
|
||||||
<el-row align="middle" :class="'title-' + themeInfo" justify="space-between">
|
<el-row align="middle" :class="'title-' + themeInfo" justify="space-between">
|
||||||
<span v-if="!canvasCollapse[sideName]">{{ title }}</span>
|
<div
|
||||||
|
:id="'attr-slide-component-name' + slideIndex"
|
||||||
|
v-if="!canvasCollapse[sideName]"
|
||||||
|
class="name-area-attr"
|
||||||
|
style="max-width: 180px; text-overflow: ellipsis; white-space: nowrap"
|
||||||
|
:style="{ width: componentNameEdit ? '300px' : 'auto' }"
|
||||||
|
:class="{ 'component-name-dark': themeInfo === 'dark' }"
|
||||||
|
@dblclick="editComponentName"
|
||||||
|
>
|
||||||
|
{{ isViewTitle ? view.title : title }}
|
||||||
|
</div>
|
||||||
<el-icon
|
<el-icon
|
||||||
:title="title"
|
:title="title"
|
||||||
:class="['custom-icon-' + themeInfo, 'collapse-icon-' + themeInfo]"
|
:class="['custom-icon-' + themeInfo, 'collapse-icon-' + themeInfo]"
|
||||||
@ -79,6 +139,16 @@ const slideStyle = computed(() => {
|
|||||||
<div class="collapse-title" v-if="canvasCollapse[sideName]">
|
<div class="collapse-title" v-if="canvasCollapse[sideName]">
|
||||||
<span>{{ title }}</span>
|
<span>{{ title }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<Teleport v-if="componentNameEdit" :to="'#attr-slide-component-name' + slideIndex">
|
||||||
|
<input
|
||||||
|
ref="componentNameInputAttr"
|
||||||
|
v-model="inputComponentName"
|
||||||
|
width="100%"
|
||||||
|
:effect="themeInfo"
|
||||||
|
@change="onComponentNameChange"
|
||||||
|
@blur="closeEditComponentName"
|
||||||
|
/>
|
||||||
|
</Teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -184,4 +254,38 @@ const slideStyle = computed(() => {
|
|||||||
.ed-scrollbar__bar.is-vertical {
|
.ed-scrollbar__bar.is-vertical {
|
||||||
width: var(--de-scroll-width);
|
width: var(--de-scroll-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.name-area-attr {
|
||||||
|
position: relative;
|
||||||
|
line-height: 24px;
|
||||||
|
height: 24px;
|
||||||
|
font-size: 14px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
outline: none;
|
||||||
|
border: 1px solid #295acc;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0 4px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.component-name-dark {
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
color: @dv-canvas-main-font-color;
|
||||||
|
background-color: #050e21;
|
||||||
|
outline: none;
|
||||||
|
border: 1px solid #295acc;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0 4px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -132,6 +132,7 @@ const canEdit = ref(false)
|
|||||||
// 初始化配置
|
// 初始化配置
|
||||||
const tinymceId = 'tinymce-view-' + element.value.id + '-' + suffixId.value
|
const tinymceId = 'tinymce-view-' + element.value.id + '-' + suffixId.value
|
||||||
const myValue = ref('')
|
const myValue = ref('')
|
||||||
|
const cellDragStart = ref(0)
|
||||||
|
|
||||||
const systemFontFamily = appearanceStore.fontList.map(item => item.name)
|
const systemFontFamily = appearanceStore.fontList.map(item => item.name)
|
||||||
const curFontFamily = () => {
|
const curFontFamily = () => {
|
||||||
@ -171,25 +172,107 @@ const init = ref({
|
|||||||
branding: false,
|
branding: false,
|
||||||
icons: 'vertical-content',
|
icons: 'vertical-content',
|
||||||
vertical_align: element.value.propValue.verticalAlign,
|
vertical_align: element.value.propValue.verticalAlign,
|
||||||
|
table_default_attributes: {
|
||||||
|
width: '400' // 使用 table_default_attributes 设置表格的宽度
|
||||||
|
},
|
||||||
|
table_default_styles: {
|
||||||
|
width: '400px' // 或者使用 table_default_styles 设置宽度,单位为 px
|
||||||
|
},
|
||||||
setup: function (editor) {
|
setup: function (editor) {
|
||||||
// 在表格调整大小开始时
|
let cloneHandle = null // 用于存储克隆的手柄
|
||||||
editor.on('ObjectResizeStart', function (e) {
|
let originalHandle = null // 用于存储原始手柄
|
||||||
const { target, width, height } = e
|
editor.on('init', () => {
|
||||||
if (target.nodeName === 'TABLE') {
|
const doc = editor.getDoc()
|
||||||
// 将宽高根据缩放比例调整
|
// 监测 mouseup、mousedown 和 mousemove 事件
|
||||||
// e.width = width / props.scale
|
// 1.单元格问题 因为缩放问题 导致拖拽的坐标系有偏差,此处隐藏原有拖拽定位bar,并根据
|
||||||
// e.height = height / props.scale
|
// 缩放比例动态调整时间定位bar的位置,这会代理鼠标移速和bar移速不同步问题,不过bar定位是准确的
|
||||||
}
|
// 可以解决因为缩放导致tinymce 内部坐标系出错问题
|
||||||
})
|
doc.addEventListener('mousedown', event => {
|
||||||
|
nextTick(() => {
|
||||||
|
originalHandle = event.target.closest('.ephox-snooker-resizer-bar-dragging')
|
||||||
|
if (originalHandle) {
|
||||||
|
// 克隆原始手柄
|
||||||
|
cloneHandle = originalHandle.cloneNode(true)
|
||||||
|
cloneHandle.style.zIndex = 9999 // 提升克隆手柄的层级
|
||||||
|
originalHandle.style.display = 'none' // 隐藏原始手柄
|
||||||
|
// 将克隆手柄添加到原手柄的父元素中
|
||||||
|
const parentDiv = originalHandle.parentNode // 获取原手柄的父元素
|
||||||
|
parentDiv.appendChild(cloneHandle) // 将克隆手柄添加到父元素中
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// 在表格调整大小结束时
|
// 监听 mousemove 事件以更新克隆手柄位置
|
||||||
editor.on('ObjectResized', function (e) {
|
doc.addEventListener('mousemove', event => {
|
||||||
const { target, width, height } = e
|
if (cloneHandle) {
|
||||||
if (target.nodeName === 'TABLE') {
|
// // 计算鼠标移动的距离
|
||||||
// 将最终调整的宽高根据缩放比例重设
|
if (cloneHandle.offsetHeight > cloneHandle.offsetWidth) {
|
||||||
// target.style.width = `${width * props.scale}px`
|
// 计算鼠标移动的距离
|
||||||
// target.style.height = `${height scaleFactor}px`
|
const offsetX = event.movementX * props.scale // 使用缩放比例进行调整
|
||||||
|
cloneHandle.style.left = `${cloneHandle.offsetLeft + offsetX}px` // 更新克隆手柄的位置
|
||||||
|
} else {
|
||||||
|
// 计算鼠标移动的距离
|
||||||
|
const offsetY = event.movementY * props.scale // 使用缩放比例进行调整
|
||||||
|
cloneHandle.style.top = `${cloneHandle.offsetTop + offsetY}px` // 更新克隆手柄的位置
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听 mouseup 事件以结束调整
|
||||||
|
doc.addEventListener('mouseup', event => {
|
||||||
|
if (cloneHandle) {
|
||||||
|
// 显示原始手柄并移除克隆手柄
|
||||||
|
originalHandle.style.display = ''
|
||||||
|
if (cloneHandle) {
|
||||||
|
cloneHandle.parentNode.removeChild(cloneHandle) // 获取原手柄的父元素
|
||||||
|
}
|
||||||
|
cloneHandle = null
|
||||||
|
originalHandle = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 函数:根据缩放比例调整 .mce-resizehandle 的位置和大小
|
||||||
|
const adjustResizeHandles = (aLeft, aTop) => {
|
||||||
|
nextTick(() => {
|
||||||
|
const nodeRt = doc.getElementById('mceResizeHandlene')
|
||||||
|
const nodeRb = doc.getElementById('mceResizeHandlese')
|
||||||
|
const nodeLb = doc.getElementById('mceResizeHandlesw')
|
||||||
|
if (nodeRt) {
|
||||||
|
nodeRt.style.left = `${aLeft}px`
|
||||||
|
}
|
||||||
|
if (nodeRb) {
|
||||||
|
nodeRb.style.left = `${aLeft}px`
|
||||||
|
nodeRb.style.top = `${aTop}px`
|
||||||
|
}
|
||||||
|
if (nodeLb) {
|
||||||
|
nodeLb.style.top = `${aTop}px`
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听 ObjectSelected 事件,点击表格时触发调整
|
||||||
|
editor.on('ObjectSelected', event => {
|
||||||
|
if (event.target.nodeName === 'TABLE') {
|
||||||
|
adjustResizeHandles(
|
||||||
|
event.target.offsetWidth + event.target.offsetLeft,
|
||||||
|
event.target.offsetHeight + event.target.offsetTop
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听 ObjectResized 事件,更新调整大小句柄
|
||||||
|
// 在表格调整大小结束时
|
||||||
|
// 解决移动表格corner点位resize时因为缩放导致的坐标系放大问题,进而导致移动错位问题
|
||||||
|
editor.on('ObjectResized', function (e) {
|
||||||
|
const { target, width, height, origin } = e
|
||||||
|
if (target.nodeName === 'TABLE' && origin.indexOf('corner') > -1) {
|
||||||
|
// 将最终调整的宽高根据缩放比例重设
|
||||||
|
target.style.width = `${width}px`
|
||||||
|
target.style.height = `${height}px`
|
||||||
|
} else if (target.nodeName === 'TABLE' && origin.indexOf('bar-col') > -1) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -634,12 +717,6 @@ defineExpose({
|
|||||||
width: 0px !important;
|
width: 0px !important;
|
||||||
height: 0px !important;
|
height: 0px !important;
|
||||||
}
|
}
|
||||||
::v-deep(p) {
|
|
||||||
zoom: var(--de-canvas-scale);
|
|
||||||
}
|
|
||||||
::v-deep(td span) {
|
|
||||||
zoom: var(--de-canvas-scale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.ol) {
|
:deep(.ol) {
|
||||||
|
@ -0,0 +1,751 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="rich-main-class"
|
||||||
|
:class="{ 'edit-model': canEdit }"
|
||||||
|
@keydown.stop
|
||||||
|
@keyup.stop
|
||||||
|
@dblclick="setEdit"
|
||||||
|
@click="onClick"
|
||||||
|
:style="richTextStyle"
|
||||||
|
>
|
||||||
|
<chart-error v-if="isError" :err-msg="errMsg" />
|
||||||
|
<Editor
|
||||||
|
v-if="editShow && !isError"
|
||||||
|
v-model="myValue"
|
||||||
|
class="custom-text-content"
|
||||||
|
:style="wrapperStyle"
|
||||||
|
:id="tinymceId"
|
||||||
|
:init="init"
|
||||||
|
:disabled="!canEdit || disabled"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="rich-placeholder"
|
||||||
|
:class="{ 'rich-placeholder--dark': themes === 'dark' }"
|
||||||
|
v-if="showPlaceHolder"
|
||||||
|
>
|
||||||
|
{{ init.outer_placeholder }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { formatDataEaseBi } from '@/utils/url'
|
||||||
|
import tinymce from 'tinymce/tinymce' // tinymce默认hidden,不引入不显示
|
||||||
|
import Editor from '@tinymce/tinymce-vue' // 编辑器引入
|
||||||
|
import 'tinymce/themes/silver/theme' // 编辑器主题
|
||||||
|
import 'tinymce/icons/default' // 引入编辑器图标icon,不引入则不显示对应图标
|
||||||
|
// 引入编辑器插件(基本免费插件都在这儿了)
|
||||||
|
import 'tinymce/plugins/advlist' // 高级列表
|
||||||
|
import 'tinymce/plugins/autolink' // 自动链接
|
||||||
|
import 'tinymce/plugins/link' // 超链接
|
||||||
|
import 'tinymce/plugins/image' // 插入编辑图片
|
||||||
|
import 'tinymce/plugins/lists' // 列表插件
|
||||||
|
import 'tinymce/plugins/charmap' // 特殊字符
|
||||||
|
import 'tinymce/plugins/media' // 插入编辑媒体
|
||||||
|
import 'tinymce/plugins/wordcount' // 字数统计
|
||||||
|
import 'tinymce/plugins/table' // 表格
|
||||||
|
import 'tinymce/plugins/contextmenu' // contextmenu
|
||||||
|
import 'tinymce/plugins/directionality'
|
||||||
|
import 'tinymce/plugins/nonbreaking'
|
||||||
|
import 'tinymce/plugins/pagebreak'
|
||||||
|
import '@npkg/tinymce-plugins/letterspacing'
|
||||||
|
import './plugins' //自定义插件
|
||||||
|
import { computed, nextTick, reactive, ref, toRefs, watch, onMounted, PropType } from 'vue'
|
||||||
|
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||||
|
import eventBus from '@/utils/eventBus'
|
||||||
|
import { guid } from '@/views/visualized/data/dataset/form/util'
|
||||||
|
import { getData } from '@/api/chart'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
|
import ChartError from '@/views/chart/components/views/components/ChartError.vue'
|
||||||
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||||
|
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
||||||
|
import { parseJson } from '@/views/chart/components/js/util'
|
||||||
|
import { mappingColor } from '@/views/chart/components/js/panel/common/common_table'
|
||||||
|
import { CHART_FONT_FAMILY } from '@/views/chart/components/editor/util/chart'
|
||||||
|
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||||
|
const snapshotStore = snapshotStoreWithOut()
|
||||||
|
const errMsg = ref('')
|
||||||
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
|
const { canvasViewInfo } = storeToRefs(dvMainStore)
|
||||||
|
const isError = ref(false)
|
||||||
|
const appearanceStore = useAppearanceStoreWithOut()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
scale: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
element: {
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
editMode: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
default: 'edit'
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 是否禁用
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
showPosition: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: 'preview'
|
||||||
|
},
|
||||||
|
themes: {
|
||||||
|
type: String as PropType<EditorTheme>,
|
||||||
|
default: 'dark'
|
||||||
|
},
|
||||||
|
//图表渲染id后缀
|
||||||
|
suffixId: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: 'common'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const { element, editMode, active, disabled, showPosition, suffixId } = toRefs(props)
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
emptyValue: '-',
|
||||||
|
data: null,
|
||||||
|
viewDataInfo: null,
|
||||||
|
totalItems: 0,
|
||||||
|
firstRender: true,
|
||||||
|
previewFirstRender: true
|
||||||
|
})
|
||||||
|
const dataRowSelect = ref({})
|
||||||
|
const dataRowNameSelect = ref({})
|
||||||
|
const dataRowNameSelectSource = ref({})
|
||||||
|
const dataRowFiledName = ref([])
|
||||||
|
const initReady = ref(false)
|
||||||
|
const editShow = ref(true)
|
||||||
|
const canEdit = ref(false)
|
||||||
|
// 初始化配置
|
||||||
|
const tinymceId = 'tinymce-view-' + element.value.id + '-' + suffixId.value
|
||||||
|
const myValue = ref('')
|
||||||
|
|
||||||
|
const systemFontFamily = appearanceStore.fontList.map(item => item.name)
|
||||||
|
const curFontFamily = () => {
|
||||||
|
let result = ''
|
||||||
|
CHART_FONT_FAMILY.concat(
|
||||||
|
appearanceStore.fontList.map(ele => ({
|
||||||
|
name: ele.name,
|
||||||
|
value: ele.name
|
||||||
|
}))
|
||||||
|
).forEach(font => {
|
||||||
|
result = result + font.name + '=' + font.name + ';'
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
const init = ref({
|
||||||
|
selector: '#' + tinymceId,
|
||||||
|
toolbar_items_size: 'small',
|
||||||
|
language_url: formatDataEaseBi('./tinymce-dataease-private/langs/zh_CN.js'), // 汉化路径是自定义的,一般放在public或static里面
|
||||||
|
language: 'zh_CN',
|
||||||
|
skin_url: formatDataEaseBi('./tinymce-dataease-private/skins/ui/oxide'), // 皮肤
|
||||||
|
content_css: formatDataEaseBi('./tinymce-dataease-private/skins/content/default/content.css'),
|
||||||
|
plugins:
|
||||||
|
'vertical-content advlist autolink link image lists charmap media wordcount table contextmenu directionality pagebreak letterspacing', // 插件
|
||||||
|
// 工具栏
|
||||||
|
toolbar:
|
||||||
|
'undo redo | fontselect fontsizeselect |forecolor backcolor bold italic letterspacing |underline strikethrough link lineheight| formatselect |' +
|
||||||
|
'top-align center-align bottom-align | alignleft aligncenter alignright | bullist numlist |' +
|
||||||
|
' blockquote subscript superscript removeformat | table image ',
|
||||||
|
toolbar_location: '/',
|
||||||
|
font_formats: curFontFamily(),
|
||||||
|
fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 42px 48px 56px 72px', // 字体大小
|
||||||
|
menubar: false,
|
||||||
|
placeholder: '',
|
||||||
|
outer_placeholder: '双击输入文字',
|
||||||
|
inline: true, // 开启内联模式
|
||||||
|
branding: false,
|
||||||
|
icons: 'vertical-content',
|
||||||
|
vertical_align: element.value.propValue.verticalAlign,
|
||||||
|
setup: function (editor) {
|
||||||
|
// 在表格调整大小开始时
|
||||||
|
editor.on('ObjectResizeStart', function (e) {
|
||||||
|
const { target, width, height } = e
|
||||||
|
if (target.nodeName === 'TABLE') {
|
||||||
|
// 将宽高根据缩放比例调整
|
||||||
|
// e.width = width / props.scale
|
||||||
|
// e.height = height / props.scale
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 在表格调整大小结束时
|
||||||
|
editor.on('ObjectResized', function (e) {
|
||||||
|
const { target, width, height } = e
|
||||||
|
if (target.nodeName === 'TABLE') {
|
||||||
|
// 将最终调整的宽高根据缩放比例重设
|
||||||
|
// target.style.width = `${width * props.scale}px`
|
||||||
|
// target.style.height = `${height scaleFactor}px`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const editStatus = computed(() => {
|
||||||
|
return editMode.value === 'edit'
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => active.value,
|
||||||
|
val => {
|
||||||
|
if (!val) {
|
||||||
|
const ed = tinymce.editors[tinymceId]
|
||||||
|
if (canEdit.value) {
|
||||||
|
element.value.propValue.textValue = ed?.getContent()
|
||||||
|
}
|
||||||
|
element.value['editing'] = false
|
||||||
|
canEdit.value = false
|
||||||
|
reShow()
|
||||||
|
myValue.value = assignment(element.value.propValue.textValue)
|
||||||
|
ed.setContent(myValue.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => myValue.value,
|
||||||
|
() => {
|
||||||
|
if (canEdit.value) {
|
||||||
|
const ed = tinymce.editors[tinymceId]
|
||||||
|
element.value.propValue.textValue = ed?.getContent()
|
||||||
|
}
|
||||||
|
if (initReady.value && canEdit.value) {
|
||||||
|
snapshotStore.recordSnapshotCache('renderChart', element.value.id)
|
||||||
|
initFontFamily(myValue.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const ALIGN_MAP = {
|
||||||
|
'top-align': {},
|
||||||
|
'center-align': {
|
||||||
|
margin: 'auto'
|
||||||
|
},
|
||||||
|
'bottom-align': {
|
||||||
|
'margin-top': 'auto'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const wrapperStyle = computed(() => {
|
||||||
|
const align = element.value.propValue.verticalAlign
|
||||||
|
if (!align) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
return ALIGN_MAP[align]
|
||||||
|
})
|
||||||
|
useEmitt({
|
||||||
|
name: 'vertical-change-' + tinymceId,
|
||||||
|
callback: align => {
|
||||||
|
element.value.propValue.verticalAlign = align
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const viewInit = () => {
|
||||||
|
useEmitt({
|
||||||
|
name: 'fieldSelect-' + element.value.id,
|
||||||
|
callback: function (val) {
|
||||||
|
fieldSelect(val)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
tinymce.init({})
|
||||||
|
myValue.value = assignment(element.value.propValue.textValue)
|
||||||
|
}
|
||||||
|
const initCurFieldsChange = () => {
|
||||||
|
if (!canEdit.value) {
|
||||||
|
myValue.value = assignment(element.value.propValue.textValue)
|
||||||
|
const ed = tinymce.editors[tinymceId]
|
||||||
|
ed.setContent(myValue.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const jumpTargetAdaptor = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const paragraphs = document.querySelectorAll('p')
|
||||||
|
paragraphs.forEach(p => {
|
||||||
|
// 如果 p 标签已经有 onclick 且包含 event.stopPropagation,则跳过
|
||||||
|
if (
|
||||||
|
p.getAttribute('onclick') &&
|
||||||
|
p.getAttribute('onclick').includes('event.stopPropagation()')
|
||||||
|
) {
|
||||||
|
return // 已经有 stopPropagation,跳过
|
||||||
|
}
|
||||||
|
// 否则添加 onclick 事件
|
||||||
|
p.setAttribute('onclick', 'event.stopPropagation()')
|
||||||
|
})
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
const assignment = content => {
|
||||||
|
const on = content.match(/\[(.+?)\]/g)
|
||||||
|
if (on) {
|
||||||
|
const thresholdStyleInfo = conditionAdaptor(state.viewDataInfo)
|
||||||
|
on.forEach(itm => {
|
||||||
|
if (dataRowFiledName.value.includes(itm)) {
|
||||||
|
const ele = itm.slice(1, -1)
|
||||||
|
let value = dataRowNameSelect.value[ele] !== undefined ? dataRowNameSelect.value[ele] : null
|
||||||
|
let targetValue = !!value ? value : state.emptyValue
|
||||||
|
if (thresholdStyleInfo && thresholdStyleInfo[ele]) {
|
||||||
|
const thresholdStyle = thresholdStyleInfo[ele]
|
||||||
|
targetValue = `<span style="color:${thresholdStyle.color};background-color: ${thresholdStyle.backgroundColor}">${targetValue}</span>`
|
||||||
|
}
|
||||||
|
if (initReady.value) {
|
||||||
|
content = content.replace(itm, targetValue)
|
||||||
|
} else {
|
||||||
|
content = content.replace(itm, !!value ? targetValue : '[获取中...]')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
content = content.replace('class="base-selected"', '')
|
||||||
|
//De 本地跳转失效问题
|
||||||
|
content = content.replace(/href="#\//g, 'href="/#/')
|
||||||
|
content = content.replace(/href=\\"#\//g, 'href=\\"/#/')
|
||||||
|
content = content.replace(/href=\\"#\//g, 'href=\\"/#/')
|
||||||
|
resetSelect()
|
||||||
|
initFontFamily(content)
|
||||||
|
jumpTargetAdaptor()
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
const initFontFamily = htmlText => {
|
||||||
|
const regex = /font-family:\s*([^;"]+);/g
|
||||||
|
let match
|
||||||
|
while ((match = regex.exec(htmlText)) !== null) {
|
||||||
|
const font = match[1].trim()
|
||||||
|
if (systemFontFamily.includes(font)) {
|
||||||
|
appearanceStore.setCurrentFont(font)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const fieldSelect = field => {
|
||||||
|
const ed = tinymce.editors[tinymceId]
|
||||||
|
const fieldId = 'changeText-' + guid()
|
||||||
|
const value =
|
||||||
|
'<span id="' +
|
||||||
|
fieldId +
|
||||||
|
'"><span class="mceNonEditable" contenteditable="false" data-mce-content="[' +
|
||||||
|
field.name +
|
||||||
|
']">[' +
|
||||||
|
field.name +
|
||||||
|
']</span></span>'
|
||||||
|
const attachValue = '<span id="attachValue"> </span>'
|
||||||
|
ed.insertContent(value)
|
||||||
|
ed.insertContent(attachValue)
|
||||||
|
snapshotStore.resetStyleChangeTimes()
|
||||||
|
}
|
||||||
|
const onClick = () => {
|
||||||
|
if (canEdit.value) {
|
||||||
|
const node = tinymce.activeEditor.selection.getNode()
|
||||||
|
resetSelect(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const resetSelect = (node?) => {
|
||||||
|
const edInner = tinymce.get(tinymceId)
|
||||||
|
if (edInner?.dom) {
|
||||||
|
const nodeArray = edInner.dom.select('.base-selected')
|
||||||
|
if (nodeArray) {
|
||||||
|
nodeArray.forEach(nodeInner => {
|
||||||
|
nodeInner.removeAttribute('class')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (node) {
|
||||||
|
const pNode = node.parentElement
|
||||||
|
if (pNode && pNode.id && pNode.id.indexOf('changeText') > -1) {
|
||||||
|
const innerId = '#' + pNode.id
|
||||||
|
const domTest = edInner.dom.select(innerId)[0]
|
||||||
|
domTest.setAttribute('class', 'base-selected')
|
||||||
|
edInner.selection.select(domTest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const computedCanEdit = computed<boolean>(() => {
|
||||||
|
return (
|
||||||
|
['canvas', 'canvasDataV', 'edit'].includes(showPosition.value) &&
|
||||||
|
editStatus.value &&
|
||||||
|
canEdit.value === false &&
|
||||||
|
!isError.value &&
|
||||||
|
!disabled.value
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const showPlaceHolder = computed<boolean>(() => {
|
||||||
|
return (
|
||||||
|
computedCanEdit.value && (myValue.value == undefined || myValue.value == '') && !isError.value
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const editActive = computed<boolean>(() => {
|
||||||
|
if (element.value.canvasId.includes('Group') && !active.value) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const setEdit = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (computedCanEdit.value && editActive.value) {
|
||||||
|
canEdit.value = true
|
||||||
|
element.value['editing'] = true
|
||||||
|
myValue.value = element.value.propValue.textValue
|
||||||
|
const ed = tinymce.editors[tinymceId]
|
||||||
|
ed.setContent(myValue.value)
|
||||||
|
reShow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const reShow = () => {
|
||||||
|
editShow.value = false
|
||||||
|
nextTick(() => {
|
||||||
|
editShow.value = true
|
||||||
|
editCursor()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const editCursor = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const myDiv = document.getElementById(tinymceId)
|
||||||
|
// 让光标聚焦到文本末尾
|
||||||
|
const range = document.createRange()
|
||||||
|
const sel = window.getSelection()
|
||||||
|
if (myDiv.childNodes) {
|
||||||
|
range.setStart(myDiv.childNodes[myDiv.childNodes.length - 1], 1)
|
||||||
|
range.collapse(false)
|
||||||
|
sel.removeAllRanges()
|
||||||
|
sel.addRange(range)
|
||||||
|
}
|
||||||
|
// 对于一些浏览器,可能需要设置光标到最后的另一种方式
|
||||||
|
if (myDiv.focus) {
|
||||||
|
myDiv.focus()
|
||||||
|
}
|
||||||
|
tinymce.init({
|
||||||
|
selector: tinymceId,
|
||||||
|
plugins: 'table',
|
||||||
|
setup: function (editor) {
|
||||||
|
editor.on('init', function () {
|
||||||
|
console.info('====init====')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateEmptyValue = view => {
|
||||||
|
state.emptyValue =
|
||||||
|
view?.senior?.functionCfg?.emptyDataStrategy === 'custom'
|
||||||
|
? view.senior.functionCfg.emptyDataCustomValue || ''
|
||||||
|
: '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
const calcData = (view: Chart, callback) => {
|
||||||
|
isError.value = false
|
||||||
|
updateEmptyValue(view)
|
||||||
|
if (view.tableId || view['dataFrom'] === 'template') {
|
||||||
|
const v = JSON.parse(JSON.stringify(view))
|
||||||
|
getData(v)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code && res.code !== 0) {
|
||||||
|
isError.value = true
|
||||||
|
errMsg.value = res.msg
|
||||||
|
} else {
|
||||||
|
state.data = res?.data
|
||||||
|
state.viewDataInfo = res
|
||||||
|
state.totalItems = res?.totalItems
|
||||||
|
const curViewInfo = canvasViewInfo.value[element.value.id]
|
||||||
|
curViewInfo['curFields'] = res.data.fields
|
||||||
|
dvMainStore.setViewDataDetails(element.value.id, res)
|
||||||
|
initReady.value = true
|
||||||
|
initCurFields(res)
|
||||||
|
}
|
||||||
|
callback?.()
|
||||||
|
nextTick(() => {
|
||||||
|
initReady.value = true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
initReady.value = true
|
||||||
|
})
|
||||||
|
callback?.()
|
||||||
|
})
|
||||||
|
} else if (!view.tableId) {
|
||||||
|
state.data = []
|
||||||
|
state.viewDataInfo = {}
|
||||||
|
state.totalItems = 0
|
||||||
|
const curViewInfo = canvasViewInfo.value[element.value.id]
|
||||||
|
if (curViewInfo) {
|
||||||
|
curViewInfo['curFields'] = []
|
||||||
|
dvMainStore.setViewDataDetails(element.value.id, state.viewDataInfo)
|
||||||
|
initReady.value = true
|
||||||
|
initCurFields(curViewInfo)
|
||||||
|
}
|
||||||
|
initReady.value = true
|
||||||
|
callback?.()
|
||||||
|
nextTick(() => {
|
||||||
|
initReady.value = true
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
nextTick(() => {
|
||||||
|
initReady.value = true
|
||||||
|
})
|
||||||
|
callback?.()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initCurFields = chartDetails => {
|
||||||
|
dataRowFiledName.value = []
|
||||||
|
dataRowSelect.value = {}
|
||||||
|
dataRowNameSelect.value = {}
|
||||||
|
dataRowNameSelectSource.value = {} // 记录原格式,部分数字是经过格式化的,再匹配颜色时会有问题
|
||||||
|
if (chartDetails.data && chartDetails.data.sourceFields) {
|
||||||
|
const checkAllAxisStr =
|
||||||
|
JSON.stringify(chartDetails.xAxis) +
|
||||||
|
JSON.stringify(chartDetails.xAxisExt) +
|
||||||
|
JSON.stringify(chartDetails.yAxis) +
|
||||||
|
JSON.stringify(chartDetails.yAxisExt)
|
||||||
|
chartDetails.data.sourceFields.forEach(field => {
|
||||||
|
if (checkAllAxisStr.indexOf(field.id) > -1) {
|
||||||
|
dataRowFiledName.value.push(`[${field.name}]`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (checkAllAxisStr.indexOf('"记录数*"') > -1) {
|
||||||
|
dataRowFiledName.value.push(`[记录数*]`)
|
||||||
|
}
|
||||||
|
// Get the corresponding relationship between id and value
|
||||||
|
const nameIdMap = chartDetails.data.fields.reduce((pre, next) => {
|
||||||
|
pre[next['dataeaseName']] = next['id']
|
||||||
|
return pre
|
||||||
|
}, {})
|
||||||
|
const sourceFieldNameIdMap = chartDetails.data.fields.reduce((pre, next) => {
|
||||||
|
pre[next['dataeaseName']] = next['name']
|
||||||
|
return pre
|
||||||
|
}, {})
|
||||||
|
const rowData = chartDetails.data.tableRow[0]
|
||||||
|
if (chartDetails.type === 'rich-text') {
|
||||||
|
let yAxis = JSON.parse(JSON.stringify(chartDetails.yAxis))
|
||||||
|
const yDataeaseNames = []
|
||||||
|
const yDataeaseNamesCfg = []
|
||||||
|
yAxis.forEach(yItem => {
|
||||||
|
yDataeaseNames.push(yItem.dataeaseName)
|
||||||
|
yDataeaseNamesCfg[yItem.dataeaseName] = yItem.formatterCfg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const valueFieldMap: Record<string, Axis> = chartDetails.yAxis.reduce((p, n) => {
|
||||||
|
p[n.dataeaseName] = n
|
||||||
|
return p
|
||||||
|
}, {})
|
||||||
|
for (const key in rowData) {
|
||||||
|
dataRowSelect.value[nameIdMap[key]] = rowData[key]
|
||||||
|
let rowDataValue = rowData[key]
|
||||||
|
const rowDataValueSource = rowData[key]
|
||||||
|
const f = valueFieldMap[key]
|
||||||
|
if (f && f.formatterCfg) {
|
||||||
|
rowDataValue = valueFormatter(rowDataValue, f.formatterCfg)
|
||||||
|
}
|
||||||
|
dataRowNameSelect.value[sourceFieldNameIdMap[key]] = rowDataValue
|
||||||
|
dataRowNameSelectSource.value[sourceFieldNameIdMap[key]] = rowDataValueSource
|
||||||
|
}
|
||||||
|
}
|
||||||
|
element.value.propValue['innerType'] = chartDetails.type
|
||||||
|
element.value.propValue['render'] = chartDetails.render
|
||||||
|
if (chartDetails.type === 'rich-text') {
|
||||||
|
nextTick(() => {
|
||||||
|
initCurFieldsChange()
|
||||||
|
eventBus.emit('initCurFields-' + element.value.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化此处不必刷新
|
||||||
|
const renderChart = viewInfo => {
|
||||||
|
//do renderView
|
||||||
|
updateEmptyValue(viewInfo)
|
||||||
|
initCurFieldsChange()
|
||||||
|
eventBus.emit('initCurFields-' + element.value.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
const conditionAdaptor = (chart: Chart) => {
|
||||||
|
if (!chart || !chart.senior) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { threshold } = parseJson(chart.senior)
|
||||||
|
if (!threshold.enable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const res = {}
|
||||||
|
const conditions = threshold.tableThreshold ?? []
|
||||||
|
if (conditions?.length > 0) {
|
||||||
|
for (let i = 0; i < conditions.length; i++) {
|
||||||
|
const field = conditions[i]
|
||||||
|
let defaultValueColor = 'none'
|
||||||
|
let defaultBgColor = 'none'
|
||||||
|
res[field.field.name] = {
|
||||||
|
color: mappingColor(
|
||||||
|
dataRowNameSelectSource.value[field.field.name],
|
||||||
|
defaultValueColor,
|
||||||
|
field,
|
||||||
|
'color'
|
||||||
|
),
|
||||||
|
backgroundColor: mappingColor(
|
||||||
|
dataRowNameSelectSource.value[field.field.name],
|
||||||
|
defaultBgColor,
|
||||||
|
field,
|
||||||
|
'backgroundColor'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
const richTextStyle = computed(() => [{ '--de-canvas-scale': props.scale }])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
viewInit()
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
calcData,
|
||||||
|
renderChart
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.rich-main-class {
|
||||||
|
display: flex;
|
||||||
|
font-size: initial;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
position: relative;
|
||||||
|
div::-webkit-scrollbar {
|
||||||
|
width: 0px !important;
|
||||||
|
height: 0px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ol) {
|
||||||
|
display: block !important;
|
||||||
|
list-style-type: decimal;
|
||||||
|
margin-block-start: 1em !important;
|
||||||
|
margin-block-end: 1em !important;
|
||||||
|
margin-inline-start: 0px !important;
|
||||||
|
margin-inline-end: 0px !important;
|
||||||
|
padding-inline-start: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(ul) {
|
||||||
|
display: block !important;
|
||||||
|
list-style-type: disc;
|
||||||
|
margin-block-start: 1em !important;
|
||||||
|
margin-block-end: 1em !important;
|
||||||
|
margin-inline-start: 0px !important;
|
||||||
|
margin-inline-end: 0px !important;
|
||||||
|
padding-inline-start: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(li) {
|
||||||
|
margin-left: 20px;
|
||||||
|
display: list-item !important;
|
||||||
|
text-align: -webkit-match-parent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.base-selected) {
|
||||||
|
background-color: #b4d7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(p) {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-model {
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mceNonEditable {
|
||||||
|
background: rgba(51, 112, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tox-tinymce-inline {
|
||||||
|
left: var(--drawLeft);
|
||||||
|
right: var(--drawRight);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.tox {
|
||||||
|
border-radius: 4px !important;
|
||||||
|
border-bottom: 1px solid #ccc !important;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
.tox-tbtn {
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
.tox-collection__item-label {
|
||||||
|
p {
|
||||||
|
color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
h5 {
|
||||||
|
color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
h6 {
|
||||||
|
color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.rich-placeholder {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
|
||||||
|
color: #646a73;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 24px;
|
||||||
|
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
|
&.rich-placeholder--dark {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-text-content {
|
||||||
|
width: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
outline: none !important;
|
||||||
|
border: none !important;
|
||||||
|
ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, toRefs, PropType } from 'vue'
|
import { computed, toRefs, PropType, CSSProperties } from 'vue'
|
||||||
import Chart from '@/views/chart/components/views/index.vue'
|
import Chart from '@/views/chart/components/views/index.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -63,19 +63,11 @@ const props = defineProps({
|
|||||||
|
|
||||||
const { element, view, active, searchCount, scale } = toRefs(props)
|
const { element, view, active, searchCount, scale } = toRefs(props)
|
||||||
const autoStyle = computed(() => {
|
const autoStyle = computed(() => {
|
||||||
return {}
|
if (element.value.innerType === 'rich-text') {
|
||||||
// if (element.value.innerType === 'rich-text') {
|
return { zoom: scale.value }
|
||||||
// return {
|
} else {
|
||||||
// position: 'absolute',
|
return {}
|
||||||
// height: 100 / scale.value + '%!important',
|
}
|
||||||
// width: 100 / scale.value + '%!important',
|
|
||||||
// left: 50 * (1 - 1 / scale.value) + '%', // 放大余量 除以 2
|
|
||||||
// top: 50 * (1 - 1 / scale.value) + '%', // 放大余量 除以 2
|
|
||||||
// transform: 'scale(' + scale.value + ') translateZ(0)'
|
|
||||||
// } as CSSProperties
|
|
||||||
// } else {
|
|
||||||
// return {}
|
|
||||||
// }
|
|
||||||
})
|
})
|
||||||
const emits = defineEmits(['onPointClick'])
|
const emits = defineEmits(['onPointClick'])
|
||||||
|
|
||||||
|
@ -441,6 +441,11 @@ const resetData = () => {
|
|||||||
next.conditionValueS = next.defaultConditionValueS
|
next.conditionValueS = next.defaultConditionValueS
|
||||||
next.conditionValueOperatorS = next.defaultConditionValueOperatorS
|
next.conditionValueOperatorS = next.defaultConditionValueOperatorS
|
||||||
|
|
||||||
|
if (next.displayType === '22') {
|
||||||
|
next.numValueEnd = next.defaultNumValueEnd
|
||||||
|
next.numValueStart = next.defaultNumValueStart
|
||||||
|
}
|
||||||
|
|
||||||
if (!next.defaultValueCheck) {
|
if (!next.defaultValueCheck) {
|
||||||
next.defaultValue = next.multiple || +next.displayType === 7 ? [] : undefined
|
next.defaultValue = next.multiple || +next.displayType === 7 ? [] : undefined
|
||||||
}
|
}
|
||||||
@ -450,6 +455,19 @@ const resetData = () => {
|
|||||||
? [...next.defaultMapValue]
|
? [...next.defaultMapValue]
|
||||||
: next.defaultMapValue
|
: next.defaultMapValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
;(props.element.cascade || []).forEach(ele => {
|
||||||
|
ele.forEach(item => {
|
||||||
|
const comId = item.datasetId.split('--')[1]
|
||||||
|
if (next.id === comId) {
|
||||||
|
item.currentSelectValue = Array.isArray(next.selectValue)
|
||||||
|
? next.selectValue
|
||||||
|
: [next.selectValue].filter(itx => ![null, undefined].includes(itx))
|
||||||
|
useEmitt().emitter.emit(`${item.datasetId.split('--')[1]}-select`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
const keyList = Object.entries(next.checkedFieldsMap)
|
const keyList = Object.entries(next.checkedFieldsMap)
|
||||||
.filter(ele => next.checkedFields.includes(ele[0]))
|
.filter(ele => next.checkedFields.includes(ele[0]))
|
||||||
.filter(ele => !!ele[1])
|
.filter(ele => !!ele[1])
|
||||||
@ -461,6 +479,14 @@ const resetData = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const clearData = () => {
|
const clearData = () => {
|
||||||
|
;(props.element.cascade || []).forEach(ele => {
|
||||||
|
ele.forEach(item => {
|
||||||
|
if (item.currentSelectValue?.length) {
|
||||||
|
useEmitt().emitter.emit(`${item.datasetId.split('--')[1]}-select`)
|
||||||
|
item.currentSelectValue = []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
;(list.value || []).reduce((pre, next) => {
|
;(list.value || []).reduce((pre, next) => {
|
||||||
next.selectValue = next.multiple || +next.displayType === 7 ? [] : undefined
|
next.selectValue = next.multiple || +next.displayType === 7 ? [] : undefined
|
||||||
if (next.optionValueSource === 1 && next.defaultMapValue?.length) {
|
if (next.optionValueSource === 1 && next.defaultMapValue?.length) {
|
||||||
@ -468,6 +494,11 @@ const clearData = () => {
|
|||||||
}
|
}
|
||||||
next.conditionValueF = ''
|
next.conditionValueF = ''
|
||||||
next.conditionValueS = ''
|
next.conditionValueS = ''
|
||||||
|
|
||||||
|
if (next.displayType === '22') {
|
||||||
|
next.numValueEnd = undefined
|
||||||
|
next.numValueStart = undefined
|
||||||
|
}
|
||||||
const keyList = Object.entries(next.checkedFieldsMap)
|
const keyList = Object.entries(next.checkedFieldsMap)
|
||||||
.filter(ele => next.checkedFields.includes(ele[0]))
|
.filter(ele => next.checkedFields.includes(ele[0]))
|
||||||
.filter(ele => !!ele[1])
|
.filter(ele => !!ele[1])
|
||||||
|
@ -32,7 +32,7 @@ const props = defineProps({
|
|||||||
timeGranularityMultiple: {
|
timeGranularityMultiple: {
|
||||||
type: Object as PropType<DatePickType>,
|
type: Object as PropType<DatePickType>,
|
||||||
default: () => {
|
default: () => {
|
||||||
return 'yearrange'
|
return { type: 'yearrange' } as PropType<DatePickType>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -41,7 +41,7 @@ const props = defineProps({
|
|||||||
timeGranularityMultiple: {
|
timeGranularityMultiple: {
|
||||||
type: Object as PropType<DatePickType>,
|
type: Object as PropType<DatePickType>,
|
||||||
default: () => {
|
default: () => {
|
||||||
return 'yearrange'
|
return { type: 'yearrange' } as PropType<DatePickType>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import copilot from '@/assets/svg/copilot.svg'
|
import copilot from '@/assets/svg/copilot.svg'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
const { t } = useI18n()
|
||||||
const visible = ref(true)
|
const visible = ref(true)
|
||||||
const emits = defineEmits(['confirm'])
|
const emits = defineEmits(['confirm'])
|
||||||
|
|
||||||
@ -21,13 +23,13 @@ onMounted(() => {
|
|||||||
show-arrow
|
show-arrow
|
||||||
>
|
>
|
||||||
<div class="copilot-popper-tips-content">
|
<div class="copilot-popper-tips-content">
|
||||||
<p class="title">Copilot 对话分析</p>
|
<p class="title">{{ t('copilot.talking_analysis') }}</p>
|
||||||
<p class="constant">
|
<p class="constant">
|
||||||
你好,我是 Copilot 对话分析
|
{{ t('copilot.hello') }}
|
||||||
<br />点击一下,开启可视化图表解答模式~<br />
|
<br />{{ t('copilot.click_talk') }}<br />
|
||||||
</p>
|
</p>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<el-button size="middle" @click="confirm"> 我知道了 </el-button>
|
<el-button size="middle" @click="confirm"> {{ t('copilot.know') }} </el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
|
@ -36,6 +36,136 @@ export default {
|
|||||||
delete_success: 'Delete success',
|
delete_success: 'Delete success',
|
||||||
no_auth_tips: 'Missing menu permissions, please contact the administrator'
|
no_auth_tips: 'Missing menu permissions, please contact the administrator'
|
||||||
},
|
},
|
||||||
|
commons: {
|
||||||
|
date: {
|
||||||
|
permanent: 'Permanent',
|
||||||
|
one_year: 'One year',
|
||||||
|
six_months: 'Six months',
|
||||||
|
three_months: 'Three months',
|
||||||
|
of_range_1_59: 'Minutes out of range [1-59]',
|
||||||
|
of_range_1_23: 'Hours out of range [1-23]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
system: {
|
||||||
|
click_to_show: 'Click to show',
|
||||||
|
click_to_hide: 'Click to hide',
|
||||||
|
basic_settings: 'Basic settings',
|
||||||
|
and_0_seconds: '0 minutes and 0 seconds',
|
||||||
|
time_0_seconds: 'Minutes (execution time: 0 seconds)',
|
||||||
|
and_0_seconds_de: 'Hours (execution time: 0 minutes and 0 seconds)',
|
||||||
|
fonts_before_deleting: 'Please set other fonts as default fonts before deleting.',
|
||||||
|
sure_to_delete:
|
||||||
|
'After the current font is deleted, the components using the font will use the default font. Are you sure to delete?',
|
||||||
|
setting_successful: 'Setting successful',
|
||||||
|
font_management: 'Font management',
|
||||||
|
search_font_name: 'Search font name',
|
||||||
|
a_new_font: 'Create a new font',
|
||||||
|
add_font: 'Add font',
|
||||||
|
default_font: 'Default font',
|
||||||
|
system_built_in: 'System built-in',
|
||||||
|
update_time: 'Update time:',
|
||||||
|
font_file: 'Font file:',
|
||||||
|
upload_font_file: 'Upload font file',
|
||||||
|
replace_font_file: 'Replace font file',
|
||||||
|
as_default_font: 'Set as default font',
|
||||||
|
the_font_name: 'Please enter the font name',
|
||||||
|
in_ttf_format: 'Only supports uploading font files in ttf format!',
|
||||||
|
character_length_1_50: 'Character length 1-50',
|
||||||
|
upload_font_file_de: 'Please upload font file',
|
||||||
|
font_name: 'Font name',
|
||||||
|
font_file_de: 'Font file',
|
||||||
|
be_the_same: 'New and old passwords cannot be the same',
|
||||||
|
twice_are_inconsistent: 'The passwords entered twice are inconsistent',
|
||||||
|
log_in_again: 'Change successfully, please log in again',
|
||||||
|
original_password: 'Original password',
|
||||||
|
the_original_password: 'Please enter the original password',
|
||||||
|
new_password: 'New password',
|
||||||
|
the_new_password: 'Please enter the new password',
|
||||||
|
confirm_password: 'Confirm password',
|
||||||
|
the_confirmation_password: 'Please enter the confirmation password',
|
||||||
|
map_settings: 'Map settings',
|
||||||
|
engine_settings: 'Engine settings',
|
||||||
|
normal_login: 'Normal login',
|
||||||
|
to_take_effect:
|
||||||
|
'Request timeout (unit: seconds, note: save and refresh the browser to take effect)',
|
||||||
|
and_platform_docking: 'Scope includes authentication settings and platform docking',
|
||||||
|
not_enabled: 'Not enabled',
|
||||||
|
default_organization: 'Default organization',
|
||||||
|
normal_role: 'Normal role',
|
||||||
|
engine_type: 'Engine type',
|
||||||
|
on_the_left: 'Please select a region on the left',
|
||||||
|
region_code: 'Region code',
|
||||||
|
superior_region: 'Superior region',
|
||||||
|
coordinate_file: 'Coordinate file',
|
||||||
|
delete_this_node: 'Are you sure you want to delete this node?',
|
||||||
|
at_the_end:
|
||||||
|
'Country code consists of three digits, province, city, district, county, and township codes consist of two digits; non-national regions need to add 0 at the end',
|
||||||
|
non_zero_three_digit_number: 'Please enter a non-zero three-digit number',
|
||||||
|
or_11_digits: 'Please enter 9 or 11 digits',
|
||||||
|
contact_the_administrator: 'If execution fails, please contact the administrator',
|
||||||
|
upload_json_files: 'Can only upload json files',
|
||||||
|
maximum_upload_200m: 'Maximum upload 200M',
|
||||||
|
geographic_information: 'Geographic information',
|
||||||
|
superior_region_first: 'Please select the superior region first',
|
||||||
|
region_name: 'Region name',
|
||||||
|
appearance_configuration: 'Appearance configuration',
|
||||||
|
platform_display_theme: 'Platform display theme',
|
||||||
|
navigation_background_color: 'Top navigation background color',
|
||||||
|
dark_color: 'Dark color',
|
||||||
|
light_color: 'Light color',
|
||||||
|
theme_color: 'Theme color',
|
||||||
|
default_blue: 'Default (blue)',
|
||||||
|
custom_color_value: 'Custom color value',
|
||||||
|
platform_login_settings: 'Platform login settings',
|
||||||
|
page_preview: 'Page preview',
|
||||||
|
restore_default: 'Restore default',
|
||||||
|
supports_custom_settings: 'Default is DataEase login interface, supports custom settings',
|
||||||
|
replace_image: 'Replace image',
|
||||||
|
website_name: 'Website name',
|
||||||
|
web_page_tab: 'Platform name displayed on web page tab',
|
||||||
|
under_product_logo: 'Slogan under product logo',
|
||||||
|
footer: 'Footer',
|
||||||
|
footer_content: 'Footer content',
|
||||||
|
platform_settings: 'Platform settings',
|
||||||
|
top_navigation_logo: 'Top navigation logo',
|
||||||
|
not_exceeding_200kb:
|
||||||
|
'Logo displayed in top navigation menu; recommended size 134 x 34, supports JPG, PNG, size not exceeding 200KB',
|
||||||
|
help_document: 'Help document',
|
||||||
|
ai_assistant_button: 'AI assistant button',
|
||||||
|
copilot_button: 'Copilot button',
|
||||||
|
document_button: 'Document button',
|
||||||
|
about_button: 'About button',
|
||||||
|
mobile_login_settings: 'Mobile login settings',
|
||||||
|
user_login: 'User login',
|
||||||
|
in_user_name: 'Please fill in user name',
|
||||||
|
fill_in_password: 'Please fill in password',
|
||||||
|
supports_custom_settings_de:
|
||||||
|
'Default is DataEase mobile login interface, supports custom settings',
|
||||||
|
login_logo: 'Login Logo',
|
||||||
|
platform: 'The default interface is DataEase platform, which supports customized settings',
|
||||||
|
not_exceeding_200kb_de:
|
||||||
|
'Logo on the right side of the login page, recommended size 120*30, supports JPG, PNG, SVG, size not exceeding 200KB',
|
||||||
|
login_background_image: 'Login background image',
|
||||||
|
not_exceeding_5m:
|
||||||
|
'Background image on the left, recommended size 375*480 for vector graphics, recommended size 1125*1440 for bitmaps; supports JPG, PNG, SVG, size not exceeding 5M',
|
||||||
|
hidden_in_iframe: 'Hidden in Iframe',
|
||||||
|
available_to_everyone: 'Open source BI tool available to everyone',
|
||||||
|
the_website_name: 'Please enter the website name',
|
||||||
|
enter_the_slogan: 'Please enter the slogan',
|
||||||
|
the_help_document: 'Please enter the help document',
|
||||||
|
assistant: 'Please choose whether to display the AI assistant',
|
||||||
|
to_display_copilot: 'Please choose whether to display Copilot',
|
||||||
|
display_the_document: 'Please choose whether to display the document',
|
||||||
|
display_the_about: 'Please choose whether to display the about',
|
||||||
|
website_logo: 'Website Logo',
|
||||||
|
not_exceeding_200kb_de_:
|
||||||
|
'The logo displayed on the top website, recommended size 48 x 48, support JPG, PNG, SVG, size not exceeding 200KB',
|
||||||
|
not_exceeding_200kb_de_right:
|
||||||
|
'Logo on the right side of the login page, recommended size 204 x 52, support JPG, PNG, SVG, size not exceeding 200KB',
|
||||||
|
not_exceeding_5m_de:
|
||||||
|
'Background image on the left, recommended size 640 x 900 for vector graphics, recommended size 1280 x 1800 for bitmaps; support JPG, PNG, SVG, size not exceeding 5M',
|
||||||
|
tab: 'Tab'
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
dashboard_style: 'Dashboard style',
|
dashboard_style: 'Dashboard style',
|
||||||
overall_configuration: 'Overall configuration',
|
overall_configuration: 'Overall configuration',
|
||||||
@ -333,9 +463,46 @@ export default {
|
|||||||
pwd_format: 'Length should be 5 to 15'
|
pwd_format: 'Length should be 5 to 15'
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
change_password: 'Change password'
|
change_password: 'Change password',
|
||||||
|
feishu: 'Feishu',
|
||||||
|
dingtalk: 'DingTalk',
|
||||||
|
wechat_for_business: 'WeChat for Business',
|
||||||
|
international_feishu: 'International Feishu',
|
||||||
|
user_management: 'User Management',
|
||||||
|
cannot_be_modified: 'System Administrator Status cannot be modified',
|
||||||
|
cannot_be_modified_de: 'Current User Status cannot be modified',
|
||||||
|
has_been_disabled: 'User has been disabled',
|
||||||
|
selected_user: 'Selected: {msg} user',
|
||||||
|
cannot_be_empty: 'Variable cannot be empty!',
|
||||||
|
set_variable_value: 'Please set variable value:',
|
||||||
|
be_an_integer: 'Variable value must be an integer:',
|
||||||
|
be_less_than: 'Cannot be less than:',
|
||||||
|
be_greater_than: 'Cannot be greater than:',
|
||||||
|
than_start_time: ', cannot be less than start time:',
|
||||||
|
than_end_time: ', cannot be greater than end time:',
|
||||||
|
variable: 'Variable',
|
||||||
|
variable_value: 'Variable value',
|
||||||
|
enter_a_value: 'Please enter a value',
|
||||||
|
contact_the_administrator: 'If execution fails, please contact the administrator',
|
||||||
|
data_import_successful: 'Data import successful',
|
||||||
|
imported_1_data: 'Successfully imported {msg} data',
|
||||||
|
import_1_data: ', failed to import {msg} data',
|
||||||
|
can: 'Can',
|
||||||
|
download_error_report: 'Download error report',
|
||||||
|
modify_and_re_import: ', modify and re-import',
|
||||||
|
return_to_view: 'Return to view',
|
||||||
|
continue_importing: 'Continue importing',
|
||||||
|
data_import_failed: 'Partial data import failed',
|
||||||
|
data_import_failed_de: 'Data import failed'
|
||||||
},
|
},
|
||||||
org: {
|
org: {
|
||||||
|
resource_migration: 'Resource migration',
|
||||||
|
migration_type: 'Migration type',
|
||||||
|
migrate_resources_only: 'Migrate resources only',
|
||||||
|
and_authorization_related: 'Migrate resources and authorization related',
|
||||||
|
target_organization: 'Target organization',
|
||||||
|
target_directory: 'Target directory',
|
||||||
|
resource_type: 'Resource type',
|
||||||
org_title: 'Organization',
|
org_title: 'Organization',
|
||||||
org_move: 'Migration',
|
org_move: 'Migration',
|
||||||
add: 'Add',
|
add: 'Add',
|
||||||
@ -349,6 +516,11 @@ export default {
|
|||||||
admin_parent_tips: '(default root organization)'
|
admin_parent_tips: '(default root organization)'
|
||||||
},
|
},
|
||||||
auth: {
|
auth: {
|
||||||
|
permission_configuration: 'Permission configuration',
|
||||||
|
was_not_obtained: 'The resource node was not obtained',
|
||||||
|
search_name: 'Search name',
|
||||||
|
loading: 'Loading...',
|
||||||
|
on_the_left: 'Please select the node on the left',
|
||||||
row_column: 'Row and column permission settings',
|
row_column: 'Row and column permission settings',
|
||||||
row_permission: 'Row permission rules',
|
row_permission: 'Row permission rules',
|
||||||
enable_row: 'Enable row permissions',
|
enable_row: 'Enable row permissions',
|
||||||
@ -435,6 +607,42 @@ export default {
|
|||||||
new_folder: 'New Folder',
|
new_folder: 'New Folder',
|
||||||
form_manage: 'Form Manage',
|
form_manage: 'Form Manage',
|
||||||
my_job: 'My Job',
|
my_job: 'My Job',
|
||||||
|
disable_data_fill_hint:
|
||||||
|
'After closing Data Filling, the form data will fail to submit. Are you sure you want to close?',
|
||||||
|
enable_data_fill_hint:
|
||||||
|
'After enabled, it allows for the creation of new tables in the data source database, and stores form data into these tables.',
|
||||||
|
todo: 'Todo',
|
||||||
|
finished: 'Finished',
|
||||||
|
expired: 'Expired',
|
||||||
|
required_select: 'Required',
|
||||||
|
condition: 'Condition',
|
||||||
|
add_condition: 'Add condition',
|
||||||
|
disable_edit: 'Non-editable',
|
||||||
|
enable_edit: 'Editable',
|
||||||
|
select_component: 'Select component',
|
||||||
|
set_condition: 'Set condition',
|
||||||
|
move_to: 'Move to',
|
||||||
|
rename: 'Rename',
|
||||||
|
delete: 'Delete',
|
||||||
|
move_success: 'Move success',
|
||||||
|
rename_success: 'Rename success',
|
||||||
|
create_success: 'Create success',
|
||||||
|
create_form: 'Create Form',
|
||||||
|
create_folder: 'Create Folder',
|
||||||
|
order_by_create_time_asc: 'Order by create time asc',
|
||||||
|
order_by_create_time_desc: 'Order by create time desc',
|
||||||
|
order_by_name_asc: 'Order by name asc',
|
||||||
|
order_by_name_desc: 'Order by name desc',
|
||||||
|
delete_folder_hint:
|
||||||
|
'After deletion, all resources under this folder will be removed. Please proceed with caution.',
|
||||||
|
confirm_delete_folder: 'Confirm to delete folder',
|
||||||
|
confirm_delete_form: 'Confirm to delete form',
|
||||||
|
confirm_delete_multiple_data: 'Confirm to delete {0} data?',
|
||||||
|
confirm_delete_data: 'Confirm to delete data?',
|
||||||
|
no_form: 'No form',
|
||||||
|
on_the_left: 'Select form on the left side',
|
||||||
|
exporting: 'During exporting, you can goto ',
|
||||||
|
progress_to_download: 'to see progress, and download',
|
||||||
form: {
|
form: {
|
||||||
mobile_number_format_is_incorrect: 'Incorrect format of mobile phone number',
|
mobile_number_format_is_incorrect: 'Incorrect format of mobile phone number',
|
||||||
email_format_is_incorrect: 'The mailbox format is incorrect',
|
email_format_is_incorrect: 'The mailbox format is incorrect',
|
||||||
@ -545,6 +753,8 @@ export default {
|
|||||||
datetime: 'Datetime'
|
datetime: 'Datetime'
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
data_not_exists: 'Data dose not exists',
|
||||||
|
cannot_select_all: 'Cannot select all',
|
||||||
commit_time: 'Commit Time',
|
commit_time: 'Commit Time',
|
||||||
confirm_delete: 'Confirm delete?',
|
confirm_delete: 'Confirm delete?',
|
||||||
add_data: 'Add Data',
|
add_data: 'Add Data',
|
||||||
@ -562,6 +772,23 @@ export default {
|
|||||||
data_not_found: '] Not Found'
|
data_not_found: '] Not Found'
|
||||||
},
|
},
|
||||||
task: {
|
task: {
|
||||||
|
time_check_5_minute_later_than_current:
|
||||||
|
'Cannot be earlier than 5 minutes after the current time.',
|
||||||
|
time_check_later_than_current: 'Cannot be earlier than the current time.',
|
||||||
|
time_check_earlier_than_end: 'Cannot be later than the end time.',
|
||||||
|
time_check_later_than_start: 'Cannot be earlier than the start time.',
|
||||||
|
confirm_exit_without_save:
|
||||||
|
'The current changes have not been saved. Are you sure you want to exit?',
|
||||||
|
deliver_now: 'Deliver now',
|
||||||
|
deliver_scheduled: 'Deliver by schedule',
|
||||||
|
logic_filter: 'Logic filter',
|
||||||
|
enum_filter: 'Enum filter',
|
||||||
|
cannot_be_all_disabled: 'Not all components can be disabled.',
|
||||||
|
template_hint_title: 'The settings instructions are as follows',
|
||||||
|
template_hint_1:
|
||||||
|
'When a component is set to be non-editable, users are not allowed to modify it when filling out the form.',
|
||||||
|
template_hint_2:
|
||||||
|
'When a component is set to be editable, users are allowed to modify it when filling out the form.',
|
||||||
finish_rate_hint: 'Finished Rate = Finished Task Count / Assigned Task Count * 100%',
|
finish_rate_hint: 'Finished Rate = Finished Task Count / Assigned Task Count * 100%',
|
||||||
distribute_frequency: 'Distribute Frequency',
|
distribute_frequency: 'Distribute Frequency',
|
||||||
one_time: 'One Time',
|
one_time: 'One Time',
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -391,7 +391,122 @@ export default {
|
|||||||
system: {
|
system: {
|
||||||
user: '用户',
|
user: '用户',
|
||||||
role: '角色',
|
role: '角色',
|
||||||
addUser: '@:common.add@:system.user'
|
addUser: '@:common.add@:system.user',
|
||||||
|
click_to_show: '点击显示',
|
||||||
|
click_to_hide: '点击隐藏',
|
||||||
|
basic_settings: '基础设置',
|
||||||
|
and_0_seconds: '0分0秒',
|
||||||
|
time_0_seconds: '分钟(执行时间:0秒)',
|
||||||
|
and_0_seconds_de: '小时(执行时间:0分0秒)',
|
||||||
|
fonts_before_deleting: '请先将其他字体设置为默认字体,再进行删除。',
|
||||||
|
sure_to_delete: '当前字体被删除后,使用该字体的组件将会使用默认字体,确定删除?',
|
||||||
|
setting_successful: '设置成功',
|
||||||
|
font_management: '字体管理',
|
||||||
|
search_font_name: '搜索字体名称',
|
||||||
|
a_new_font: '新建字体',
|
||||||
|
add_font: '添加字体',
|
||||||
|
default_font: '默认字体',
|
||||||
|
system_built_in: '系统内置',
|
||||||
|
update_time: '更新时间:',
|
||||||
|
font_file: '字库文件:',
|
||||||
|
upload_font_file: '上传字库文件',
|
||||||
|
replace_font_file: '替换字库文件',
|
||||||
|
as_default_font: '设为默认字体',
|
||||||
|
the_font_name: '请输入字体名称',
|
||||||
|
in_ttf_format: '只支持上传ttf格式的字体文件!',
|
||||||
|
character_length_1_50: '字符长度1-50',
|
||||||
|
upload_font_file_de: '请上传字库文件',
|
||||||
|
font_name: '字体名称',
|
||||||
|
font_file_de: '字库文件',
|
||||||
|
be_the_same: '新旧密码不能相同',
|
||||||
|
twice_are_inconsistent: '两次输入的密码不一致',
|
||||||
|
log_in_again: '修改成功,请重新登录',
|
||||||
|
original_password: '原始密码',
|
||||||
|
the_original_password: '请输入原始密码',
|
||||||
|
new_password: '新密码',
|
||||||
|
the_new_password: '请输入新密码',
|
||||||
|
confirm_password: '确认密码',
|
||||||
|
the_confirmation_password: '请输入确认密码',
|
||||||
|
map_settings: '地图设置',
|
||||||
|
engine_settings: '引擎设置',
|
||||||
|
normal_login: '普通登录',
|
||||||
|
to_take_effect: '请求超时时间(单位:秒,注意:保存后刷新浏览器生效)',
|
||||||
|
and_platform_docking: '作用域包括认证设置和平台对接',
|
||||||
|
not_enabled: '未开启',
|
||||||
|
default_organization: '默认组织',
|
||||||
|
normal_role: '普通角色',
|
||||||
|
engine_type: '引擎类型',
|
||||||
|
on_the_left: '请在左侧选择区域',
|
||||||
|
region_code: '区域代码',
|
||||||
|
superior_region: '上级区域',
|
||||||
|
coordinate_file: '坐标文件',
|
||||||
|
delete_this_node: '确定删除此节点吗',
|
||||||
|
at_the_end:
|
||||||
|
'国家代码由三位数字组成,省、市、区县、乡镇代码由两位数字组成;非国家区域需要再后面补0',
|
||||||
|
non_zero_three_digit_number: '请输入非0的三位数字',
|
||||||
|
or_11_digits: '请输入9或11位数字',
|
||||||
|
contact_the_administrator: '执行失败请联系管理员',
|
||||||
|
upload_json_files: '只能上传json文件',
|
||||||
|
maximum_upload_200m: '最大上传200M',
|
||||||
|
geographic_information: '地理信息',
|
||||||
|
superior_region_first: '请先选择上级区域',
|
||||||
|
region_name: '区域名称',
|
||||||
|
appearance_configuration: '外观配置',
|
||||||
|
platform_display_theme: '平台显示主题',
|
||||||
|
navigation_background_color: '顶部导航背景色',
|
||||||
|
dark_color: '暗色',
|
||||||
|
light_color: '浅色',
|
||||||
|
theme_color: '主题色',
|
||||||
|
default_blue: '默认 (蓝色) ',
|
||||||
|
custom_color_value: '自定义色值',
|
||||||
|
platform_login_settings: '平台登录设置',
|
||||||
|
page_preview: '页面预览',
|
||||||
|
restore_default: '恢复默认',
|
||||||
|
platform: '默认为 {msg} 平台界面,支持自定义设置',
|
||||||
|
supports_custom_settings: '默认为 {msg} 登录界面,支持自定义设置',
|
||||||
|
replace_image: '替换图片',
|
||||||
|
website_name: '网站名称',
|
||||||
|
web_page_tab: '显示在网页 Tab 的平台名称',
|
||||||
|
under_product_logo: '产品 Logo 下的 Slogan',
|
||||||
|
footer: '页脚',
|
||||||
|
footer_content: '页脚内容',
|
||||||
|
platform_settings: '平台设置',
|
||||||
|
top_navigation_logo: '顶部导航 Logo',
|
||||||
|
not_exceeding_200kb:
|
||||||
|
'顶部导航菜单显示的 Logo;建议尺寸 134 x 34,支持JPG、PNG,大小不超过 200KB',
|
||||||
|
help_document: '帮助文档',
|
||||||
|
ai_assistant_button: 'AI 助手按钮',
|
||||||
|
copilot_button: 'Copilot 按钮',
|
||||||
|
document_button: '文档按钮',
|
||||||
|
about_button: '关于按钮',
|
||||||
|
mobile_login_settings: '移动端登录设置',
|
||||||
|
user_login: '用户登录',
|
||||||
|
in_user_name: '请填写用户名',
|
||||||
|
fill_in_password: '请填写密码',
|
||||||
|
supports_custom_settings_de: '默认为 {msg} 移动端登录界面,支持自定义设置',
|
||||||
|
login_logo: '登录 Logo',
|
||||||
|
not_exceeding_200kb_de:
|
||||||
|
'登录页面右侧 Logo,建议尺寸 120*30,支持 JPG、PNG、SVG,大小不超过 200KB',
|
||||||
|
login_background_image: '登录背景图',
|
||||||
|
not_exceeding_5m:
|
||||||
|
'左侧背景图,矢量图建议尺寸375*480,位图建议尺寸1125*1440;支持 JPG、PNG、SVG,大小不超过5M',
|
||||||
|
hidden_in_iframe: 'Iframe中隐藏',
|
||||||
|
available_to_everyone: '人人可用的开源 BI 工具',
|
||||||
|
the_website_name: '请输入网站名称',
|
||||||
|
enter_the_slogan: '请输入Slogan',
|
||||||
|
the_help_document: '请输入帮助文档',
|
||||||
|
assistant: '请选择是否展示AI助手',
|
||||||
|
to_display_copilot: '请选择是否展示Copilot',
|
||||||
|
display_the_document: '请选择是否展示文档',
|
||||||
|
display_the_about: '请选择是否展示关于',
|
||||||
|
website_logo: '网站 Logo',
|
||||||
|
not_exceeding_200kb_de_:
|
||||||
|
'顶部网站显示的 Logo,建议尺寸 48 x 48,支持 JPG、PNG、SVG,大小不超过 200KB',
|
||||||
|
not_exceeding_200kb_de_right:
|
||||||
|
'登录页面右侧 Logo,建议尺寸 204 x 52,支持 JPG、PNG、SVG,大小不超过 200KB',
|
||||||
|
not_exceeding_5m_de:
|
||||||
|
'左侧背景图,矢量图建议尺寸 640 x 900,位图建议尺寸 1280 x 1800;支持 JPG、PNG、SVG,大小不超过 5M',
|
||||||
|
tab: '页签'
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
dashboard_style: '仪表板风格',
|
dashboard_style: '仪表板风格',
|
||||||
@ -455,7 +570,37 @@ export default {
|
|||||||
phone_format: '请填写正确格式手机号',
|
phone_format: '请填写正确格式手机号',
|
||||||
email_format_is_incorrect: '请填写正确格式邮箱',
|
email_format_is_incorrect: '请填写正确格式邮箱',
|
||||||
enable_success: '已启用',
|
enable_success: '已启用',
|
||||||
disable_success: '已禁用'
|
disable_success: '已禁用',
|
||||||
|
feishu: '飞书',
|
||||||
|
dingtalk: '钉钉',
|
||||||
|
wechat_for_business: '企业微信',
|
||||||
|
international_feishu: '国际飞书',
|
||||||
|
user_management: '用户管理',
|
||||||
|
cannot_be_modified: '系统管理员状态不可修改',
|
||||||
|
cannot_be_modified_de: '不能修改当前用户状态',
|
||||||
|
has_been_disabled: '用户已被禁用',
|
||||||
|
selected_user: '已选: {msg} 个用户',
|
||||||
|
cannot_be_empty: '变量不能为空!',
|
||||||
|
set_variable_value: '请设置变量值:',
|
||||||
|
be_an_integer: '变量值必须为整数:',
|
||||||
|
be_less_than: '不能小于:',
|
||||||
|
be_greater_than: '不能大于:',
|
||||||
|
than_start_time: ',不能小于开始时间:',
|
||||||
|
than_end_time: ',不能大于结束时间:',
|
||||||
|
variable: '变量',
|
||||||
|
variable_value: '变量值',
|
||||||
|
enter_a_value: '请输入数值',
|
||||||
|
contact_the_administrator: '执行失败请联系管理员',
|
||||||
|
data_import_successful: '导入数据成功',
|
||||||
|
imported_1_data: '成功导入数据 {msg} 条',
|
||||||
|
import_1_data: ',导入失败 {msg} 条 ',
|
||||||
|
can: '可',
|
||||||
|
download_error_report: '下载错误报告',
|
||||||
|
modify_and_re_import: ',修改后重新导入',
|
||||||
|
return_to_view: '返回查看',
|
||||||
|
continue_importing: '继续导入',
|
||||||
|
data_import_failed: '部分数据导入失败',
|
||||||
|
data_import_failed_de: '数据导入失败'
|
||||||
},
|
},
|
||||||
userimport: {
|
userimport: {
|
||||||
buttonText: '批量导入',
|
buttonText: '批量导入',
|
||||||
@ -516,6 +661,15 @@ export default {
|
|||||||
empty_description: '请先选择左侧角色'
|
empty_description: '请先选择左侧角色'
|
||||||
},
|
},
|
||||||
org: {
|
org: {
|
||||||
|
resource_migration: '资源迁移',
|
||||||
|
migration_type: '迁移类型',
|
||||||
|
migrate_resources_only: '仅迁移资源',
|
||||||
|
and_authorization_related: '迁移资源及授权相关',
|
||||||
|
target_organization: '目标组织',
|
||||||
|
target_directory: '目标目录',
|
||||||
|
resource_type: '资源类型',
|
||||||
|
user_dimension: '按用户配置',
|
||||||
|
resource_dimension: '按资源配置',
|
||||||
org_title: '组织管理',
|
org_title: '组织管理',
|
||||||
org_move: '组织迁移',
|
org_move: '组织迁移',
|
||||||
add: '添加组织',
|
add: '添加组织',
|
||||||
@ -537,6 +691,11 @@ export default {
|
|||||||
please_login_per_changed: '当前用户权限已变更,请重新登录'
|
please_login_per_changed: '当前用户权限已变更,请重新登录'
|
||||||
},
|
},
|
||||||
auth: {
|
auth: {
|
||||||
|
permission_configuration: '权限配置',
|
||||||
|
was_not_obtained: '未获取到资源节点',
|
||||||
|
search_name: '搜索名称',
|
||||||
|
loading: '加载中···',
|
||||||
|
on_the_left: '请选择左侧节点',
|
||||||
sysParams_type: {
|
sysParams_type: {
|
||||||
user_id: '账号',
|
user_id: '账号',
|
||||||
user_name: '姓名',
|
user_name: '姓名',
|
||||||
@ -546,8 +705,6 @@ export default {
|
|||||||
dept: '组织',
|
dept: '组织',
|
||||||
role: '角色'
|
role: '角色'
|
||||||
},
|
},
|
||||||
user_dimension: '按用户配置',
|
|
||||||
resource_dimension: '按资源配置',
|
|
||||||
user: '用户',
|
user: '用户',
|
||||||
role: '角色',
|
role: '角色',
|
||||||
resource: '资源权限',
|
resource: '资源权限',
|
||||||
@ -2142,7 +2299,13 @@ export default {
|
|||||||
data_time_error: '开始日期不能大于结束日期',
|
data_time_error: '开始日期不能大于结束日期',
|
||||||
one_day: '一天',
|
one_day: '一天',
|
||||||
one_week: '一周',
|
one_week: '一周',
|
||||||
one_month: '一个月'
|
one_month: '一个月',
|
||||||
|
permanent: '永久',
|
||||||
|
one_year: '一年',
|
||||||
|
six_months: '半年',
|
||||||
|
three_months: '三个月',
|
||||||
|
of_range_1_59: '分钟超出范围【1-59】',
|
||||||
|
of_range_1_23: '小时超出范围【1-23】'
|
||||||
},
|
},
|
||||||
adv_search: {
|
adv_search: {
|
||||||
title: '高级搜索',
|
title: '高级搜索',
|
||||||
@ -2776,6 +2939,39 @@ export default {
|
|||||||
new_folder: '新建文件夹',
|
new_folder: '新建文件夹',
|
||||||
form_manage: '表单管理',
|
form_manage: '表单管理',
|
||||||
my_job: '我的填报',
|
my_job: '我的填报',
|
||||||
|
disable_data_fill_hint: '关闭数据填报后,表单数据将提交失败,确定关闭?',
|
||||||
|
enable_data_fill_hint: '启用后,允许在数据源数据库中新建表,并将表单数据存放至表中',
|
||||||
|
todo: '待填报',
|
||||||
|
finished: '已填报',
|
||||||
|
expired: '已过期',
|
||||||
|
required_select: '必选',
|
||||||
|
condition: '过滤值',
|
||||||
|
add_condition: '添加条件',
|
||||||
|
disable_edit: '禁止编辑',
|
||||||
|
enable_edit: '允许编辑',
|
||||||
|
select_component: '请选择组件',
|
||||||
|
set_condition: '设置条件',
|
||||||
|
move_to: '移动到',
|
||||||
|
rename: '重命名',
|
||||||
|
delete: '删除',
|
||||||
|
move_success: '移动成功',
|
||||||
|
rename_success: '重命名成功',
|
||||||
|
create_success: '新建成功',
|
||||||
|
create_form: '新建表单',
|
||||||
|
create_folder: '新建文件夹',
|
||||||
|
order_by_create_time_asc: '按创建时间升序',
|
||||||
|
order_by_create_time_desc: '按创建时间降序',
|
||||||
|
order_by_name_asc: '按照名称升序',
|
||||||
|
order_by_name_desc: '按照名称降序',
|
||||||
|
delete_folder_hint: '删除后,此文件夹下的所有资源都会被删除,请谨慎操作。',
|
||||||
|
confirm_delete_folder: '确定删除该文件夹吗',
|
||||||
|
confirm_delete_form: '确定删除该表单吗',
|
||||||
|
confirm_delete_multiple_data: '确定删除 {0} 条数据吗?',
|
||||||
|
confirm_delete_data: '确定删除数据?',
|
||||||
|
no_form: '暂无表单',
|
||||||
|
on_the_left: '请在左侧选择表单',
|
||||||
|
exporting: '后台导出中,可前往',
|
||||||
|
progress_to_download: '查看进度,进行下载',
|
||||||
form: {
|
form: {
|
||||||
mobile_number_format_is_incorrect: '手机号码格式不正确',
|
mobile_number_format_is_incorrect: '手机号码格式不正确',
|
||||||
email_format_is_incorrect: '邮箱格式不正确',
|
email_format_is_incorrect: '邮箱格式不正确',
|
||||||
@ -2885,6 +3081,8 @@ export default {
|
|||||||
datetime: '日期'
|
datetime: '日期'
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
data_not_exists: '数据不存在',
|
||||||
|
cannot_select_all: '不能全选',
|
||||||
commit_time: '提交时间',
|
commit_time: '提交时间',
|
||||||
confirm_delete: '确认删除?',
|
confirm_delete: '确认删除?',
|
||||||
add_data: '添加数据',
|
add_data: '添加数据',
|
||||||
@ -2902,6 +3100,19 @@ export default {
|
|||||||
data_not_found: ']的数据不存在'
|
data_not_found: ']的数据不存在'
|
||||||
},
|
},
|
||||||
task: {
|
task: {
|
||||||
|
time_check_5_minute_later_than_current: '不能小于当前时间5分钟后',
|
||||||
|
time_check_later_than_current: '不能小于当前时间',
|
||||||
|
time_check_earlier_than_end: '不能大于结束时间',
|
||||||
|
time_check_later_than_start: '不能小于开始时间',
|
||||||
|
confirm_exit_without_save: '当前的更改尚未保存,确定退出吗?',
|
||||||
|
deliver_now: '立即下发',
|
||||||
|
deliver_scheduled: '定时下发',
|
||||||
|
logic_filter: '条件筛选',
|
||||||
|
enum_filter: '枚举筛选',
|
||||||
|
cannot_be_all_disabled: '所有组件不能全为禁止',
|
||||||
|
template_hint_title: '设置说明如下',
|
||||||
|
template_hint_1: '当组件被设置为禁止编辑时,用户填写表单时不允许修改',
|
||||||
|
template_hint_2: '当组件被设置为允许编辑时,用户填写表单时允许修改',
|
||||||
finish_rate_hint: '填报完成率=已填报数据条数/下发填报条数*100%',
|
finish_rate_hint: '填报完成率=已填报数据条数/下发填报条数*100%',
|
||||||
distribute_frequency: '发送频率',
|
distribute_frequency: '发送频率',
|
||||||
one_time: '仅下发一次',
|
one_time: '仅下发一次',
|
||||||
@ -2976,5 +3187,53 @@ export default {
|
|||||||
module_name: '阈值告警',
|
module_name: '阈值告警',
|
||||||
setting: '阈值告警设置',
|
setting: '阈值告警设置',
|
||||||
no_view_tip: '请在设置阈值告警前先保存'
|
no_view_tip: '请在设置阈值告警前先保存'
|
||||||
|
},
|
||||||
|
relation: {
|
||||||
|
no_permission: '没有查看权限',
|
||||||
|
datasource: '数据源',
|
||||||
|
dataset: '数据集',
|
||||||
|
dashboard: '仪表板',
|
||||||
|
dataV: '数据大屏',
|
||||||
|
analysis: '血缘分析',
|
||||||
|
resource_type: '资源类型',
|
||||||
|
pls_choose: '请选择',
|
||||||
|
choose_resource: '选择资源',
|
||||||
|
list_chart: '列表视图',
|
||||||
|
mind_map: '脑图',
|
||||||
|
index: '序号',
|
||||||
|
datasource_name: '数据源名称',
|
||||||
|
dataset_name: '数据源集名称',
|
||||||
|
dashboard_name: '仪表板名称',
|
||||||
|
dataV_name: '数据大屏名称',
|
||||||
|
retract: '收起',
|
||||||
|
expand: '展开',
|
||||||
|
node_info: '节点详情',
|
||||||
|
node_name: '节点名称',
|
||||||
|
creator: '创建人',
|
||||||
|
last_update_time: '最近更新时间',
|
||||||
|
dependent: '资源依赖',
|
||||||
|
new_page: '新页面打开'
|
||||||
|
},
|
||||||
|
copilot: {
|
||||||
|
talking_analysis: 'Copilot 对话分析',
|
||||||
|
hello: '你好,我是 Copilot 对话分析',
|
||||||
|
click_talk: '点击一下,开启可视化图表解答模式~',
|
||||||
|
know: '我知道了',
|
||||||
|
ds_prefix: '当前数据集为【',
|
||||||
|
ds_suffix: '】,切换数据集将清空当前会话。',
|
||||||
|
confirm: '确定要切换数据集吗?',
|
||||||
|
choose_dataset: '选择数据集',
|
||||||
|
pls_choose_dataset: '请选择数据集',
|
||||||
|
chart: '图表',
|
||||||
|
line: '折线图',
|
||||||
|
bar: '柱状图',
|
||||||
|
pie: '饼图',
|
||||||
|
sorry: '抱歉,根据已知信息无法回答这个问题,请重新描述你的问题或提供更多信息~',
|
||||||
|
hello1: '您好,我是 Copilot,很高兴为你服务~',
|
||||||
|
answer: '回答中',
|
||||||
|
example: '您可以问我: 2020年各个销售部门销售额占比的饼图',
|
||||||
|
switch_chart: '切换图表类型',
|
||||||
|
switch_table: '切换至明细表',
|
||||||
|
download: '下载'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,6 +272,10 @@ declare interface ChartMiscStyle {
|
|||||||
axisLabel: SplitAxisLabel
|
axisLabel: SplitAxisLabel
|
||||||
splitLine: SplitAxisLine
|
splitLine: SplitAxisLine
|
||||||
splitArea: SplitSplitArea
|
splitArea: SplitSplitArea
|
||||||
|
/**
|
||||||
|
* 轴值设置
|
||||||
|
*/
|
||||||
|
axisValue: AxisValue
|
||||||
}
|
}
|
||||||
declare interface SplitLineStyle {
|
declare interface SplitLineStyle {
|
||||||
color: string
|
color: string
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onBeforeMount, reactive, inject } from 'vue'
|
import { ref, onBeforeMount, reactive, inject, nextTick } from 'vue'
|
||||||
import { initCanvasData } from '@/utils/canvasUtils'
|
import { initCanvasData, onInitReady } from '@/utils/canvasUtils'
|
||||||
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||||
import { useEmbedded } from '@/store/modules/embedded'
|
import { useEmbedded } from '@/store/modules/embedded'
|
||||||
import { check } from '@/utils/CrossPermission'
|
import { check } from '@/utils/CrossPermission'
|
||||||
@ -125,6 +125,9 @@ onBeforeMount(async () => {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
nextTick(() => {
|
||||||
|
onInitReady({ resourceId: chartId })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -782,6 +782,20 @@ export function findComponentById(componentId) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function onInitReady(params) {
|
||||||
|
try {
|
||||||
|
console.info('Canvas initReady')
|
||||||
|
const targetPm = {
|
||||||
|
type: 'dataease-embedded-interactive',
|
||||||
|
eventName: 'canvas_init_ready',
|
||||||
|
args: params
|
||||||
|
}
|
||||||
|
window.parent.postMessage(targetPm, '*')
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('de_inner_params send error')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function mobileViewStyleSwitch(component) {
|
export function mobileViewStyleSwitch(component) {
|
||||||
if (component) {
|
if (component) {
|
||||||
const viewInfo = canvasViewInfo.value[component.id]
|
const viewInfo = canvasViewInfo.value[component.id]
|
||||||
|
@ -3,7 +3,7 @@ import icon_info_outlined from '@/assets/svg/icon_info_outlined.svg'
|
|||||||
import { computed, onMounted, reactive, watch } from 'vue'
|
import { computed, onMounted, reactive, watch } from 'vue'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { DEFAULT_MISC } from '@/views/chart/components/editor/util/chart'
|
import { DEFAULT_MISC } from '@/views/chart/components/editor/util/chart'
|
||||||
import { ElMessage, ElRow } from 'element-plus-secondary'
|
import { ElRow } from 'element-plus-secondary'
|
||||||
import { fieldType } from '@/utils/attr'
|
import { fieldType } from '@/utils/attr'
|
||||||
import { cloneDeep, defaultsDeep } from 'lodash-es'
|
import { cloneDeep, defaultsDeep } from 'lodash-es'
|
||||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||||
@ -25,6 +25,14 @@ useEmitt({
|
|||||||
name: 'word-cloud-default-data-range',
|
name: 'word-cloud-default-data-range',
|
||||||
callback: args => wordCloudDefaultDataRange(args)
|
callback: args => wordCloudDefaultDataRange(args)
|
||||||
})
|
})
|
||||||
|
useEmitt({
|
||||||
|
name: 'gauge-default-data',
|
||||||
|
callback: args => gaugeDefaultDataRange(args)
|
||||||
|
})
|
||||||
|
useEmitt({
|
||||||
|
name: 'liquid-default-data',
|
||||||
|
callback: args => gaugeDefaultDataRange(args)
|
||||||
|
})
|
||||||
const emit = defineEmits(['onMiscChange'])
|
const emit = defineEmits(['onMiscChange'])
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -59,7 +67,10 @@ const state = reactive({
|
|||||||
minField: {},
|
minField: {},
|
||||||
maxField: {},
|
maxField: {},
|
||||||
liquidMaxField: {},
|
liquidMaxField: {},
|
||||||
quotaData: []
|
quotaData: [],
|
||||||
|
// 是否已处理没有 y 轴字段的情况
|
||||||
|
liquidProcessedNoYAxis: false,
|
||||||
|
gaugeProcessedNoYAxis: false
|
||||||
})
|
})
|
||||||
|
|
||||||
const liquidShapeOptions = [
|
const liquidShapeOptions = [
|
||||||
@ -71,9 +82,6 @@ const liquidShapeOptions = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const changeMisc = (prop = '', refresh = false) => {
|
const changeMisc = (prop = '', refresh = false) => {
|
||||||
if (state.miscForm.gaugeMax <= state.miscForm.gaugeMin) {
|
|
||||||
ElMessage.error(t('chart.max_more_than_mix'))
|
|
||||||
}
|
|
||||||
emit('onMiscChange', { data: state.miscForm, requestData: refresh }, prop)
|
emit('onMiscChange', { data: state.miscForm, requestData: refresh }, prop)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,13 +101,93 @@ const initField = () => {
|
|||||||
if (state.miscForm.liquidMaxField.id) {
|
if (state.miscForm.liquidMaxField.id) {
|
||||||
state.liquidMaxField = getQuotaField(state.miscForm.liquidMaxField.id)
|
state.liquidMaxField = getQuotaField(state.miscForm.liquidMaxField.id)
|
||||||
}
|
}
|
||||||
|
initDynamicDefaultField()
|
||||||
|
}
|
||||||
|
|
||||||
|
const initDynamicDefaultField = () => {
|
||||||
|
if (state.quotaData.length > 0) {
|
||||||
|
// 查找 quotaData 中是否存在 chart.yAxis[0].id
|
||||||
|
const yAxisId = props.chart.yAxis?.[0]?.id
|
||||||
|
const yAxisExists = state.quotaData.find(ele => ele.id === yAxisId)
|
||||||
|
// 如果不存在
|
||||||
|
if (!yAxisExists && (state.miscForm.liquidMaxField.id || state.miscForm.gaugeMaxField.id)) {
|
||||||
|
if (props.chart.type === 'liquid' && !state.liquidProcessedNoYAxis) {
|
||||||
|
state.liquidProcessedNoYAxis = true
|
||||||
|
state.miscForm.liquidMaxField.id = ''
|
||||||
|
state.miscForm.liquidMaxField.summary = ''
|
||||||
|
state.liquidMaxField = getQuotaField(state.miscForm.liquidMaxField.id)
|
||||||
|
changeMisc('liquidMaxField', false)
|
||||||
|
} else {
|
||||||
|
if (!state.gaugeProcessedNoYAxis) {
|
||||||
|
state.gaugeProcessedNoYAxis = true
|
||||||
|
state.miscForm.gaugeMaxField.id = ''
|
||||||
|
state.miscForm.gaugeMaxField.summary = ''
|
||||||
|
state.maxField = {}
|
||||||
|
changeMisc('gaugeMaxField', false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (props.chart.type === 'liquid') {
|
||||||
|
if (state.miscForm.liquidMaxType === 'dynamic') {
|
||||||
|
state.miscForm.liquidMax = undefined
|
||||||
|
// 查找 quotaData 中是否存在 liquidMaxField.id
|
||||||
|
const liquidMaxFieldExists = state.quotaData.find(
|
||||||
|
ele => ele.id === state.miscForm.liquidMaxField.id
|
||||||
|
)
|
||||||
|
if (!liquidMaxFieldExists) {
|
||||||
|
if (yAxisId) {
|
||||||
|
state.liquidProcessedNoYAxis = false
|
||||||
|
// 根据查找结果设置 liquidMaxField.id
|
||||||
|
state.miscForm.liquidMaxField.id = yAxisExists ? yAxisId : state.quotaData[0]?.id
|
||||||
|
// 设置 summary 和 maxField
|
||||||
|
state.miscForm.liquidMaxField.summary = 'sum'
|
||||||
|
state.maxField = getQuotaField(state.miscForm.liquidMaxField.id)
|
||||||
|
// 触发 changeMisc 事件
|
||||||
|
if (yAxisExists) {
|
||||||
|
changeMisc('liquidMaxField', true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!state.miscForm.liquidMax && state.miscForm.liquidMaxType === 'fix') {
|
||||||
|
state.miscForm.liquidMax = cloneDeep(defaultMaxValue.liquidMax)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (state.miscForm.gaugeMaxType === 'dynamic') {
|
||||||
|
state.miscForm.gaugeMax = undefined
|
||||||
|
|
||||||
|
// 查找 quotaData 中是否存在 gaugeMaxField.id
|
||||||
|
const gaugeMaxFieldExists = state.quotaData.find(
|
||||||
|
ele => ele.id === state.miscForm.gaugeMaxField.id
|
||||||
|
)
|
||||||
|
if (!gaugeMaxFieldExists) {
|
||||||
|
if (yAxisId) {
|
||||||
|
state.gaugeProcessedNoYAxis = false
|
||||||
|
// 根据查找结果设置 gaugeMaxField.id
|
||||||
|
state.miscForm.gaugeMaxField.id = yAxisExists ? yAxisId : state.quotaData[0]?.id
|
||||||
|
// 设置 summary 和 maxField
|
||||||
|
state.miscForm.gaugeMaxField.summary = 'sum'
|
||||||
|
state.maxField = getQuotaField(state.miscForm.gaugeMaxField.id)
|
||||||
|
if (yAxisExists) {
|
||||||
|
// 触发 changeMisc 事件
|
||||||
|
changeMisc('gaugeMaxField', true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!state.miscForm.gaugeMax && state.miscForm.gaugeMaxType === 'fix') {
|
||||||
|
state.miscForm.gaugeMax = cloneDeep(defaultMaxValue.gaugeMax)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeQuotaField = (type: string, resetSummary?: boolean) => {
|
const changeQuotaField = (type: string, resetSummary?: boolean) => {
|
||||||
if (type === 'min') {
|
if (type === 'min') {
|
||||||
if (state.miscForm.gaugeMinType === 'dynamic') {
|
if (state.miscForm.gaugeMinType === 'dynamic') {
|
||||||
if (!state.miscForm.gaugeMinField.id) {
|
if (!state.miscForm.gaugeMinField.id) {
|
||||||
state.miscForm.gaugeMinField.id = state.quotaData[0]?.id
|
state.miscForm.gaugeMinField.id = props.chart.yAxis?.[0]?.id
|
||||||
}
|
}
|
||||||
if (!state.miscForm.gaugeMinField.summary) {
|
if (!state.miscForm.gaugeMinField.summary) {
|
||||||
state.miscForm.gaugeMinField.summary = 'count'
|
state.miscForm.gaugeMinField.summary = 'count'
|
||||||
@ -122,14 +210,21 @@ const changeQuotaField = (type: string, resetSummary?: boolean) => {
|
|||||||
}
|
}
|
||||||
} else if (type === 'max') {
|
} else if (type === 'max') {
|
||||||
if (props.chart.type === 'liquid') {
|
if (props.chart.type === 'liquid') {
|
||||||
|
if (state.miscForm.liquidMaxType === 'dynamic') {
|
||||||
|
state.miscForm.liquidMax = undefined
|
||||||
|
} else {
|
||||||
|
if (!state.miscForm.liquidMax) {
|
||||||
|
state.miscForm.liquidMax = cloneDeep(defaultMaxValue.liquidMax)
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!state.miscForm.liquidMaxField.id) {
|
if (!state.miscForm.liquidMaxField.id) {
|
||||||
state.miscForm.liquidMaxField.id = state.quotaData[0]?.id
|
state.miscForm.liquidMaxField.id = props.chart.yAxis?.[0]?.id
|
||||||
}
|
}
|
||||||
if (!state.miscForm.liquidMaxField.summary) {
|
if (!state.miscForm.liquidMaxField.summary) {
|
||||||
state.miscForm.liquidMaxField.summary = 'count'
|
state.miscForm.liquidMaxField.summary = 'sum'
|
||||||
}
|
}
|
||||||
if (resetSummary) {
|
if (resetSummary) {
|
||||||
state.miscForm.liquidMaxField.summary = 'count'
|
state.miscForm.liquidMaxField.summary = 'sum'
|
||||||
}
|
}
|
||||||
if (state.miscForm.liquidMaxField.id && state.miscForm.liquidMaxField.summary) {
|
if (state.miscForm.liquidMaxField.id && state.miscForm.liquidMaxField.summary) {
|
||||||
state.maxField = getQuotaField(state.miscForm.liquidMaxField.id)
|
state.maxField = getQuotaField(state.miscForm.liquidMaxField.id)
|
||||||
@ -137,20 +232,24 @@ const changeQuotaField = (type: string, resetSummary?: boolean) => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (state.miscForm.gaugeMaxType === 'dynamic') {
|
if (state.miscForm.gaugeMaxType === 'dynamic') {
|
||||||
|
state.miscForm.gaugeMax = undefined
|
||||||
if (!state.miscForm.gaugeMaxField.id) {
|
if (!state.miscForm.gaugeMaxField.id) {
|
||||||
state.miscForm.gaugeMaxField.id = state.quotaData[0]?.id
|
state.miscForm.gaugeMaxField.id = props.chart.yAxis?.[0]?.id
|
||||||
}
|
}
|
||||||
if (!state.miscForm.gaugeMaxField.summary) {
|
if (!state.miscForm.gaugeMaxField.summary) {
|
||||||
state.miscForm.gaugeMaxField.summary = 'count'
|
state.miscForm.gaugeMaxField.summary = 'sum'
|
||||||
}
|
}
|
||||||
if (resetSummary) {
|
if (resetSummary) {
|
||||||
state.miscForm.gaugeMaxField.summary = 'count'
|
state.miscForm.gaugeMaxField.summary = 'sum'
|
||||||
}
|
}
|
||||||
if (state.miscForm.gaugeMaxField.id && state.miscForm.gaugeMaxField.summary) {
|
if (state.miscForm.gaugeMaxField.id && state.miscForm.gaugeMaxField.summary) {
|
||||||
state.maxField = getQuotaField(state.miscForm.gaugeMaxField.id)
|
state.maxField = getQuotaField(state.miscForm.gaugeMaxField.id)
|
||||||
changeMisc('gaugeMaxField', true)
|
changeMisc('gaugeMaxField', true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!state.miscForm.gaugeMax) {
|
||||||
|
state.miscForm.gaugeMax = cloneDeep(defaultMaxValue.gaugeMax)
|
||||||
|
}
|
||||||
if (state.miscForm.gaugeMinType === 'dynamic') {
|
if (state.miscForm.gaugeMinType === 'dynamic') {
|
||||||
if (state.miscForm.gaugeMinField.id && state.miscForm.gaugeMinField.summary) {
|
if (state.miscForm.gaugeMinField.id && state.miscForm.gaugeMinField.summary) {
|
||||||
changeMisc('gaugeMaxField', true)
|
changeMisc('gaugeMaxField', true)
|
||||||
@ -187,6 +286,39 @@ const wordCloudDefaultDataRange = args => {
|
|||||||
state.miscForm.wordCloudAxisValueRange.min = args.data.min
|
state.miscForm.wordCloudAxisValueRange.min = args.data.min
|
||||||
state.miscForm.wordCloudAxisValueRange.fieldId = props.chart.yAxis?.[0]?.id
|
state.miscForm.wordCloudAxisValueRange.fieldId = props.chart.yAxis?.[0]?.id
|
||||||
}
|
}
|
||||||
|
const defaultMaxValue = {
|
||||||
|
gaugeMax: undefined,
|
||||||
|
liquidMax: undefined
|
||||||
|
}
|
||||||
|
const gaugeDefaultDataRange = args => {
|
||||||
|
if (args.data.type === 'gauge') {
|
||||||
|
defaultMaxValue.gaugeMax = cloneDeep(args.data.max)
|
||||||
|
if (!state.miscForm.gaugeMax) {
|
||||||
|
state.miscForm.gaugeMax = cloneDeep(defaultMaxValue.gaugeMax)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (args.data.type === 'liquid') {
|
||||||
|
defaultMaxValue.liquidMax = cloneDeep(args.data.max)
|
||||||
|
if (!state.miscForm.liquidMax) {
|
||||||
|
state.miscForm.liquidMax = cloneDeep(defaultMaxValue.liquidMax)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 校验最大值的输入
|
||||||
|
*/
|
||||||
|
const changeMaxValidate = prop => {
|
||||||
|
if (prop === 'gaugeMax') {
|
||||||
|
if (!state.miscForm.gaugeMax) {
|
||||||
|
state.miscForm.gaugeMax = cloneDeep(defaultMaxValue.gaugeMax)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!state.miscForm.liquidMax) {
|
||||||
|
state.miscForm.liquidMax = cloneDeep(defaultMaxValue.liquidMax)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changeMisc(prop)
|
||||||
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initField()
|
initField()
|
||||||
init()
|
init()
|
||||||
@ -357,7 +489,7 @@ onMounted(() => {
|
|||||||
v-model="state.miscForm.gaugeMax"
|
v-model="state.miscForm.gaugeMax"
|
||||||
size="small"
|
size="small"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
@change="changeMisc('gaugeMax')"
|
@blur="changeMaxValidate('gaugeMax')"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-row
|
<el-row
|
||||||
@ -505,7 +637,7 @@ onMounted(() => {
|
|||||||
:min="1"
|
:min="1"
|
||||||
size="small"
|
size="small"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
@change="changeMisc('liquidMax')"
|
@blur="changeMaxValidate('liquidMax')"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import { computed, onMounted, reactive, watch } from 'vue'
|
import { computed, onMounted, reactive, watch } from 'vue'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { COLOR_PANEL, DEFAULT_MISC_STYLE } from '@/views/chart/components/editor/util/chart'
|
import { COLOR_PANEL, DEFAULT_MISC_STYLE } from '@/views/chart/components/editor/util/chart'
|
||||||
|
import icon_info_outlined from '@/assets/svg/icon_info_outlined.svg'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
@ -14,6 +15,10 @@ const props = withDefaults(
|
|||||||
{ themes: 'dark' }
|
{ themes: 'dark' }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const toolTip = computed(() => {
|
||||||
|
return props.themes === 'dark' ? 'ndark' : 'dark'
|
||||||
|
})
|
||||||
|
|
||||||
const predefineColors = COLOR_PANEL
|
const predefineColors = COLOR_PANEL
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
@ -57,6 +62,9 @@ const init = () => {
|
|||||||
}
|
}
|
||||||
if (customStyle.xAxis) {
|
if (customStyle.xAxis) {
|
||||||
state.miscForm = customStyle.misc
|
state.miscForm = customStyle.misc
|
||||||
|
if (!state.miscForm.axisValue) {
|
||||||
|
state.miscForm.axisValue = JSON.parse(JSON.stringify(DEFAULT_MISC_STYLE)).axisValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,6 +146,89 @@ onMounted(() => {
|
|||||||
@change="changeMiscStyle('axisColor')"
|
@change="changeMiscStyle('axisColor')"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<template v-if="showProperty('axisValue')">
|
||||||
|
<div
|
||||||
|
style="display: flex; flex-direction: row; justify-content: space-between; padding: 8px 0"
|
||||||
|
>
|
||||||
|
<label class="custom-form-item-label" :class="'custom-form-item-label--' + themes">
|
||||||
|
{{ t('chart.axis_value') }}
|
||||||
|
<el-tooltip class="item" :effect="toolTip" placement="top">
|
||||||
|
<template #content><span v-html="t('chart.axis_tip')"></span></template>
|
||||||
|
<span style="vertical-align: middle">
|
||||||
|
<el-icon style="cursor: pointer">
|
||||||
|
<Icon name="icon_info_outlined"><icon_info_outlined class="svg-icon" /></Icon>
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||||
|
<el-checkbox
|
||||||
|
size="small"
|
||||||
|
:effect="props.themes"
|
||||||
|
v-model="state.miscForm.axisValue.auto"
|
||||||
|
@change="changeMiscStyle('axisValue.auto')"
|
||||||
|
>
|
||||||
|
{{ t('chart.axis_auto') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-if="showProperty('axisValue') && !state.miscForm.axisValue.auto">
|
||||||
|
<el-row :gutter="8">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item
|
||||||
|
class="form-item"
|
||||||
|
:class="'form-item-' + themes"
|
||||||
|
:label="t('chart.axis_value_max')"
|
||||||
|
>
|
||||||
|
<el-input-number
|
||||||
|
controls-position="right"
|
||||||
|
:effect="props.themes"
|
||||||
|
v-model.number="state.miscForm.axisValue.max"
|
||||||
|
@change="changeMiscStyle('axisValue.max')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item
|
||||||
|
class="form-item"
|
||||||
|
:class="'form-item-' + themes"
|
||||||
|
:label="t('chart.axis_value_min')"
|
||||||
|
>
|
||||||
|
<el-input-number
|
||||||
|
:effect="props.themes"
|
||||||
|
controls-position="right"
|
||||||
|
v-model.number="state.miscForm.axisValue.min"
|
||||||
|
@change="changeMiscStyle('axisValue.min')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<label class="custom-form-item-label" :class="'custom-form-item-label--' + themes">
|
||||||
|
{{ t('chart.axis_value_split_count') }}
|
||||||
|
<el-tooltip class="item" :effect="toolTip" placement="top">
|
||||||
|
<template #content>期望的坐标轴刻度数量,非最终结果。</template>
|
||||||
|
<span style="vertical-align: middle">
|
||||||
|
<el-icon style="cursor: pointer">
|
||||||
|
<Icon name="icon_info_outlined"><icon_info_outlined class="svg-icon" /></Icon>
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||||
|
<el-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:effect="props.themes"
|
||||||
|
controls-position="right"
|
||||||
|
v-model.number="state.miscForm.axisValue.splitCount"
|
||||||
|
@change="changeMiscStyle('axisValue.splitCount')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -145,4 +236,17 @@ onMounted(() => {
|
|||||||
.form-item-checkbox {
|
.form-item-checkbox {
|
||||||
margin-bottom: 0 !important;
|
margin-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
|
.custom-form-item-label {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: #646a73;
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
padding: 2px 12px 0 0;
|
||||||
|
|
||||||
|
&.custom-form-item-label--dark {
|
||||||
|
color: #a6a6a6;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1591,7 +1591,7 @@ const setCacheId = () => {
|
|||||||
!cacheId ||
|
!cacheId ||
|
||||||
!!view.value.tableId ||
|
!!view.value.tableId ||
|
||||||
templateStatusShow.value ||
|
templateStatusShow.value ||
|
||||||
view.value.type === 'rich-text'
|
['rich-text', 'picture-group'].includes(view.value.type)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
view.value.tableId = cacheId as unknown as number
|
view.value.tableId = cacheId as unknown as number
|
||||||
|
@ -232,12 +232,12 @@ export const DEFAULT_MISC: ChartMiscAttr = {
|
|||||||
summary: ''
|
summary: ''
|
||||||
},
|
},
|
||||||
gaugeMin: 0,
|
gaugeMin: 0,
|
||||||
gaugeMaxType: 'fix',
|
gaugeMaxType: 'dynamic',
|
||||||
gaugeMaxField: {
|
gaugeMaxField: {
|
||||||
id: '',
|
id: '',
|
||||||
summary: ''
|
summary: ''
|
||||||
},
|
},
|
||||||
gaugeMax: 1,
|
gaugeMax: undefined,
|
||||||
gaugeStartAngle: 225,
|
gaugeStartAngle: 225,
|
||||||
gaugeEndAngle: -45,
|
gaugeEndAngle: -45,
|
||||||
nameFontSize: 18,
|
nameFontSize: 18,
|
||||||
@ -258,8 +258,8 @@ export const DEFAULT_MISC: ChartMiscAttr = {
|
|||||||
nameFontShadow: false,
|
nameFontShadow: false,
|
||||||
treemapWidth: 80,
|
treemapWidth: 80,
|
||||||
treemapHeight: 80,
|
treemapHeight: 80,
|
||||||
liquidMax: 1,
|
liquidMax: undefined,
|
||||||
liquidMaxType: 'fix',
|
liquidMaxType: 'dynamic',
|
||||||
liquidMaxField: {
|
liquidMaxField: {
|
||||||
id: '',
|
id: '',
|
||||||
summary: ''
|
summary: ''
|
||||||
@ -731,6 +731,13 @@ export const DEFAULT_MISC_STYLE: ChartMiscStyle = {
|
|||||||
},
|
},
|
||||||
splitArea: {
|
splitArea: {
|
||||||
show: true
|
show: true
|
||||||
|
},
|
||||||
|
axisValue: {
|
||||||
|
auto: true,
|
||||||
|
min: 10,
|
||||||
|
max: 100,
|
||||||
|
split: 10,
|
||||||
|
splitCount: 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const DEFAULT_FUNCTION_CFG: ChartFunctionCfg = {
|
export const DEFAULT_FUNCTION_CFG: ChartFunctionCfg = {
|
||||||
|
@ -53,8 +53,8 @@ export class Liquid extends G2PlotChartView<LiquidOptions, G2Liquid> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async drawChart(drawOptions: G2PlotDrawOptions<G2Liquid>): Promise<G2Liquid> {
|
async drawChart(drawOptions: G2PlotDrawOptions<G2Liquid>): Promise<G2Liquid> {
|
||||||
const { chart, container } = drawOptions
|
const { chart, container, action } = drawOptions
|
||||||
if (!chart.data?.series) {
|
if (!chart.data?.series || !chart.yAxis.length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const initOptions: LiquidOptions = {
|
const initOptions: LiquidOptions = {
|
||||||
@ -62,8 +62,17 @@ export class Liquid extends G2PlotChartView<LiquidOptions, G2Liquid> {
|
|||||||
}
|
}
|
||||||
const options = this.setupOptions(chart, initOptions)
|
const options = this.setupOptions(chart, initOptions)
|
||||||
const { Liquid: G2Liquid } = await import('@antv/g2plot/esm/plots/liquid')
|
const { Liquid: G2Liquid } = await import('@antv/g2plot/esm/plots/liquid')
|
||||||
// 开始渲染
|
const newChart = new G2Liquid(container, options)
|
||||||
return new G2Liquid(container, options)
|
newChart.on('afterrender', () => {
|
||||||
|
action({
|
||||||
|
from: 'liquid',
|
||||||
|
data: {
|
||||||
|
type: 'liquid',
|
||||||
|
max: chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return newChart
|
||||||
}
|
}
|
||||||
|
|
||||||
protected configTheme(chart: Chart, options: LiquidOptions): LiquidOptions {
|
protected configTheme(chart: Chart, options: LiquidOptions): LiquidOptions {
|
||||||
@ -100,10 +109,11 @@ export class Liquid extends G2PlotChartView<LiquidOptions, G2Liquid> {
|
|||||||
let max, radius, shape
|
let max, radius, shape
|
||||||
if (customAttr.misc) {
|
if (customAttr.misc) {
|
||||||
const misc = customAttr.misc
|
const misc = customAttr.misc
|
||||||
|
const defaultLiquidMax = chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
||||||
if (misc.liquidMaxType === 'dynamic') {
|
if (misc.liquidMaxType === 'dynamic') {
|
||||||
max = chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
max = defaultLiquidMax
|
||||||
} else {
|
} else {
|
||||||
max = misc.liquidMax ? misc.liquidMax : DEFAULT_MISC.liquidMax
|
max = misc.liquidMax ? misc.liquidMax : defaultLiquidMax
|
||||||
}
|
}
|
||||||
radius = (misc.liquidSize ? misc.liquidSize : DEFAULT_MISC.liquidSize) / 100
|
radius = (misc.liquidSize ? misc.liquidSize : DEFAULT_MISC.liquidSize) / 100
|
||||||
shape = misc.liquidShape ?? DEFAULT_MISC.liquidShape
|
shape = misc.liquidShape ?? DEFAULT_MISC.liquidShape
|
||||||
|
@ -276,6 +276,7 @@ export class SymbolicMap extends L7ChartView<Scene, L7Config> {
|
|||||||
await scene.addImage(`customIcon`, svgStrToUrl(svgEle.outerHTML))
|
await scene.addImage(`customIcon`, svgStrToUrl(svgEle.outerHTML))
|
||||||
pointLayer.shape('customIcon')
|
pointLayer.shape('customIcon')
|
||||||
} else {
|
} else {
|
||||||
|
pointLayer.shape(mapSymbol)
|
||||||
pointLayer.color(colorsWithAlpha[0])
|
pointLayer.color(colorsWithAlpha[0])
|
||||||
pointLayer.style({
|
pointLayer.style({
|
||||||
stroke: colorsWithAlpha[0],
|
stroke: colorsWithAlpha[0],
|
||||||
|
@ -67,8 +67,8 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async drawChart(drawOptions: G2PlotDrawOptions<G2Gauge>): Promise<G2Gauge> {
|
async drawChart(drawOptions: G2PlotDrawOptions<G2Gauge>): Promise<G2Gauge> {
|
||||||
const { chart, container, scale } = drawOptions
|
const { chart, container, scale, action } = drawOptions
|
||||||
if (!chart.data?.series) {
|
if (!chart.data?.series || !chart.yAxis.length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// options
|
// options
|
||||||
@ -99,7 +99,17 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
}
|
}
|
||||||
const options = this.setupOptions(chart, initOptions, { scale })
|
const options = this.setupOptions(chart, initOptions, { scale })
|
||||||
const { Gauge: G2Gauge } = await import('@antv/g2plot/esm/plots/gauge')
|
const { Gauge: G2Gauge } = await import('@antv/g2plot/esm/plots/gauge')
|
||||||
return new G2Gauge(container, options)
|
const newChart = new G2Gauge(container, options)
|
||||||
|
newChart.on('afterrender', () => {
|
||||||
|
action({
|
||||||
|
from: 'gauge',
|
||||||
|
data: {
|
||||||
|
type: 'gauge',
|
||||||
|
max: chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return newChart
|
||||||
}
|
}
|
||||||
|
|
||||||
protected configMisc(
|
protected configMisc(
|
||||||
@ -116,13 +126,13 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
min = chart.data?.series[chart.data?.series.length - 2]?.data[0]
|
min = chart.data?.series[chart.data?.series.length - 2]?.data[0]
|
||||||
max = chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
max = chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
||||||
} else if (misc.gaugeMinType !== 'dynamic' && misc.gaugeMaxType === 'dynamic') {
|
} else if (misc.gaugeMinType !== 'dynamic' && misc.gaugeMaxType === 'dynamic') {
|
||||||
min = misc.gaugeMin ? misc.gaugeMin : DEFAULT_MISC.gaugeMin
|
min = misc.gaugeMin || misc.gaugeMin === 0 ? misc.gaugeMin : DEFAULT_MISC.gaugeMin
|
||||||
max = chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
max = chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
||||||
} else if (misc.gaugeMinType === 'dynamic' && misc.gaugeMaxType !== 'dynamic') {
|
} else if (misc.gaugeMinType === 'dynamic' && misc.gaugeMaxType !== 'dynamic') {
|
||||||
min = chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
min = chart.data?.series[chart.data?.series.length - 1]?.data[0]
|
||||||
max = misc.gaugeMax ? misc.gaugeMax : DEFAULT_MISC.gaugeMax
|
max = misc.gaugeMax ? misc.gaugeMax : DEFAULT_MISC.gaugeMax
|
||||||
} else {
|
} else {
|
||||||
min = misc.gaugeMin ? misc.gaugeMin : DEFAULT_MISC.gaugeMin
|
min = misc.gaugeMin || misc.gaugeMin === 0 ? misc.gaugeMin : DEFAULT_MISC.gaugeMin
|
||||||
max = misc.gaugeMax ? misc.gaugeMax : DEFAULT_MISC.gaugeMax
|
max = misc.gaugeMax ? misc.gaugeMax : DEFAULT_MISC.gaugeMax
|
||||||
}
|
}
|
||||||
startAngle = (misc.gaugeStartAngle * Math.PI) / 180
|
startAngle = (misc.gaugeStartAngle * Math.PI) / 180
|
||||||
|
@ -27,7 +27,7 @@ export class Radar extends G2PlotChartView<RadarOptions, G2Radar> {
|
|||||||
'basic-style-selector': ['colors', 'alpha', 'radarShape', 'seriesColor'],
|
'basic-style-selector': ['colors', 'alpha', 'radarShape', 'seriesColor'],
|
||||||
'label-selector': ['seriesLabelFormatter'],
|
'label-selector': ['seriesLabelFormatter'],
|
||||||
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'misc-style-selector': ['showName', 'color', 'fontSize', 'axisColor'],
|
'misc-style-selector': ['showName', 'color', 'fontSize', 'axisColor', 'axisValue'],
|
||||||
'title-selector': [
|
'title-selector': [
|
||||||
'show',
|
'show',
|
||||||
'title',
|
'title',
|
||||||
@ -213,6 +213,22 @@ export class Radar extends G2PlotChartView<RadarOptions, G2Radar> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const axisValue = misc.axisValue
|
||||||
|
if (!axisValue?.auto) {
|
||||||
|
const axisYAxis = {
|
||||||
|
...yAxis,
|
||||||
|
min: axisValue.min,
|
||||||
|
max: axisValue.max,
|
||||||
|
minLimit: axisValue.min,
|
||||||
|
maxLimit: axisValue.max,
|
||||||
|
tickCount: axisValue.splitCount
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...options,
|
||||||
|
xAxis,
|
||||||
|
yAxis: axisYAxis
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...options,
|
...options,
|
||||||
xAxis,
|
xAxis,
|
||||||
|
@ -23,7 +23,12 @@ import {
|
|||||||
type PivotSheet,
|
type PivotSheet,
|
||||||
type Node,
|
type Node,
|
||||||
type Meta,
|
type Meta,
|
||||||
S2DataConfig
|
S2DataConfig,
|
||||||
|
SpreadSheet,
|
||||||
|
InteractionStateName,
|
||||||
|
InteractionName,
|
||||||
|
DataCellBrushSelection,
|
||||||
|
TableDataCell
|
||||||
} from '@antv/s2'
|
} from '@antv/s2'
|
||||||
import { keys, intersection, filter, cloneDeep, merge, find, repeat } from 'lodash-es'
|
import { keys, intersection, filter, cloneDeep, merge, find, repeat } from 'lodash-es'
|
||||||
import { createVNode, render } from 'vue'
|
import { createVNode, render } from 'vue'
|
||||||
@ -31,6 +36,7 @@ import TableTooltip from '@/views/chart/components/editor/common/TableTooltip.vu
|
|||||||
import Exceljs from 'exceljs'
|
import Exceljs from 'exceljs'
|
||||||
import { saveAs } from 'file-saver'
|
import { saveAs } from 'file-saver'
|
||||||
import { ElMessage } from 'element-plus-secondary'
|
import { ElMessage } from 'element-plus-secondary'
|
||||||
|
import { matrix } from 'mathjs'
|
||||||
|
|
||||||
export function getCustomTheme(chart: Chart): S2Theme {
|
export function getCustomTheme(chart: Chart): S2Theme {
|
||||||
const headerColor = hexColorToRGBA(
|
const headerColor = hexColorToRGBA(
|
||||||
@ -971,12 +977,76 @@ export function configTooltip(chart: Chart, option: S2Options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function copyContent(s2Instance, event, fieldMeta) {
|
export function copyContent(s2Instance: SpreadSheet, event, fieldMeta) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
const cell = s2Instance.getCell(event.target)
|
const cell = s2Instance.getCell(event.target)
|
||||||
const valueField = cell.getMeta().valueField
|
const valueField = cell.getMeta().valueField
|
||||||
const cellMeta = cell.getMeta()
|
const cellMeta = cell.getMeta()
|
||||||
let content
|
const selectState = s2Instance.interaction.getState()
|
||||||
|
let content = ''
|
||||||
|
// 多选
|
||||||
|
if (selectState.stateName === InteractionStateName.SELECTED) {
|
||||||
|
const { cells } = selectState
|
||||||
|
if (!cells?.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const brushSelection = s2Instance.interaction.interactions.get(
|
||||||
|
InteractionName.BRUSH_SELECTION
|
||||||
|
) as DataCellBrushSelection
|
||||||
|
const selectedCells: TableDataCell[] = brushSelection.getScrollBrushRangeCells(cells)
|
||||||
|
selectedCells.sort((a, b) => {
|
||||||
|
const aMeta = a.getMeta()
|
||||||
|
const bMeta = b.getMeta()
|
||||||
|
if (aMeta.rowIndex !== bMeta.rowIndex) {
|
||||||
|
return aMeta.rowIndex - bMeta.rowIndex
|
||||||
|
}
|
||||||
|
return aMeta.colIndex - bMeta.colIndex
|
||||||
|
})
|
||||||
|
// 点击已选的就复制,未选的就忽略
|
||||||
|
let validClick = false
|
||||||
|
const matrix = selectedCells.reduce((p, n) => {
|
||||||
|
if (
|
||||||
|
n.getMeta().colIndex === cellMeta.colIndex &&
|
||||||
|
n.getMeta().rowIndex === cellMeta.rowIndex
|
||||||
|
) {
|
||||||
|
validClick = true
|
||||||
|
}
|
||||||
|
const arr = p[n.getMeta().rowIndex]
|
||||||
|
if (!arr) {
|
||||||
|
p[n.getMeta().rowIndex] = [n]
|
||||||
|
} else {
|
||||||
|
arr.push(n)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}, {}) as Record<number, TableDataCell[]>
|
||||||
|
if (validClick) {
|
||||||
|
keys(matrix).forEach(k => {
|
||||||
|
const arr = matrix[k] as TableDataCell[]
|
||||||
|
arr.forEach((cell, index) => {
|
||||||
|
const cellMeta = cell.getMeta()
|
||||||
|
const value = cellMeta.data?.[cellMeta.valueField]
|
||||||
|
const metaObj = find(fieldMeta, m => m.field === valueField)
|
||||||
|
let fieldVal = value?.toString()
|
||||||
|
if (metaObj) {
|
||||||
|
fieldVal = metaObj.formatter(value)
|
||||||
|
}
|
||||||
|
if (fieldVal === undefined) {
|
||||||
|
fieldVal = ''
|
||||||
|
}
|
||||||
|
if (index !== arr.length - 1) {
|
||||||
|
fieldVal += '\t'
|
||||||
|
}
|
||||||
|
content += fieldVal
|
||||||
|
})
|
||||||
|
content = content + '\n'
|
||||||
|
})
|
||||||
|
if (content) {
|
||||||
|
copyString(content, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s2Instance.interaction.clearState()
|
||||||
|
return
|
||||||
|
}
|
||||||
// 单元格
|
// 单元格
|
||||||
if (cellMeta?.data) {
|
if (cellMeta?.data) {
|
||||||
const value = cellMeta.data[valueField]
|
const value = cellMeta.data[valueField]
|
||||||
|
@ -317,13 +317,24 @@ const pointClickTrans = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const action = param => {
|
const actionDefault = param => {
|
||||||
if (param.from === 'map') {
|
if (param.from === 'map') {
|
||||||
emitter.emit('map-default-range', param)
|
emitter.emit('map-default-range', param)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if (param.from === 'word-cloud') {
|
if (param.from === 'word-cloud') {
|
||||||
emitter.emit('word-cloud-default-data-range', param)
|
emitter.emit('word-cloud-default-data-range', param)
|
||||||
|
}
|
||||||
|
if (param.from === 'gauge') {
|
||||||
|
emitter.emit('gauge-default-data', param)
|
||||||
|
}
|
||||||
|
if (param.from === 'liquid') {
|
||||||
|
emitter.emit('liquid-default-data', param)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = param => {
|
||||||
|
if (param.from) {
|
||||||
|
actionDefault(param)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state.pointParam = param.data
|
state.pointParam = param.data
|
||||||
|
@ -583,6 +583,10 @@ const checkFieldIsAllowEmpty = (allField?) => {
|
|||||||
showEmpty.value = false
|
showEmpty.value = false
|
||||||
if (view.value?.render && view.value?.type) {
|
if (view.value?.render && view.value?.type) {
|
||||||
const chartView = chartViewManager.getChartView(view.value.render, view.value.type)
|
const chartView = chartViewManager.getChartView(view.value.render, view.value.type)
|
||||||
|
// 插件
|
||||||
|
if (!chartView) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const map = parseJson(view.value.customAttr).map
|
const map = parseJson(view.value.customAttr).map
|
||||||
if (['bubble-map', 'map'].includes(view.value?.type) && !map?.id) {
|
if (['bubble-map', 'map'].includes(view.value?.type) && !map?.id) {
|
||||||
showEmpty.value = true
|
showEmpty.value = true
|
||||||
|
@ -11,6 +11,8 @@ import { Column, Line, Pie } from '@antv/g2plot'
|
|||||||
import { useElementSize } from '@vueuse/core'
|
import { useElementSize } from '@vueuse/core'
|
||||||
import { downloadCanvas } from '@/utils/imgUtils'
|
import { downloadCanvas } from '@/utils/imgUtils'
|
||||||
import ExcelJS from 'exceljs'
|
import ExcelJS from 'exceljs'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
const { t } = useI18n()
|
||||||
interface Copilot {
|
interface Copilot {
|
||||||
msgType: string
|
msgType: string
|
||||||
question: string
|
question: string
|
||||||
@ -199,7 +201,7 @@ const downloadChart = () => {
|
|||||||
exportExcel()
|
exportExcel()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
downloadCanvas('img', chartTypeRef.value, '图表')
|
downloadCanvas('img', chartTypeRef.value, t('copilot.chart'))
|
||||||
}
|
}
|
||||||
watch(
|
watch(
|
||||||
() => props.copilotInfo.loading,
|
() => props.copilotInfo.loading,
|
||||||
@ -223,17 +225,17 @@ const activeCommand = ref('')
|
|||||||
|
|
||||||
const curTypeList = [
|
const curTypeList = [
|
||||||
{
|
{
|
||||||
label: '折线图',
|
label: t('copilot.line'),
|
||||||
value: 'line',
|
value: 'line',
|
||||||
icon: icon_chartLineC
|
icon: icon_chartLineC
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '柱状图',
|
label: t('copilot.bar'),
|
||||||
icon: icon_dashboard_outlinedC,
|
icon: icon_dashboard_outlinedC,
|
||||||
value: 'bar'
|
value: 'bar'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '饼图',
|
label: t('copilot.pie'),
|
||||||
icon: icon_pie_outlinedC,
|
icon: icon_pie_outlinedC,
|
||||||
value: 'pie'
|
value: 'pie'
|
||||||
}
|
}
|
||||||
@ -248,7 +250,7 @@ const tips = computed(() => {
|
|||||||
return chart.title
|
return chart.title
|
||||||
}
|
}
|
||||||
if (msgStatus === 0) {
|
if (msgStatus === 0) {
|
||||||
return '抱歉,根据已知信息无法回答这个问题,请重新描述你的问题或提供更多信息~'
|
return t('copilot.sorry')
|
||||||
} else if (msgType === 'user') {
|
} else if (msgType === 'user') {
|
||||||
return question
|
return question
|
||||||
}
|
}
|
||||||
@ -274,15 +276,15 @@ const tips = computed(() => {
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
<div ref="content" class="content">
|
<div ref="content" class="content">
|
||||||
<div v-if="isWelcome" class="question-or-title" style="font-size: 16px; font-weight: 500">
|
<div v-if="isWelcome" class="question-or-title" style="font-size: 16px; font-weight: 500">
|
||||||
您好,我是 Copilot,很高兴为你服务~
|
{{ t('copilot.hello1') }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="isAnswer" class="question-or-title" style="font-size: 16px; font-weight: 500">
|
<div v-else-if="isAnswer" class="question-or-title" style="font-size: 16px; font-weight: 500">
|
||||||
回答中<span class="dot">...</span>
|
{{ t('copilot.answer') }}<span class="dot">...</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="question-or-title">
|
<div v-else class="question-or-title">
|
||||||
{{ tips }}
|
{{ tips }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isWelcome" class="is-welcome">您可以问我: 2020年各个销售部门销售额占比的饼图</div>
|
<div v-if="isWelcome" class="is-welcome">{{ t('copilot.example') }}</div>
|
||||||
<div
|
<div
|
||||||
v-else-if="copilotInfo.msgType === 'api' && copilotInfo.msgStatus === 1"
|
v-else-if="copilotInfo.msgType === 'api' && copilotInfo.msgStatus === 1"
|
||||||
class="chart-type"
|
class="chart-type"
|
||||||
@ -324,14 +326,14 @@ const tips = computed(() => {
|
|||||||
></component
|
></component
|
||||||
></Icon>
|
></Icon>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<el-tooltip effect="dark" content="切换图表类型" placement="top">
|
<el-tooltip effect="dark" :content="t('copilot.switch_chart')" placement="top">
|
||||||
<div
|
<div
|
||||||
v-show="renderTable || renderTableLocal"
|
v-show="renderTable || renderTableLocal"
|
||||||
@click="switchChartType(activeCommand)"
|
@click="switchChartType(activeCommand)"
|
||||||
class="fake-mask_select"
|
class="fake-mask_select"
|
||||||
></div>
|
></div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip effect="dark" content="切换图表类型" placement="top">
|
<el-tooltip effect="dark" :content="t('copilot.switch_chart')" placement="top">
|
||||||
<el-select
|
<el-select
|
||||||
popper-class="copilot-select_popper"
|
popper-class="copilot-select_popper"
|
||||||
class="select-copilot-list"
|
class="select-copilot-list"
|
||||||
@ -350,7 +352,7 @@ const tips = computed(() => {
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-divider direction="vertical" />
|
<el-divider direction="vertical" />
|
||||||
</template>
|
</template>
|
||||||
<el-tooltip effect="dark" content="切换至明细表" placement="top">
|
<el-tooltip effect="dark" :content="t('copilot.switch_table')" placement="top">
|
||||||
<el-icon
|
<el-icon
|
||||||
:class="(renderTable || renderTableLocal) && 'active'"
|
:class="(renderTable || renderTableLocal) && 'active'"
|
||||||
class="ed-icon_chart"
|
class="ed-icon_chart"
|
||||||
@ -360,7 +362,7 @@ const tips = computed(() => {
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-divider direction="vertical" />
|
<el-divider direction="vertical" />
|
||||||
<el-tooltip effect="dark" content="下载" placement="top">
|
<el-tooltip effect="dark" :content="t('copilot.download')" placement="top">
|
||||||
<el-icon class="ed-icon_chart" @click="downloadChart">
|
<el-icon class="ed-icon_chart" @click="downloadChart">
|
||||||
<Icon name="chart-download"><chartDownload class="svg-icon" /></Icon>
|
<Icon name="chart-download"><chartDownload class="svg-icon" /></Icon>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
|
@ -23,6 +23,8 @@ import DialogueChart from '@/views/copilot/DialogueChart.vue'
|
|||||||
import { type Tree } from '@/views/visualized/data/dataset/form/CreatDsGroup.vue'
|
import { type Tree } from '@/views/visualized/data/dataset/form/CreatDsGroup.vue'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { iconFieldMap } from '@/components/icon-group/field-list'
|
import { iconFieldMap } from '@/components/icon-group/field-list'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
const { t } = useI18n()
|
||||||
const quota = shallowRef([])
|
const quota = shallowRef([])
|
||||||
const dimensions = shallowRef([])
|
const dimensions = shallowRef([])
|
||||||
const datasetTree = shallowRef([])
|
const datasetTree = shallowRef([])
|
||||||
@ -105,8 +107,8 @@ const handleDatasetChange = () => {
|
|||||||
if (!!oldId && !!historyArr.value.length) {
|
if (!!oldId && !!historyArr.value.length) {
|
||||||
currentId = datasetId.value
|
currentId = datasetId.value
|
||||||
datasetId.value = oldId
|
datasetId.value = oldId
|
||||||
const msg = `当前数据集为【${oldName}】,切换数据集将清空当前会话。`
|
const msg = t('copilot.ds_prefix') + oldName + t('copilot.ds_suffix')
|
||||||
ElMessageBox.confirm('确定要切换数据集吗?', {
|
ElMessageBox.confirm(t('copilot.confirm'), {
|
||||||
confirmButtonType: 'primary',
|
confirmButtonType: 'primary',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
tip: msg,
|
tip: msg,
|
||||||
@ -209,7 +211,7 @@ const queryAnswer = (event?: KeyboardEvent) => {
|
|||||||
<el-icon style="margin-right: 8px; font-size: 24px">
|
<el-icon style="margin-right: 8px; font-size: 24px">
|
||||||
<Icon name="copilot"><copilot class="svg-icon" /></Icon>
|
<Icon name="copilot"><copilot class="svg-icon" /></Icon>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
Copilot 对话分析
|
{{ t('copilot.talking_analysis') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="copilot-service">
|
<div class="copilot-service">
|
||||||
<div class="dialogue">
|
<div class="dialogue">
|
||||||
@ -243,7 +245,7 @@ const queryAnswer = (event?: KeyboardEvent) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dataset-select" :style="{ width: showLeft ? 0 : '280px' }">
|
<div class="dataset-select" :style="{ width: showLeft ? 0 : '280px' }">
|
||||||
<el-tooltip effect="dark" content="收起" placement="left">
|
<el-tooltip effect="dark" :content="t('relation.retract')" placement="left">
|
||||||
<p v-show="!showLeft" class="arrow-right" @click="handleShowLeft(true)">
|
<p v-show="!showLeft" class="arrow-right" @click="handleShowLeft(true)">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Icon name="icon_right_outlined"><icon_right_outlined class="svg-icon" /></Icon>
|
<Icon name="icon_right_outlined"><icon_right_outlined class="svg-icon" /></Icon>
|
||||||
@ -251,19 +253,19 @@ const queryAnswer = (event?: KeyboardEvent) => {
|
|||||||
</p>
|
</p>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip effect="dark" content="展开" placement="left">
|
<el-tooltip effect="dark" :content="t('relation.expand')" placement="left">
|
||||||
<p v-show="showLeft" class="left-outlined" @click="handleShowLeft(false)">
|
<p v-show="showLeft" class="left-outlined" @click="handleShowLeft(false)">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Icon name="icon_left_outlined"><icon_left_outlined class="svg-icon" /></Icon>
|
<Icon name="icon_left_outlined"><icon_left_outlined class="svg-icon" /></Icon>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</p>
|
</p>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<div class="title-dataset_select">选择数据集</div>
|
<div class="title-dataset_select">{{ t('copilot.choose_dataset') }}</div>
|
||||||
<div style="margin: 0 16px" class="tree-select">
|
<div style="margin: 0 16px" class="tree-select">
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
v-model="datasetId"
|
v-model="datasetId"
|
||||||
:data="computedTree"
|
:data="computedTree"
|
||||||
placeholder="请选择数据集"
|
:placeholder="t('copilot.pls_choose_dataset')"
|
||||||
@change="handleDatasetChange"
|
@change="handleDatasetChange"
|
||||||
:props="dsSelectProps"
|
:props="dsSelectProps"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@ -7,7 +7,7 @@ import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
|||||||
import PreviewHead from '@/views/data-visualization/PreviewHead.vue'
|
import PreviewHead from '@/views/data-visualization/PreviewHead.vue'
|
||||||
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
||||||
import ArrowSide from '@/views/common/DeResourceArrow.vue'
|
import ArrowSide from '@/views/common/DeResourceArrow.vue'
|
||||||
import { initCanvasData, initCanvasDataPrepare } from '@/utils/canvasUtils'
|
import { initCanvasData, initCanvasDataPrepare, onInitReady } from '@/utils/canvasUtils'
|
||||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
import { useAppStoreWithOut } from '@/store/modules/app'
|
||||||
import { useRequestStoreWithOut } from '@/store/modules/request'
|
import { useRequestStoreWithOut } from '@/store/modules/request'
|
||||||
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
||||||
@ -108,6 +108,7 @@ const loadCanvasData = (dvId, weight?) => {
|
|||||||
dataInitState.value = true
|
dataInitState.value = true
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
dashboardPreview.value.restore()
|
dashboardPreview.value.restore()
|
||||||
|
onInitReady({ resourceId: dvId })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -13,7 +13,7 @@ import ViewEditor from '@/views/chart/components/editor/index.vue'
|
|||||||
import { getDatasetTree } from '@/api/dataset'
|
import { getDatasetTree } from '@/api/dataset'
|
||||||
import { Tree } from '@/views/visualized/data/dataset/form/CreatDsGroup.vue'
|
import { Tree } from '@/views/visualized/data/dataset/form/CreatDsGroup.vue'
|
||||||
import DbCanvasAttr from '@/components/dashboard/DbCanvasAttr.vue'
|
import DbCanvasAttr from '@/components/dashboard/DbCanvasAttr.vue'
|
||||||
import { decompressionPre, initCanvasData } from '@/utils/canvasUtils'
|
import { decompressionPre, initCanvasData, onInitReady } from '@/utils/canvasUtils'
|
||||||
import ChartStyleBatchSet from '@/views/chart/components/editor/editor-style/ChartStyleBatchSet.vue'
|
import ChartStyleBatchSet from '@/views/chart/components/editor/editor-style/ChartStyleBatchSet.vue'
|
||||||
import DeCanvas from '@/views/canvas/DeCanvas.vue'
|
import DeCanvas from '@/views/canvas/DeCanvas.vue'
|
||||||
import { check, compareStorage } from '@/utils/CrossPermission'
|
import { check, compareStorage } from '@/utils/CrossPermission'
|
||||||
@ -160,6 +160,7 @@ const initLocalCanvasData = () => {
|
|||||||
snapshotStore.recordSnapshotCache()
|
snapshotStore.recordSnapshotCache()
|
||||||
}, 1500)
|
}, 1500)
|
||||||
}
|
}
|
||||||
|
onInitReady({ resourceId: resourceId })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@ -281,6 +282,7 @@ onUnmounted(() => {
|
|||||||
:width="420"
|
:width="420"
|
||||||
:side-name="'componentProp'"
|
:side-name="'componentProp'"
|
||||||
:aside-position="'right'"
|
:aside-position="'right'"
|
||||||
|
:view="canvasViewInfo[curComponent.id]"
|
||||||
class="left-sidebar"
|
class="left-sidebar"
|
||||||
>
|
>
|
||||||
<component :is="findComponentAttr(curComponent)" :themes="'light'" />
|
<component :is="findComponentAttr(curComponent)" :themes="'light'" />
|
||||||
|
@ -3,7 +3,6 @@ import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
|||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { ElScrollbar } from 'element-plus-secondary'
|
|
||||||
|
|
||||||
const dvMainStore = dvMainStoreWithOut()
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
const { fullscreenFlag } = storeToRefs(dvMainStore)
|
const { fullscreenFlag } = storeToRefs(dvMainStore)
|
||||||
|
@ -4,7 +4,7 @@ import { nextTick, onMounted, reactive, ref } from 'vue'
|
|||||||
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||||
import { initCanvasData } from '@/utils/canvasUtils'
|
import { initCanvasData, onInitReady } from '@/utils/canvasUtils'
|
||||||
import { queryTargetVisualizationJumpInfo } from '@/api/visualization/linkJump'
|
import { queryTargetVisualizationJumpInfo } from '@/api/visualization/linkJump'
|
||||||
import { Base64 } from 'js-base64'
|
import { Base64 } from 'js-base64'
|
||||||
import { getOuterParamsInfo } from '@/api/visualization/outerParams'
|
import { getOuterParamsInfo } from '@/api/visualization/outerParams'
|
||||||
@ -28,7 +28,7 @@ const state = reactive({
|
|||||||
canvasViewInfoPreview: null,
|
canvasViewInfoPreview: null,
|
||||||
dvInfo: null,
|
dvInfo: null,
|
||||||
curPreviewGap: 0,
|
curPreviewGap: 0,
|
||||||
initState: false
|
initState: true
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -116,7 +116,6 @@ const loadCanvasDataAsync = async (dvId, dvType) => {
|
|||||||
canvasViewInfoPreview,
|
canvasViewInfoPreview,
|
||||||
curPreviewGap
|
curPreviewGap
|
||||||
}) {
|
}) {
|
||||||
state.initState = false
|
|
||||||
state.canvasDataPreview = canvasDataResult
|
state.canvasDataPreview = canvasDataResult
|
||||||
state.canvasStylePreview = canvasStyleResult
|
state.canvasStylePreview = canvasStyleResult
|
||||||
state.canvasViewInfoPreview = canvasViewInfoPreview
|
state.canvasViewInfoPreview = canvasViewInfoPreview
|
||||||
@ -125,6 +124,7 @@ const loadCanvasDataAsync = async (dvId, dvType) => {
|
|||||||
if (jumpParam) {
|
if (jumpParam) {
|
||||||
dvMainStore.addViewTrackFilter(jumpParam)
|
dvMainStore.addViewTrackFilter(jumpParam)
|
||||||
}
|
}
|
||||||
|
state.initState = false
|
||||||
dvMainStore.addOuterParamsFilter(attachParam)
|
dvMainStore.addOuterParamsFilter(attachParam)
|
||||||
state.initState = true
|
state.initState = true
|
||||||
if (props.publicLinkStatus) {
|
if (props.publicLinkStatus) {
|
||||||
@ -133,9 +133,13 @@ const loadCanvasDataAsync = async (dvId, dvType) => {
|
|||||||
setTitle(dvInfo.name)
|
setTitle(dvInfo.name)
|
||||||
}
|
}
|
||||||
initBrowserTimer()
|
initBrowserTimer()
|
||||||
|
nextTick(() => {
|
||||||
|
onInitReady({ resourceId: dvId })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadH2 = type => {
|
const downloadH2 = type => {
|
||||||
downloadStatus.value = true
|
downloadStatus.value = true
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
@ -8,7 +8,7 @@ import PreviewHead from '@/views/data-visualization/PreviewHead.vue'
|
|||||||
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
import { useAppStoreWithOut } from '@/store/modules/app'
|
||||||
import { initCanvasData, initCanvasDataPrepare } from '@/utils/canvasUtils'
|
import { initCanvasData, initCanvasDataPrepare, onInitReady } from '@/utils/canvasUtils'
|
||||||
import { useRequestStoreWithOut } from '@/store/modules/request'
|
import { useRequestStoreWithOut } from '@/store/modules/request'
|
||||||
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
||||||
import { useMoveLine } from '@/hooks/web/useMoveLine'
|
import { useMoveLine } from '@/hooks/web/useMoveLine'
|
||||||
@ -92,6 +92,9 @@ const loadCanvasData = (dvId, weight?) => {
|
|||||||
dvPreviewRef.value?.restore()
|
dvPreviewRef.value?.restore()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
nextTick(() => {
|
||||||
|
onInitReady({ resourceId: dvId })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,8 @@ import {
|
|||||||
decompressionPre,
|
decompressionPre,
|
||||||
findDragComponent,
|
findDragComponent,
|
||||||
findNewComponent,
|
findNewComponent,
|
||||||
initCanvasData
|
initCanvasData,
|
||||||
|
onInitReady
|
||||||
} from '@/utils/canvasUtils'
|
} from '@/utils/canvasUtils'
|
||||||
import CanvasCore from '@/components/data-visualization/canvas/CanvasCore.vue'
|
import CanvasCore from '@/components/data-visualization/canvas/CanvasCore.vue'
|
||||||
import { listenGlobalKeyDown, releaseAttachKey } from '@/utils/DeShortcutKey'
|
import { listenGlobalKeyDown, releaseAttachKey } from '@/utils/DeShortcutKey'
|
||||||
@ -245,6 +246,7 @@ const initLocalCanvasData = async () => {
|
|||||||
snapshotStore.recordSnapshotCache('renderChart')
|
snapshotStore.recordSnapshotCache('renderChart')
|
||||||
}, 1500)
|
}, 1500)
|
||||||
}
|
}
|
||||||
|
onInitReady({ resourceId: resourceId })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -490,6 +492,8 @@ eventBus.on('handleNew', handleNew)
|
|||||||
:side-name="'componentProp'"
|
:side-name="'componentProp'"
|
||||||
:aside-position="'right'"
|
:aside-position="'right'"
|
||||||
class="left-sidebar"
|
class="left-sidebar"
|
||||||
|
:slide-index="2"
|
||||||
|
:view="canvasViewInfo[curComponent.id]"
|
||||||
:class="{ 'preview-aside': editMode === 'preview' }"
|
:class="{ 'preview-aside': editMode === 'preview' }"
|
||||||
>
|
>
|
||||||
<component :is="findComponentAttr(curComponent)" />
|
<component :is="findComponentAttr(curComponent)" />
|
||||||
|
@ -48,7 +48,9 @@
|
|||||||
|
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
effect="dark"
|
effect="dark"
|
||||||
:content="pwdItem[item.pkey]['hidden'] ? '点击显示' : '点击隐藏'"
|
:content="
|
||||||
|
pwdItem[item.pkey]['hidden'] ? t('system.click_to_show') : t('system.click_to_hide')
|
||||||
|
"
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<el-button text @click="switchPwd(item.pkey)" class="setting-tip-btn">
|
<el-button text @click="switchPwd(item.pkey)" class="setting-tip-btn">
|
||||||
@ -64,7 +66,7 @@
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<span v-else-if="item.pkey.includes('basic.dsIntervalTime')">
|
<span v-else-if="item.pkey.includes('basic.dsIntervalTime')">
|
||||||
<span>{{ item.pval + ' ' + executeTime + '执行一次' }}</span>
|
<span>{{ item.pval + ' ' + executeTime + t('common.every_exec') }}</span>
|
||||||
</span>
|
</span>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<span>{{ item.pval }}</span>
|
<span>{{ item.pval }}</span>
|
||||||
@ -113,7 +115,7 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
settingTitle: {
|
settingTitle: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '基础设置'
|
default: ''
|
||||||
},
|
},
|
||||||
hideHead: {
|
hideHead: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -132,9 +134,9 @@ const props = defineProps({
|
|||||||
default: () => []
|
default: () => []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const executeTime = ref('0分0秒')
|
const executeTime = ref(t('system.and_0_seconds'))
|
||||||
const curTitle = computed(() => {
|
const curTitle = computed(() => {
|
||||||
return props.settingTitle
|
return props.settingTitle || t('system.basic_settings')
|
||||||
})
|
})
|
||||||
const copyVal = async val => {
|
const copyVal = async val => {
|
||||||
try {
|
try {
|
||||||
@ -159,8 +161,8 @@ const loadList = () => {
|
|||||||
|
|
||||||
const getExecuteTime = val => {
|
const getExecuteTime = val => {
|
||||||
const options = [
|
const options = [
|
||||||
{ value: 'minute', label: '分钟(执行时间:0秒)' },
|
{ value: 'minute', label: t('system.time_0_seconds') },
|
||||||
{ value: 'hour', label: '小时(执行时间:0分0秒)' }
|
{ value: 'hour', label: t('system.and_0_seconds_de') }
|
||||||
]
|
]
|
||||||
return options.filter(item => item.value === val)[0].label
|
return options.filter(item => item.value === val)[0].label
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,18 @@
|
|||||||
import icon_upload_outlined from '@/assets/svg/icon_upload_outlined.svg'
|
import icon_upload_outlined from '@/assets/svg/icon_upload_outlined.svg'
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
import { uploadFontFile } from '@/api/font'
|
import { uploadFontFile } from '@/api/font'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import FontInfo from './FontInfo.vue'
|
import FontInfo from './FontInfo.vue'
|
||||||
import { ElMessage } from 'element-plus-secondary'
|
import { ElMessage } from 'element-plus-secondary'
|
||||||
import { edit } from '@/api/font'
|
import { edit } from '@/api/font'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
fileList: null
|
fileList: null
|
||||||
})
|
})
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const upload = ref()
|
const upload = ref()
|
||||||
|
const { t } = useI18n()
|
||||||
const uploadExcel = () => {
|
const uploadExcel = () => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', state.fileList.raw)
|
formData.append('file', state.fileList.raw)
|
||||||
@ -53,7 +56,7 @@ const defaultForm = {
|
|||||||
const ruleForm = reactive(cloneDeep(defaultForm))
|
const ruleForm = reactive(cloneDeep(defaultForm))
|
||||||
|
|
||||||
const init = (val, type, item) => {
|
const init = (val, type, item) => {
|
||||||
dialogTitle.value = val || '添加字体'
|
dialogTitle.value = val || t('system.add_font')
|
||||||
action.value = type
|
action.value = type
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
Object.assign(ruleForm, cloneDeep(defaultForm))
|
Object.assign(ruleForm, cloneDeep(defaultForm))
|
||||||
@ -67,8 +70,8 @@ const fontDel = () => {
|
|||||||
const ruleFormRef = ref()
|
const ruleFormRef = ref()
|
||||||
const rules = {
|
const rules = {
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: '请输入字体名称', trigger: 'blur' },
|
{ required: true, message: t('system.the_font_name'), trigger: 'blur' },
|
||||||
{ min: 1, max: 50, message: '字符长度1-50', trigger: 'blur' }
|
{ min: 1, max: 50, message: t('system.character_length_1_50'), trigger: 'blur' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
defineExpose({
|
defineExpose({
|
||||||
@ -77,7 +80,7 @@ defineExpose({
|
|||||||
|
|
||||||
const beforeAvatarUpload = rawFile => {
|
const beforeAvatarUpload = rawFile => {
|
||||||
if (!rawFile.name.endsWith('.ttf')) {
|
if (!rawFile.name.endsWith('.ttf')) {
|
||||||
ElMessage.error('只支持上传ttf格式的字体文件!')
|
ElMessage.error(t('system.in_ttf_format'))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -105,12 +108,12 @@ const confirm = () => {
|
|||||||
if (val) {
|
if (val) {
|
||||||
if (action.value === 'uploadFile') {
|
if (action.value === 'uploadFile') {
|
||||||
if (ruleForm.fileTransName === '') {
|
if (ruleForm.fileTransName === '') {
|
||||||
ElMessage.error('请上传字库文件')
|
ElMessage.error(t('system.upload_font_file_de'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
edit(ruleForm).then(() => {
|
edit(ruleForm).then(() => {
|
||||||
ElMessage.success(dialogTitle.value + '成功')
|
ElMessage.success(dialogTitle.value + t('data_set.success'))
|
||||||
cancel()
|
cancel()
|
||||||
emits('finish')
|
emits('finish')
|
||||||
})
|
})
|
||||||
@ -136,10 +139,14 @@ const confirm = () => {
|
|||||||
label-width="auto"
|
label-width="auto"
|
||||||
class="demo-ruleForm"
|
class="demo-ruleForm"
|
||||||
>
|
>
|
||||||
<el-form-item v-if="action !== 'uploadFile'" label="字体名称" prop="name">
|
<el-form-item v-if="action !== 'uploadFile'" :label="t('system.font_name')" prop="name">
|
||||||
<el-input placeholder="请输入字体名称" v-model.trim="ruleForm.name" />
|
<el-input :placeholder="t('system.the_font_name')" v-model.trim="ruleForm.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-loading="loading" v-if="action !== 'rename'" label="字库文件">
|
<el-form-item
|
||||||
|
v-loading="loading"
|
||||||
|
v-if="action !== 'rename'"
|
||||||
|
:label="t('system.font_file_de')"
|
||||||
|
>
|
||||||
<el-upload
|
<el-upload
|
||||||
action=""
|
action=""
|
||||||
:multiple="false"
|
:multiple="false"
|
||||||
@ -158,7 +165,7 @@ const confirm = () => {
|
|||||||
<template #icon>
|
<template #icon>
|
||||||
<Icon name="icon_upload_outlined"><icon_upload_outlined class="svg-icon" /></Icon>
|
<Icon name="icon_upload_outlined"><icon_upload_outlined class="svg-icon" /></Icon>
|
||||||
</template>
|
</template>
|
||||||
上传字库文件
|
{{ t('system.upload_font_file') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
@ -182,15 +189,17 @@ const confirm = () => {
|
|||||||
v-show="state.fileList"
|
v-show="state.fileList"
|
||||||
>
|
>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<el-button text> 重新上传 </el-button>
|
<el-button text> {{ t('data_source.reupload') }} </el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="cancel">取消</el-button>
|
<el-button @click="cancel">{{ t('userimport.cancel') }}</el-button>
|
||||||
<el-button v-loading="loading" type="primary" @click="confirm"> 确定 </el-button>
|
<el-button v-loading="loading" type="primary" @click="confirm">
|
||||||
|
{{ t('userimport.sure') }}
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
@ -4,12 +4,13 @@ import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
|
|||||||
import { onMounted, ref, computed } from 'vue'
|
import { onMounted, ref, computed } from 'vue'
|
||||||
import UploadDetail from './UploadDetail.vue'
|
import UploadDetail from './UploadDetail.vue'
|
||||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { deleteById, edit, defaultFont } from '@/api/font'
|
import { deleteById, edit, defaultFont } from '@/api/font'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus-secondary'
|
import { ElMessage, ElMessageBox } from 'element-plus-secondary'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
const appearanceStore = useAppearanceStoreWithOut()
|
const appearanceStore = useAppearanceStoreWithOut()
|
||||||
|
const { t } = useI18n()
|
||||||
const fontKeyword = ref('')
|
const fontKeyword = ref('')
|
||||||
const fontList = ref([])
|
const fontList = ref([])
|
||||||
const basePath = import.meta.env.VITE_API_BASEPATH
|
const basePath = import.meta.env.VITE_API_BASEPATH
|
||||||
@ -35,10 +36,10 @@ const fontListComputed = computed(() => {
|
|||||||
|
|
||||||
const deleteFont = item => {
|
const deleteFont = item => {
|
||||||
if (item.isDefault) {
|
if (item.isDefault) {
|
||||||
ElMessage.warning('请先将其他字体设置为默认字体,再进行删除。')
|
ElMessage.warning(t('system.fonts_before_deleting'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ElMessageBox.confirm('当前字体被删除后,使用该字体的组件将会使用默认字体,确定删除?', {
|
ElMessageBox.confirm(t('system.sure_to_delete'), {
|
||||||
confirmButtonType: 'danger',
|
confirmButtonType: 'danger',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
@ -47,7 +48,7 @@ const deleteFont = item => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
deleteById(item.id)
|
deleteById(item.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success('删除成功')
|
ElMessage.success(t('common.delete_success'))
|
||||||
listFont()
|
listFont()
|
||||||
getDefaultFont()
|
getDefaultFont()
|
||||||
})
|
})
|
||||||
@ -62,7 +63,7 @@ const setToDefault = item => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
edit(item)
|
edit(item)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success('设置成功')
|
ElMessage.success(t('system.setting_successful'))
|
||||||
getDefaultFont()
|
getDefaultFont()
|
||||||
listFont()
|
listFont()
|
||||||
})
|
})
|
||||||
@ -115,9 +116,14 @@ onMounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="font-management_system" v-loading="loading">
|
<div class="font-management_system" v-loading="loading">
|
||||||
<div class="route-title">
|
<div class="route-title">
|
||||||
字体管理
|
{{ t('system.font_management') }}
|
||||||
<div class="search-font">
|
<div class="search-font">
|
||||||
<el-input v-model="fontKeyword" clearable style="width: 240px" placeholder="搜索字体名称">
|
<el-input
|
||||||
|
v-model="fontKeyword"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
:placeholder="t('system.search_font_name')"
|
||||||
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Icon name="icon_search-outline_outlined"
|
<Icon name="icon_search-outline_outlined"
|
||||||
@ -127,42 +133,45 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
|
||||||
<el-button type="primary" @click="uploadFont('新建字体', 'create', {})">
|
<el-button type="primary" @click="uploadFont(t('system.a_new_font'), 'create', {})">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||||
</template>
|
</template>
|
||||||
添加字体
|
{{ t('system.add_font') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="font-content_overflow">
|
<div class="font-content_overflow">
|
||||||
<div class="font-content_list">
|
<div class="font-content_list">
|
||||||
<div class="font-content_item" v-for="ele in fontListComputed" :key="ele">
|
<div class="font-content_item" v-for="ele in fontListComputed" :key="ele">
|
||||||
<span v-if="ele.isDefault" class="font-default">默认字体</span>
|
<span v-if="ele.isDefault" class="font-default">{{ t('system.default_font') }}</span>
|
||||||
<div class="font-name">
|
<div class="font-name">
|
||||||
{{ ele.name }} <span v-if="ele.isBuiltin" class="font-type"> 系统内置 </span>
|
{{ ele.name }}
|
||||||
|
<span v-if="ele.isBuiltin" class="font-type"> {{ t('system.system_built_in') }} </span>
|
||||||
</div>
|
</div>
|
||||||
<div :title="ele.fileName" class="font-update_time">
|
<div :title="ele.fileName" class="font-update_time">
|
||||||
更新时间: {{ new Date(ele.updateTime).toLocaleString() }}
|
{{ t('system.update_time') }} {{ new Date(ele.updateTime).toLocaleString() }}
|
||||||
<span class="line"></span> 字库文件: {{ ele.fileName }}
|
<span class="line"></span> {{ t('system.font_file') }} {{ ele.fileName }}
|
||||||
</div>
|
</div>
|
||||||
<div class="font-upload_btn">
|
<div class="font-upload_btn">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="!ele.fileTransName"
|
v-if="!ele.fileTransName"
|
||||||
@click="uploadFont('上传字库文件', 'uploadFile', ele)"
|
@click="uploadFont(t('system.upload_font_file'), 'uploadFile', ele)"
|
||||||
secondary
|
secondary
|
||||||
>上传字库文件</el-button
|
>{{ t('system.upload_font_file') }}</el-button
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="ele.fileTransName"
|
v-if="ele.fileTransName"
|
||||||
@click="uploadFont('替换字库文件', 'uploadFile', ele)"
|
@click="uploadFont(t('system.replace_font_file'), 'uploadFile', ele)"
|
||||||
secondary
|
secondary
|
||||||
>替换字库文件</el-button
|
>{{ t('system.replace_font_file') }}</el-button
|
||||||
>
|
>
|
||||||
<el-button v-if="!ele.isDefault" @click="setToDefault(ele)" secondary
|
<el-button v-if="!ele.isDefault" @click="setToDefault(ele)" secondary>{{
|
||||||
>设为默认字体</el-button
|
t('system.as_default_font')
|
||||||
>
|
}}</el-button>
|
||||||
<el-button v-if="ele.id !== '1'" @click="deleteFont(ele)" secondary>删除</el-button>
|
<el-button v-if="ele.id !== '1'" @click="deleteFont(ele)" secondary>{{
|
||||||
|
t('common.delete')
|
||||||
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +19,7 @@ const pwdForm = reactive(cloneDeep(defaultForm))
|
|||||||
|
|
||||||
const validatePwd = (_: any, value: any, callback: any) => {
|
const validatePwd = (_: any, value: any, callback: any) => {
|
||||||
if (value === pwdForm.pwd) {
|
if (value === pwdForm.pwd) {
|
||||||
callback(new Error('新旧密码不能相同'))
|
callback(new Error(t('system.be_the_same')))
|
||||||
}
|
}
|
||||||
const pattern =
|
const pattern =
|
||||||
/^.*(?=.{6,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/])[a-zA-Z0-9~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/]*$/
|
/^.*(?=.{6,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/])[a-zA-Z0-9~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/]*$/
|
||||||
@ -34,7 +34,7 @@ const validatePwd = (_: any, value: any, callback: any) => {
|
|||||||
|
|
||||||
const validateConfirmPwd = (_: any, value: any, callback: any) => {
|
const validateConfirmPwd = (_: any, value: any, callback: any) => {
|
||||||
if (value !== pwdForm.newPwd) {
|
if (value !== pwdForm.newPwd) {
|
||||||
callback(new Error('两次输入的密码不一致'))
|
callback(new Error(t('system.twice_are_inconsistent')))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ const save = () => {
|
|||||||
const pwd = rsaEncryp(pwdForm.pwd)
|
const pwd = rsaEncryp(pwdForm.pwd)
|
||||||
const newPwd = rsaEncryp(pwdForm.newPwd)
|
const newPwd = rsaEncryp(pwdForm.newPwd)
|
||||||
request.post({ url: '/user/modifyPwd', data: { pwd, newPwd } }).then(() => {
|
request.post({ url: '/user/modifyPwd', data: { pwd, newPwd } }).then(() => {
|
||||||
ElMessage.success('修改成功,请重新登录')
|
ElMessage.success(t('system.log_in_again'))
|
||||||
logoutHandler()
|
logoutHandler()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -103,28 +103,28 @@ const save = () => {
|
|||||||
label-width="80px"
|
label-width="80px"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
>
|
>
|
||||||
<el-form-item label="原始密码" prop="pwd">
|
<el-form-item :label="t('system.original_password')" prop="pwd">
|
||||||
<CustomPassword
|
<CustomPassword
|
||||||
v-model="pwdForm.pwd"
|
v-model="pwdForm.pwd"
|
||||||
show-password
|
show-password
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="请输入原始密码"
|
:placeholder="t('system.the_original_password')"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="新密码" prop="newPwd">
|
<el-form-item :label="t('system.new_password')" prop="newPwd">
|
||||||
<CustomPassword
|
<CustomPassword
|
||||||
v-model="pwdForm.newPwd"
|
v-model="pwdForm.newPwd"
|
||||||
show-password
|
show-password
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="请输入新密码"
|
:placeholder="t('system.the_new_password')"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="确认密码" prop="confirm">
|
<el-form-item :label="t('system.confirm_password')" prop="confirm">
|
||||||
<CustomPassword
|
<CustomPassword
|
||||||
v-model="pwdForm.confirm"
|
v-model="pwdForm.confirm"
|
||||||
show-password
|
show-password
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="请输入确认密码"
|
:placeholder="t('system.the_confirmation_password')"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-button @click="save" type="primary">
|
<el-button @click="save" type="primary">
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="user-center flex-align-center">
|
<div class="user-center flex-align-center">
|
||||||
<div class="user-center-container">
|
<div class="user-center-container">
|
||||||
<div class="user-tabs">
|
<div class="user-tabs">
|
||||||
<div class="tabs-title flex-align-center">用户中心</div>
|
<div class="tabs-title flex-align-center">{{ t('commons.user_center') }}</div>
|
||||||
<el-divider />
|
<el-divider />
|
||||||
<div class="list-item_primary active">
|
<div class="list-item_primary active">
|
||||||
{{ t('user.change_password') }}
|
{{ t('user.change_password') }}
|
||||||
|
@ -9,15 +9,15 @@ const dialogVisible = ref(false)
|
|||||||
const loadingInstance = ref(null)
|
const loadingInstance = ref(null)
|
||||||
const basicForm = ref<FormInstance>()
|
const basicForm = ref<FormInstance>()
|
||||||
const options = [
|
const options = [
|
||||||
{ value: 'minute', label: '分钟(执行时间:0秒)' },
|
{ value: 'minute', label: t('system.time_0_seconds') },
|
||||||
{ value: 'hour', label: '小时(执行时间:0分0秒)' }
|
{ value: 'hour', label: t('system.and_0_seconds_de') }
|
||||||
]
|
]
|
||||||
const pvpOptions = [
|
const pvpOptions = [
|
||||||
{ value: '0', label: '永久' },
|
{ value: '0', label: t('commons.date.permanent') },
|
||||||
{ value: '1', label: '一年' },
|
{ value: '1', label: t('commons.date.one_year') },
|
||||||
{ value: '2', label: '半年' },
|
{ value: '2', label: t('commons.date.six_months') },
|
||||||
{ value: '3', label: '三个月' },
|
{ value: '3', label: t('commons.date.three_months') },
|
||||||
{ value: '4', label: '一个月' }
|
{ value: '4', label: t('commons.date.one_month') }
|
||||||
]
|
]
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
@ -30,7 +30,7 @@ const state = reactive({
|
|||||||
orgOptions: [],
|
orgOptions: [],
|
||||||
roleOptions: [],
|
roleOptions: [],
|
||||||
loginOptions: [
|
loginOptions: [
|
||||||
{ value: '0', label: '普通登录' },
|
{ value: '0', label: t('system.normal_login') },
|
||||||
{ value: '1', label: 'LDAP' },
|
{ value: '1', label: 'LDAP' },
|
||||||
{ value: '2', label: 'OIDC' },
|
{ value: '2', label: 'OIDC' },
|
||||||
{ value: '3', label: 'CAS' },
|
{ value: '3', label: 'CAS' },
|
||||||
@ -69,14 +69,14 @@ const submitForm = async (formEl: FormInstance | undefined) => {
|
|||||||
state.form.dsExecuteTime === 'minute' &&
|
state.form.dsExecuteTime === 'minute' &&
|
||||||
(Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 59)
|
(Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 59)
|
||||||
) {
|
) {
|
||||||
ElMessage.error('分钟超出范围【1-59】')
|
ElMessage.error(t('commons.date.of_range_1_59'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
state.form.dsExecuteTime === 'hour' &&
|
state.form.dsExecuteTime === 'hour' &&
|
||||||
(Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 23)
|
(Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 23)
|
||||||
) {
|
) {
|
||||||
ElMessage.error('小时超出范围【1-23】')
|
ElMessage.error(t('commons.date.of_range_1_23'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const param = buildSettingList()
|
const param = buildSettingList()
|
||||||
@ -210,7 +210,7 @@ defineExpose({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-drawer
|
<el-drawer
|
||||||
title="基础设置"
|
:title="t('system.basic_settings')"
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
custom-class="basic-param-drawer"
|
custom-class="basic-param-drawer"
|
||||||
size="600px"
|
size="600px"
|
||||||
@ -245,7 +245,7 @@ defineExpose({
|
|||||||
v-model="state.form[item.pkey]"
|
v-model="state.form[item.pkey]"
|
||||||
/>
|
/>
|
||||||
<div v-else-if="item.pkey === 'dsIntervalTime'" class="ds-task-form-inline">
|
<div v-else-if="item.pkey === 'dsIntervalTime'" class="ds-task-form-inline">
|
||||||
<span>每</span>
|
<span>{{ t('cron.every') }}</span>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="state.form.dsIntervalTime"
|
v-model="state.form.dsIntervalTime"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
@ -264,7 +264,7 @@ defineExpose({
|
|||||||
:value="item.value"
|
:value="item.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
<span class="ds-span">执行一次</span>
|
<span class="ds-span">{{ t('cron.every_exec') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.pkey === 'frontTimeOut'">
|
<div v-else-if="item.pkey === 'frontTimeOut'">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
ref="infoTemplate"
|
ref="infoTemplate"
|
||||||
:label-tooltips="tooltips"
|
:label-tooltips="tooltips"
|
||||||
setting-key="basic"
|
setting-key="basic"
|
||||||
setting-title="基础设置"
|
:setting-title="t('system.basic_settings')"
|
||||||
:setting-data="state.templateList"
|
:setting-data="state.templateList"
|
||||||
@edit="edit"
|
@edit="edit"
|
||||||
/>
|
/>
|
||||||
@ -24,24 +24,24 @@ const editor = ref()
|
|||||||
const infoTemplate = ref()
|
const infoTemplate = ref()
|
||||||
const showDefaultLogin = ref(false)
|
const showDefaultLogin = ref(false)
|
||||||
const pvpOptions = [
|
const pvpOptions = [
|
||||||
{ value: '0', label: '永久' },
|
{ value: '0', label: t('commons.date.permanent') },
|
||||||
{ value: '1', label: '一年' },
|
{ value: '1', label: t('commons.date.one_year') },
|
||||||
{ value: '2', label: '半年' },
|
{ value: '2', label: t('commons.date.six_months') },
|
||||||
{ value: '3', label: '三个月' },
|
{ value: '3', label: t('commons.date.three_months') },
|
||||||
{ value: '4', label: '一个月' }
|
{ value: '4', label: t('commons.date.one_month') }
|
||||||
]
|
]
|
||||||
const tooltips = [
|
const tooltips = [
|
||||||
{
|
{
|
||||||
key: 'setting_basic.frontTimeOut',
|
key: 'setting_basic.frontTimeOut',
|
||||||
val: '请求超时时间(单位:秒,注意:保存后刷新浏览器生效)'
|
val: t('system.to_take_effect')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'setting_basic.platformOid',
|
key: 'setting_basic.platformOid',
|
||||||
val: '作用域包括认证设置和平台对接'
|
val: t('system.and_platform_docking')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'setting_basic.platformRid',
|
key: 'setting_basic.platformRid',
|
||||||
val: '作用域包括认证设置和平台对接'
|
val: t('system.and_platform_docking')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'setting_basic.shareDisable',
|
key: 'setting_basic.shareDisable',
|
||||||
@ -66,7 +66,7 @@ const state = reactive({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
loginOptions: [
|
loginOptions: [
|
||||||
{ value: '0', label: '普通登录' },
|
{ value: '0', label: t('system.normal_login') },
|
||||||
{ value: '1', label: 'LDAP' },
|
{ value: '1', label: 'LDAP' },
|
||||||
{ value: '2', label: 'OIDC' },
|
{ value: '2', label: 'OIDC' },
|
||||||
{ value: '3', label: 'CAS' },
|
{ value: '3', label: 'CAS' },
|
||||||
@ -95,11 +95,11 @@ const search = cb => {
|
|||||||
item.pkey === 'basic.shareDisable' ||
|
item.pkey === 'basic.shareDisable' ||
|
||||||
item.pkey === 'basic.sharePeRequire'
|
item.pkey === 'basic.sharePeRequire'
|
||||||
) {
|
) {
|
||||||
item.pval = item.pval === 'true' ? '开启' : '未开启'
|
item.pval = item.pval === 'true' ? t('chart.open') : t('system.not_enabled')
|
||||||
} else if (item.pkey === 'basic.platformOid') {
|
} else if (item.pkey === 'basic.platformOid') {
|
||||||
selectedOid.value = item.pval
|
selectedOid.value = item.pval
|
||||||
await loadOrgOptions()
|
await loadOrgOptions()
|
||||||
item.pval = selectedOName.value || '默认组织'
|
item.pval = selectedOName.value || t('system.default_organization')
|
||||||
} else if (item.pkey === 'basic.platformRid') {
|
} else if (item.pkey === 'basic.platformRid') {
|
||||||
const pval = item.pval
|
const pval = item.pval
|
||||||
if (pval?.length) {
|
if (pval?.length) {
|
||||||
@ -109,11 +109,11 @@ const search = cb => {
|
|||||||
if (selectedRName.value.length) {
|
if (selectedRName.value.length) {
|
||||||
item.pval = selectedRName.value.join(',')
|
item.pval = selectedRName.value.join(',')
|
||||||
} else {
|
} else {
|
||||||
item.pval = '普通角色'
|
item.pval = t('system.normal_role')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedRid.value = []
|
selectedRid.value = []
|
||||||
item.pval = '普通角色'
|
item.pval = t('system.normal_role')
|
||||||
}
|
}
|
||||||
} else if (item.pkey === 'basic.pvp') {
|
} else if (item.pkey === 'basic.pvp') {
|
||||||
selectedPvp.value = item.pval || '0'
|
selectedPvp.value = item.pval || '0'
|
||||||
|
@ -254,7 +254,7 @@ defineExpose({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-drawer
|
<el-drawer
|
||||||
title="引擎设置"
|
:title="t('system.engine_settings')"
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
custom-class="basic-param-drawer"
|
custom-class="basic-param-drawer"
|
||||||
size="600px"
|
size="600px"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
setting-key="basic"
|
setting-key="basic"
|
||||||
showValidate
|
showValidate
|
||||||
style="padding-bottom: 0"
|
style="padding-bottom: 0"
|
||||||
setting-title="引擎设置"
|
:setting-title="t('system.engine_settings')"
|
||||||
:setting-data="templateList"
|
:setting-data="templateList"
|
||||||
@edit="edit"
|
@edit="edit"
|
||||||
@check="validateById"
|
@check="validateById"
|
||||||
@ -91,7 +91,7 @@ const getEngine = () => {
|
|||||||
|
|
||||||
templateList.value = [
|
templateList.value = [
|
||||||
{
|
{
|
||||||
pkey: '引擎类型',
|
pkey: t('system.engine_type'),
|
||||||
pval: typeMap[type],
|
pval: typeMap[type],
|
||||||
type: '',
|
type: '',
|
||||||
sort: 0
|
sort: 0
|
||||||
|
@ -28,9 +28,9 @@ import { XpackComponent } from '@/components/plugin'
|
|||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const tabArray = ref([
|
const tabArray = ref([
|
||||||
{ label: '基础设置', name: 'basic' },
|
{ label: t('system.basic_settings'), name: 'basic' },
|
||||||
{ label: '地图设置', name: 'map' },
|
{ label: t('system.map_settings'), name: 'map' },
|
||||||
{ label: '引擎设置', name: 'engine' }
|
{ label: t('system.engine_settings'), name: 'engine' }
|
||||||
])
|
])
|
||||||
|
|
||||||
const activeName = ref('basic')
|
const activeName = ref('basic')
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
</el-aside>
|
</el-aside>
|
||||||
<el-main class="geometry-main">
|
<el-main class="geometry-main">
|
||||||
<div class="geo-content-container" v-if="!selectedData">
|
<div class="geo-content-container" v-if="!selectedData">
|
||||||
<EmptyBackground img-type="noneWhite" description="请在左侧选择区域" />
|
<EmptyBackground img-type="noneWhite" :description="t('system.on_the_left')" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="geo-content-container">
|
<div v-else class="geo-content-container">
|
||||||
<div class="geo-content-top">
|
<div class="geo-content-top">
|
||||||
@ -77,13 +77,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="geo-content-middle">
|
<div class="geo-content-middle">
|
||||||
<div class="geo-area">
|
<div class="geo-area">
|
||||||
<div class="area-label"><span>区域代码</span></div>
|
<div class="area-label">
|
||||||
|
<span>{{ t('system.region_code') }}</span>
|
||||||
|
</div>
|
||||||
<div class="area-content">
|
<div class="area-content">
|
||||||
<span>{{ selectedData.id }}</span>
|
<span>{{ selectedData.id }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="geo-area">
|
<div class="geo-area">
|
||||||
<div class="area-label"><span>上级区域</span></div>
|
<div class="area-label">
|
||||||
|
<span>{{ t('system.superior_region') }}</span>
|
||||||
|
</div>
|
||||||
<div class="area-content">
|
<div class="area-content">
|
||||||
<span>{{ selectedData.parentName || '-' }}</span>
|
<span>{{ selectedData.parentName || '-' }}</span>
|
||||||
<span v-if="selectedData.pid" class="area-secondary">{{
|
<span v-if="selectedData.pid" class="area-secondary">{{
|
||||||
@ -93,7 +97,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="geo-content-bottom">
|
<div class="geo-content-bottom">
|
||||||
<div class="area-label"><span>坐标文件</span></div>
|
<div class="area-label">
|
||||||
|
<span>{{ t('system.coordinate_file') }}</span>
|
||||||
|
</div>
|
||||||
<el-scrollbar class="area-content-geo">
|
<el-scrollbar class="area-content-geo">
|
||||||
<span>{{ selectedData.geoJson }}</span>
|
<span>{{ selectedData.geoJson }}</span>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
@ -145,7 +151,7 @@ const handleNodeClick = async (data: Tree) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const delHandler = data => {
|
const delHandler = data => {
|
||||||
ElMessageBox.confirm('确定删除此节点吗', {
|
ElMessageBox.confirm(t('system.delete_this_node'), {
|
||||||
confirmButtonType: 'danger',
|
confirmButtonType: 'danger',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
confirmButtonText: t('common.delete'),
|
confirmButtonText: t('common.delete'),
|
||||||
|
@ -39,9 +39,7 @@ const formatPid = computed(() => {
|
|||||||
const pid = state.form.pid
|
const pid = state.form.pid
|
||||||
return pid.replace(/(0+)$/g, '').replace(/\D/g, '')
|
return pid.replace(/(0+)$/g, '').replace(/\D/g, '')
|
||||||
})
|
})
|
||||||
const codeTips = ref(
|
const codeTips = ref(t('system.at_the_end'))
|
||||||
'国家代码由三位数字组成,省、市、区县、乡镇代码由两位数字组成;非国家区域需要再后面补0'
|
|
||||||
)
|
|
||||||
const pidChange = () => {
|
const pidChange = () => {
|
||||||
state.form.code = null
|
state.form.code = null
|
||||||
}
|
}
|
||||||
@ -50,7 +48,7 @@ const validateCode = (_: any, value: any, callback: any) => {
|
|||||||
if (isCountry) {
|
if (isCountry) {
|
||||||
const reg = /^[0-9]\d{2}$/
|
const reg = /^[0-9]\d{2}$/
|
||||||
if (!reg.test(value) || value === '000') {
|
if (!reg.test(value) || value === '000') {
|
||||||
const msg = '请输入非0的三位数字'
|
const msg = t('system.non_zero_three_digit_number')
|
||||||
callback(new Error(msg))
|
callback(new Error(msg))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
@ -59,7 +57,7 @@ const validateCode = (_: any, value: any, callback: any) => {
|
|||||||
const fullValue = formatPid.value + value
|
const fullValue = formatPid.value + value
|
||||||
const reg = /^[1-9](\d{8}|\d{10})$/
|
const reg = /^[1-9](\d{8}|\d{10})$/
|
||||||
if (!reg.test(fullValue)) {
|
if (!reg.test(fullValue)) {
|
||||||
const msg = '请输入9或11位数字'
|
const msg = t('system.or_11_digits')
|
||||||
callback(new Error(msg))
|
callback(new Error(msg))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
@ -157,7 +155,7 @@ const handleExceed: UploadProps['onExceed'] = () => {
|
|||||||
ElMessage.warning(t('userimport.exceedMsg'))
|
ElMessage.warning(t('userimport.exceedMsg'))
|
||||||
}
|
}
|
||||||
const handleError = () => {
|
const handleError = () => {
|
||||||
ElMessage.warning('执行失败请联系管理员')
|
ElMessage.warning(t('system.contact_the_administrator'))
|
||||||
}
|
}
|
||||||
const setFile = (options: UploadRequestOptions) => {
|
const setFile = (options: UploadRequestOptions) => {
|
||||||
geoFile.value = options.file
|
geoFile.value = options.file
|
||||||
@ -166,12 +164,12 @@ const setFile = (options: UploadRequestOptions) => {
|
|||||||
const uploadValidate = file => {
|
const uploadValidate = file => {
|
||||||
const suffix = file.name.substring(file.name.lastIndexOf('.') + 1)
|
const suffix = file.name.substring(file.name.lastIndexOf('.') + 1)
|
||||||
if (suffix !== 'json') {
|
if (suffix !== 'json') {
|
||||||
ElMessage.warning('只能上传json文件')
|
ElMessage.warning(t('system.upload_json_files'))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.size / 1024 / 1024 > 200) {
|
if (file.size / 1024 / 1024 > 200) {
|
||||||
ElMessage.warning('最大上传200M')
|
ElMessage.warning(t('system.maximum_upload_200m'))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -191,7 +189,7 @@ defineExpose({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-drawer
|
<el-drawer
|
||||||
title="地理信息"
|
:title="t('system.geographic_information')"
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
custom-class="basic-info-drawer"
|
custom-class="basic-info-drawer"
|
||||||
size="600px"
|
size="600px"
|
||||||
@ -205,7 +203,7 @@ defineExpose({
|
|||||||
label-width="80px"
|
label-width="80px"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
>
|
>
|
||||||
<el-form-item label="上级区域" prop="pid">
|
<el-form-item :label="t('system.superior_region')" prop="pid">
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
class="map-tree-selector"
|
class="map-tree-selector"
|
||||||
node-key="id"
|
node-key="id"
|
||||||
@ -219,10 +217,10 @@ defineExpose({
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="区域代码" prop="code">
|
<el-form-item :label="t('system.region_code')" prop="code">
|
||||||
<template v-slot:label>
|
<template v-slot:label>
|
||||||
<span class="area-code-label">
|
<span class="area-code-label">
|
||||||
<span>区域代码</span>
|
<span>{{ t('system.region_code') }}</span>
|
||||||
<el-tooltip effect="dark" :content="codeTips" placement="top">
|
<el-tooltip effect="dark" :content="codeTips" placement="top">
|
||||||
<el-icon class="info-tips"
|
<el-icon class="info-tips"
|
||||||
><Icon name="dv-info"><dvInfo class="svg-icon" /></Icon
|
><Icon name="dv-info"><dvInfo class="svg-icon" /></Icon
|
||||||
@ -240,19 +238,19 @@ defineExpose({
|
|||||||
v-else
|
v-else
|
||||||
class="box-item"
|
class="box-item"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
content="请先选择上级区域"
|
:content="t('system.superior_region_first')"
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<el-input v-model="state.form.code" disabled />
|
<el-input v-model="state.form.code" disabled />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="区域名称" prop="name">
|
<el-form-item :label="t('system.region_name')" prop="name">
|
||||||
<el-input v-model="state.form.name" />
|
<el-input v-model="state.form.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<div class="geo-label-mask" />
|
<div class="geo-label-mask" />
|
||||||
<el-form-item label="坐标文件" prop="fileName">
|
<el-form-item :label="t('system.coordinate_file')" prop="fileName">
|
||||||
<el-upload
|
<el-upload
|
||||||
class="upload-geo"
|
class="upload-geo"
|
||||||
action=""
|
action=""
|
||||||
|
@ -6,6 +6,7 @@ import icon_dataset from '@/assets/svg/icon_dataset.svg'
|
|||||||
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
|
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
|
||||||
import icon_intoItem_outlined from '@/assets/svg/icon_into-item_outlined.svg'
|
import icon_intoItem_outlined from '@/assets/svg/icon_into-item_outlined.svg'
|
||||||
import icon_rename_outlined from '@/assets/svg/icon_rename_outlined.svg'
|
import icon_rename_outlined from '@/assets/svg/icon_rename_outlined.svg'
|
||||||
|
import icon_warning_colorful_red from '@/assets/svg/icon_warning_colorful_red.svg'
|
||||||
import dvFolder from '@/assets/svg/dv-folder.svg'
|
import dvFolder from '@/assets/svg/dv-folder.svg'
|
||||||
import dvNewFolder from '@/assets/svg/dv-new-folder.svg'
|
import dvNewFolder from '@/assets/svg/dv-new-folder.svg'
|
||||||
import icon_fileAdd_outlined from '@/assets/svg/icon_file-add_outlined.svg'
|
import icon_fileAdd_outlined from '@/assets/svg/icon_file-add_outlined.svg'
|
||||||
@ -380,7 +381,6 @@ const initSearch = () => {
|
|||||||
state.filterTable = tableData.value.filter(ele =>
|
state.filterTable = tableData.value.filter(ele =>
|
||||||
ele.tableName.toLowerCase().includes(nickName.value.toLowerCase())
|
ele.tableName.toLowerCase().includes(nickName.value.toLowerCase())
|
||||||
)
|
)
|
||||||
console.log(tableData.value)
|
|
||||||
state.paginationConfig.total = state.filterTable.length
|
state.paginationConfig.total = state.filterTable.length
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -867,7 +867,6 @@ const operation = (cmd: string, data: Tree, nodeType: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleClick = (tabName: TabPaneName) => {
|
const handleClick = (tabName: TabPaneName) => {
|
||||||
console.log(tabName)
|
|
||||||
switch (tabName) {
|
switch (tabName) {
|
||||||
case 'config':
|
case 'config':
|
||||||
listDatasourceTables({ datasourceId: nodeInfo.id }).then(res => {
|
listDatasourceTables({ datasourceId: nodeInfo.id }).then(res => {
|
||||||
@ -1081,18 +1080,38 @@ const getMenuList = (val: boolean) => {
|
|||||||
@node-click="handleNodeClick"
|
@node-click="handleNodeClick"
|
||||||
>
|
>
|
||||||
<template #default="{ node, data }">
|
<template #default="{ node, data }">
|
||||||
<span class="custom-tree-node">
|
<span class="custom-tree-node" style="position: relative">
|
||||||
<el-icon :class="data.leaf && 'icon-border'" style="font-size: 18px">
|
<el-icon :class="data.leaf && 'icon-border'" style="font-size: 18px">
|
||||||
<Icon :static-content="getDsIcon(data)"
|
<Icon :static-content="getDsIcon(data)"
|
||||||
><component class="svg-icon" :is="getDsIconName(data)"></component
|
><component class="svg-icon" :is="getDsIconName(data)"></component
|
||||||
></Icon>
|
></Icon>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
|
<el-icon
|
||||||
|
style="position: absolute; top: 10px; left: 10px; font-size: 12px"
|
||||||
|
v-if="data.extraFlag <= -1"
|
||||||
|
>
|
||||||
|
<Icon><icon_warning_colorful_red class="svg-icon" /></Icon>
|
||||||
|
</el-icon>
|
||||||
<span
|
<span
|
||||||
:title="node.label"
|
:title="node.label"
|
||||||
class="label-tooltip ellipsis"
|
class="label-tooltip ellipsis"
|
||||||
:class="data.type === 'Excel' && 'excel'"
|
:class="data.type === 'Excel' && 'excel'"
|
||||||
|
v-if="data.extraFlag > -1"
|
||||||
>{{ node.label }}</span
|
>{{ node.label }}</span
|
||||||
>
|
>
|
||||||
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
|
v-else
|
||||||
|
:content="`${t('data_set.invalid_data_source')}: ${node.label}`"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
:title="node.label"
|
||||||
|
class="label-tooltip ellipsis"
|
||||||
|
:class="data.type === 'Excel' && 'excel'"
|
||||||
|
>{{ node.label }}</span
|
||||||
|
>
|
||||||
|
</el-tooltip>
|
||||||
<div class="icon-more" v-if="data.weight >= 7">
|
<div class="icon-more" v-if="data.weight >= 7">
|
||||||
<handle-more
|
<handle-more
|
||||||
icon-size="24px"
|
icon-size="24px"
|
||||||
|
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
|||||||
Subproject commit 1087f588ed77a9fa2630c4bd92d71df65559793b
|
Subproject commit 4b8fe0d27463e4a6e238f862ed09bdb3c9c1b871
|
@ -176,8 +176,6 @@ function install_docker() {
|
|||||||
cp docker/service/docker.service /etc/systemd/system/
|
cp docker/service/docker.service /etc/systemd/system/
|
||||||
chmod +x /usr/bin/docker*
|
chmod +x /usr/bin/docker*
|
||||||
chmod 644 /etc/systemd/system/docker.service
|
chmod 644 /etc/systemd/system/docker.service
|
||||||
log_content "启动 docker"
|
|
||||||
systemctl enable docker >/dev/null 2>&1; systemctl daemon-reload; systemctl start docker 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
|
||||||
else
|
else
|
||||||
log_content "在线安装 docker"
|
log_content "在线安装 docker"
|
||||||
curl -fsSL https://resource.fit2cloud.com/get-docker-linux.sh -o get-docker.sh 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
curl -fsSL https://resource.fit2cloud.com/get-docker-linux.sh -o get-docker.sh 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||||
@ -186,13 +184,20 @@ function install_docker() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
sudo sh get-docker.sh 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
sudo sh get-docker.sh 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||||
log_content "启动 docker"
|
|
||||||
systemctl enable docker >/dev/null 2>&1; systemctl daemon-reload; systemctl start docker 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
docker_config_folder="/etc/docker"
|
docker_config_folder="/etc/docker"
|
||||||
if [ ! -d "$docker_config_folder" ];then
|
if [ ! -d "$docker_config_folder" ];then
|
||||||
mkdir -p "$docker_config_folder"
|
mkdir -p "$docker_config_folder"
|
||||||
|
cat <<EOF> $docker_config_folder/daemon.json
|
||||||
|
{
|
||||||
|
"log-driver": "json-file",
|
||||||
|
"log-opts": {
|
||||||
|
"max-file": "3",
|
||||||
|
"max-size": "10m"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
docker version >/dev/null 2>&1
|
docker version >/dev/null 2>&1
|
||||||
@ -201,6 +206,8 @@ function install_docker() {
|
|||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
log_content "docker 安装成功"
|
log_content "docker 安装成功"
|
||||||
|
log_content "启动 docker"
|
||||||
|
systemctl enable docker >/dev/null 2>&1; systemctl daemon-reload; systemctl start docker 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user