diff --git a/core/backend/src/main/java/io/dataease/plugins/server/XAuthServer.java b/core/backend/src/main/java/io/dataease/plugins/server/XAuthServer.java index 61e4094dce..e13b22ebb0 100644 --- a/core/backend/src/main/java/io/dataease/plugins/server/XAuthServer.java +++ b/core/backend/src/main/java/io/dataease/plugins/server/XAuthServer.java @@ -129,6 +129,10 @@ public class XAuthServer { if (StringUtils.equals("panel", sourceType)) { return SysLogConstants.SOURCE_TYPE.PANEL; } + + if (StringUtils.equals("data_fill", sourceType)) { + return SysLogConstants.SOURCE_TYPE.DATA_FILL_FORM; + } return null; } diff --git a/core/backend/src/main/java/io/dataease/provider/ext/MysqlExtDDLProvider.java b/core/backend/src/main/java/io/dataease/provider/ext/MysqlExtDDLProvider.java index 14d852a555..78100e0879 100644 --- a/core/backend/src/main/java/io/dataease/provider/ext/MysqlExtDDLProvider.java +++ b/core/backend/src/main/java/io/dataease/provider/ext/MysqlExtDDLProvider.java @@ -39,9 +39,9 @@ public class MysqlExtDDLProvider extends DefaultExtDDLProvider { @Override public String createTableSql(String table, List formFields) { //check inject - if (checkSqlInjection(table)) { + /*if (checkSqlInjection(table)) { throw new RuntimeException("包含SQL注入的参数,请检查参数!"); - } + }*/ List fields = convertTableFields(true, formFields); String fieldSql = convertTableFieldsString(table, fields); @@ -249,9 +249,9 @@ public class MysqlExtDDLProvider extends DefaultExtDDLProvider { } //check inject - if (checkSqlInjection(field.getColumnName())) { + /*if (checkSqlInjection(field.getColumnName())) { throw new RuntimeException("包含SQL注入的参数,请检查参数!"); - } + }*/ //column name str.append("`").append(field.getColumnName()).append("` "); @@ -345,9 +345,9 @@ public class MysqlExtDDLProvider extends DefaultExtDDLProvider { } //check inject - if (checkSqlInjection(table) || checkSqlInjection(indexField.getName())) { + /*if (checkSqlInjection(table) || checkSqlInjection(indexField.getName())) { throw new RuntimeException("包含SQL注入的参数,请检查参数!"); - } + }*/ int count = 0; for (ExtIndexField.ColumnSetting indexFieldColumn : indexField.getColumns()) { diff --git a/core/backend/src/main/java/io/dataease/service/datafill/DataFillDataService.java b/core/backend/src/main/java/io/dataease/service/datafill/DataFillDataService.java index 4146af01ff..6323fb8abb 100644 --- a/core/backend/src/main/java/io/dataease/service/datafill/DataFillDataService.java +++ b/core/backend/src/main/java/io/dataease/service/datafill/DataFillDataService.java @@ -41,6 +41,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.math.BigDecimal; +import java.math.RoundingMode; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; @@ -171,7 +172,15 @@ public class DataFillDataService { List countData = datasourceProvider.getData(datasourceRequest); long count = NumberUtils.toLong(countData.get(0)[0]); - String searchSql = extDDLProvider.searchSql(dataFillForm.getTableName(), searchFields, whereSql, searchRequest.getPageSize(), (searchRequest.getCurrentPage() - 1) * searchRequest.getPageSize()); + long totalPage = new BigDecimal(count).divide(new BigDecimal(searchRequest.getPageSize()), 0, RoundingMode.CEILING).longValue(); + + long currentPage = totalPage < searchRequest.getCurrentPage() ? totalPage - 1 : searchRequest.getCurrentPage(); + + if (currentPage < 1) { + currentPage = 1; + } + + String searchSql = extDDLProvider.searchSql(dataFillForm.getTableName(), searchFields, whereSql, searchRequest.getPageSize(), (currentPage - 1) * searchRequest.getPageSize()); datasourceRequest.setQuery(searchSql); List data2 = datasourceProvider.getData(datasourceRequest); @@ -241,7 +250,7 @@ public class DataFillDataService { .setFields(fields) .setTotal(count) .setPageSize(searchRequest.getPageSize()) - .setCurrentPage(searchRequest.getCurrentPage()); + .setCurrentPage(currentPage); } @@ -378,7 +387,7 @@ public class DataFillDataService { uniqueMap.putIfAbsent(name, new ArrayList<>()); if (uniqueMap.get(name).contains(data.get(name).toString())) { //提前判断录入的数据有没有unique字段重复的 - DataEaseException.throwException(extTableFields.get(name).getSettings().getName() + " 值不能重复"); + DataEaseException.throwException("[" + extTableFields.get(name).getSettings().getName() + "] 值: " + data.get(name) + " 不能重复"); } else { uniqueMap.get(name).add(data.get(name).toString()); } @@ -416,7 +425,7 @@ public class DataFillDataService { long count = NumberUtils.toLong(countData.get(0)[0]); if (count > 0) { - DataEaseException.throwException(extTableFields.get(uniqueField.getFiledName()).getSettings().getName() + " 值不能重复"); + DataEaseException.throwException("[" + extTableFields.get(uniqueField.getFiledName()).getSettings().getName() + "] 值: " + data.get(name) + " 在数据库中已存在, 不能重复"); } } @@ -684,14 +693,10 @@ public class DataFillDataService { if (i < excelDatum.size()) { excelRowData = excelDatum.get(i); } - if (StringUtils.isBlank(excelRowData)) { //处理必填,这里如果是字符串格式的,强制改成空字符串防止报错,其他类型都直接报错 + if (StringUtils.isBlank(excelRowData)) { //处理必填 + excelRowData = null; if (field.getSettings().isRequired()) { - if (field.getSettings().getMapping().getType().equals(ExtTableField.BaseType.nvarchar) || - field.getSettings().getMapping().getType().equals(ExtTableField.BaseType.text)) { - excelRowData = StringUtils.EMPTY; - } else { - DataEaseException.throwException(field.getSettings().getName() + "不能为空"); - } + DataEaseException.throwException("[" + field.getSettings().getName() + "] 不能为空"); } } if (excelRowData == null) { @@ -709,10 +714,26 @@ public class DataFillDataService { break; case datetime: Date date = getDate(field, excelRowData); - rowData.put(field.getSettings().getMapping().getColumnName(), date.getTime()); + Long time = date == null ? null : date.getTime(); + if (time != null && time < 0) { + throw new Exception("时间不能小于1970/01/01"); + } + rowData.put(field.getSettings().getMapping().getColumnName(), time); break; default: - if (StringUtils.equalsIgnoreCase(field.getType(), "checkbox") || + if (StringUtils.equalsIgnoreCase(field.getType(), "select") && !field.getSettings().isMultiple()) { + boolean has = false; + for (ExtTableField.Option option : field.getSettings().getOptions()) { + if (StringUtils.equals((String) option.getValue(), excelRowData)) { + has = true; + break; + } + } + if (!has) { + DataEaseException.throwException("[" + field.getSettings().getName() + "] 值: " + excelRowData + " 不在范围内"); + } + rowData.put(field.getSettings().getMapping().getColumnName(), excelRowData); + } else if (StringUtils.equalsIgnoreCase(field.getType(), "checkbox") || StringUtils.equalsIgnoreCase(field.getType(), "select") && field.getSettings().isMultiple()) { List list = new ArrayList<>(); String[] strArr = excelRowData.split(";"); @@ -723,11 +744,43 @@ public class DataFillDataService { } if (field.getSettings().isRequired()) { if (CollectionUtils.isEmpty(list)) { - DataEaseException.throwException(field.getSettings().getName() + "不能为空"); + DataEaseException.throwException("[" + field.getSettings().getName() + "] 不能为空"); } } - rowData.put(field.getSettings().getMapping().getColumnName(), gson.toJson(list)); + + List result = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(list)) { + for (String str : list) { + boolean has = false; + for (ExtTableField.Option option : field.getSettings().getOptions()) { + if (StringUtils.equals((String) option.getValue(), str)) { + has = true; + break; + } + } + if (has) { + result.add(str); + } + } + if (CollectionUtils.isEmpty(result)) { + DataEaseException.throwException("[" + field.getSettings().getName() + "] 输入值不在范围内"); + } + } + + rowData.put(field.getSettings().getMapping().getColumnName(), gson.toJson(result)); } else { + //校验手机号,校验邮箱格式 + if (StringUtils.equalsAnyIgnoreCase(field.getSettings().getInputType(), "tel")) { + if (!excelRowData.matches("^1[3|4|5|7|8][0-9]{9}$")) { + throw new Exception(Translator.get("i18n_wrong_tel")); + } + } + if (StringUtils.equalsAnyIgnoreCase(field.getSettings().getInputType(), "email")) { + if (!excelRowData.matches("^[a-zA-Z0-9_._-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")) { + throw new Exception(Translator.get("i18n_wrong_email")); + } + } + rowData.put(field.getSettings().getMapping().getColumnName(), excelRowData); } } @@ -735,7 +788,7 @@ public class DataFillDataService { } catch (DataEaseException e) { DataEaseException.throwException(e.getMessage()); } catch (Exception e) { - DataEaseException.throwException(field.getSettings().getName() + "格式错误"); + DataEaseException.throwException("[" + field.getSettings().getName() + "] 值: " + excelRowData + " 格式解析错误: " + e.getMessage()); } } @@ -755,6 +808,9 @@ public class DataFillDataService { } private static Date getDate(ExtTableField field, String excelRowData) throws ParseException { + if (StringUtils.isBlank(excelRowData)) { + return null; + } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //默认会拿到这种格式的 if (field.getSettings().isEnableTime()) { sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); diff --git a/core/backend/src/main/java/io/dataease/service/datafill/DataFillService.java b/core/backend/src/main/java/io/dataease/service/datafill/DataFillService.java index 00fc50be02..8bafbfde0e 100644 --- a/core/backend/src/main/java/io/dataease/service/datafill/DataFillService.java +++ b/core/backend/src/main/java/io/dataease/service/datafill/DataFillService.java @@ -387,7 +387,7 @@ public class DataFillService { break; case text: case nvarchar: - if (StringUtils.equalsIgnoreCase("select", formField.getType()) || StringUtils.equalsIgnoreCase("checkbox", formField.getType())) { + if (StringUtils.equalsIgnoreCase("select", formField.getType()) && formField.getSettings().isMultiple() || StringUtils.equalsIgnoreCase("checkbox", formField.getType())) { example = "\n(多个值使用分号\";\"分割)"; } else if (StringUtils.equalsIgnoreCase("email", formField.getSettings().getInputType())) { example = "\n(邮箱格式)"; diff --git a/core/backend/src/main/java/io/dataease/service/exportCenter/ExportCenterService.java b/core/backend/src/main/java/io/dataease/service/exportCenter/ExportCenterService.java index 0b875c60f0..0a9ea0832e 100644 --- a/core/backend/src/main/java/io/dataease/service/exportCenter/ExportCenterService.java +++ b/core/backend/src/main/java/io/dataease/service/exportCenter/ExportCenterService.java @@ -290,7 +290,7 @@ public class ExportCenterService { // with DataType if ((excelTypes[j].equals(DeTypeConstants.DE_INT) || excelTypes[j].equals(DeTypeConstants.DE_FLOAT)) && rowData[j] != null) { cell.setCellValue(Double.valueOf(rowData[j].toString())); - } else { + } else if(rowData[j] != null){ cell.setCellValue(String.valueOf(rowData[j])); } } catch (Exception e) { @@ -496,7 +496,7 @@ public class ExportCenterService { // with DataType if ((excelTypes[j].equals(DeTypeConstants.DE_INT) || excelTypes[j].equals(DeTypeConstants.DE_FLOAT)) && StringUtils.isNotEmpty(cellValObj.toString())) { cell.setCellValue(Double.valueOf(cellValObj.toString())); - } else { + } else if(cellValObj != null){ cell.setCellValue(cellValObj.toString()); } } catch (Exception e) { diff --git a/core/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java b/core/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java index 644dec2bef..cfde7c56cb 100644 --- a/core/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java +++ b/core/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java @@ -664,15 +664,17 @@ public class PanelGroupService { CacheUtils.removeAll(AuthConstants.DEPT_PANEL_NAME); } - public DataSetExportRequest composeDatasetExportRequest(PanelViewDetailsRequest request){ + public DataSetExportRequest composeDatasetExportRequest(PanelViewDetailsRequest request) { ChartExtRequest extRequest = request.getComponentFilterInfo(); List filter = new ArrayList(); - if(extRequest != null){ - if(CollectionUtils.isNotEmpty(extRequest.getFilter())){ + if (extRequest != null) { + if (CollectionUtils.isNotEmpty(extRequest.getFilter())) { filter.addAll(extRequest.getFilter()); - }if(CollectionUtils.isNotEmpty(extRequest.getLinkageFilters())){ + } + if (CollectionUtils.isNotEmpty(extRequest.getLinkageFilters())) { filter.addAll(extRequest.getLinkageFilters()); - }if(CollectionUtils.isNotEmpty(extRequest.getOuterParamsFilters())){ + } + if (CollectionUtils.isNotEmpty(extRequest.getOuterParamsFilters())) { filter.addAll(extRequest.getOuterParamsFilters()); } } @@ -681,23 +683,23 @@ public class PanelGroupService { permissionsTreeObjFilter.setLogic("and"); List composePermission = new ArrayList<>(); permissionsTreeObjFilter.setItems(composePermission); - if(CollectionUtils.isNotEmpty(filter)){ - filter.forEach(filterInfo ->{ + if (CollectionUtils.isNotEmpty(filter)) { + filter.forEach(filterInfo -> { DatasetRowPermissionsTreeItem filterPermission = new DatasetRowPermissionsTreeItem(); List values = filterInfo.getValue(); String operator = filterInfo.getOperator(); String dataSetFilterType = "logic"; String term = operator; - if("eq".equals(operator) && values.size()>1){ + if ("eq".equals(operator) && values.size() > 1) { dataSetFilterType = "enum"; } String fieldId = filterInfo.getFieldId(); filterPermission.setFieldId(fieldId); filterPermission.setFilterType(dataSetFilterType); filterPermission.setType("item"); - if(dataSetFilterType.equals("enum")){ + if (dataSetFilterType.equals("enum")) { filterPermission.setEnumValue(values); - }else{ + } else { filterPermission.setTerm(term); filterPermission.setValue(values.get(0)); } @@ -708,17 +710,19 @@ public class PanelGroupService { ChartViewWithBLOBs chartInfo = chartViewMapper.selectByPrimaryKey(request.getViewId()); String customFilter = chartInfo.getCustomFilter(); - DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(chartInfo.getTableId()); + DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(chartInfo.getTableId()); DataSetExportRequest dataSetExportRequest = new DataSetExportRequest(); - BeanUtils.copyBean(dataSetExportRequest,datasetTable); - if(CollectionUtils.isNotEmpty(composePermission)){ - DatasetRowPermissionsTreeObj permissionsTreeObjCustomsFilter = gson.fromJson(customFilter,DatasetRowPermissionsTreeObj.class); - DatasetRowPermissionsTreeItem customFilterPermission = new DatasetRowPermissionsTreeItem(); - customFilterPermission.setType("tree"); - customFilterPermission.setSubTree(permissionsTreeObjCustomsFilter); - composePermission.add(customFilterPermission); + BeanUtils.copyBean(dataSetExportRequest, datasetTable); + DatasetRowPermissionsTreeObj permissionsTreeObjCustomsFilter = gson.fromJson(customFilter, DatasetRowPermissionsTreeObj.class); + if (CollectionUtils.isNotEmpty(composePermission)) { + if (StringUtils.isNotEmpty(permissionsTreeObjCustomsFilter.getLogic())) { + DatasetRowPermissionsTreeItem customFilterPermission = new DatasetRowPermissionsTreeItem(); + customFilterPermission.setType("tree"); + customFilterPermission.setSubTree(permissionsTreeObjCustomsFilter); + composePermission.add(customFilterPermission); + } dataSetExportRequest.setExpressionTree(gson.toJson(permissionsTreeObjFilter)); - }else{ + } else if(StringUtils.isNotEmpty(permissionsTreeObjCustomsFilter.getLogic())){ dataSetExportRequest.setExpressionTree(customFilter); } dataSetExportRequest.setFilename(dataSetExportRequest.getName()); @@ -727,7 +731,7 @@ public class PanelGroupService { } public void exportDatasetDetails(PanelViewDetailsRequest request, HttpServletResponse response) throws Exception { - dataSetTableService.exportDataset(composeDatasetExportRequest(request),response); + dataSetTableService.exportDataset(composeDatasetExportRequest(request), response); } diff --git a/core/backend/src/main/java/io/dataease/service/sys/log/LogManager.java b/core/backend/src/main/java/io/dataease/service/sys/log/LogManager.java index 975a48bf73..0d6deb370c 100644 --- a/core/backend/src/main/java/io/dataease/service/sys/log/LogManager.java +++ b/core/backend/src/main/java/io/dataease/service/sys/log/LogManager.java @@ -104,6 +104,9 @@ public class LogManager { case 11: typeValue = "menu"; break; + case 13: + typeValue = "data_fill"; + break; default: break; } diff --git a/core/backend/src/main/resources/application.properties b/core/backend/src/main/resources/application.properties index 866b9e1adb..59caa2a006 100644 --- a/core/backend/src/main/resources/application.properties +++ b/core/backend/src/main/resources/application.properties @@ -1,6 +1,9 @@ spring.profiles.active=@profiles.active@ spring.application.name=dataease server.port=8081 + +# spring.jackson.serialization.fail-on-empty-beans=true +# spring.jackson.deserialization.fail-on-unknown-properties=true # Hikari spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=5 diff --git a/core/frontend/src/components/canvas/components/editor/Preview.vue b/core/frontend/src/components/canvas/components/editor/Preview.vue index 87501b528d..6e6306b0d7 100644 --- a/core/frontend/src/components/canvas/components/editor/Preview.vue +++ b/core/frontend/src/components/canvas/components/editor/Preview.vue @@ -127,7 +127,7 @@ > - 导出分辨率 + {{ $t('panel.export_pixel') }} { if (component.type === 'custom') { - component.style = deepCopy(this.findSourceComponent(component.id).style) + const sourceComponent = this.findSourceComponent(component.id) + if (sourceComponent?.style) { + component.style = deepCopy(this.findSourceComponent(component.id).style) + } } Object.keys(component.style).forEach(key => { if (this.needToChangeHeight.includes(key)) { diff --git a/core/frontend/src/components/canvas/customComponent/UserView.vue b/core/frontend/src/components/canvas/customComponent/UserView.vue index 4afa2184a3..8d43c238a9 100644 --- a/core/frontend/src/components/canvas/customComponent/UserView.vue +++ b/core/frontend/src/components/canvas/customComponent/UserView.vue @@ -160,7 +160,7 @@ > - 导出分辨率 + {{ $t('panel.export_pixel') }} { - const snapshot = canvas.toDataURL('image/jpeg', 1) - _this.exportExcelDownload(snapshot, canvas.width, canvas.height, callBack) - }) - } else { - _this.exportExcelDownload(null, null, null, callBack) - } - } + this.exportExcelDownload(null, null, null, callBack) }, exportSourceDetails(callBack) { const loadingWrapper = { val: this.linkLoading } diff --git a/core/frontend/src/components/canvas/utils/utils.js b/core/frontend/src/components/canvas/utils/utils.js index dea764c617..dc87709fed 100644 --- a/core/frontend/src/components/canvas/utils/utils.js +++ b/core/frontend/src/components/canvas/utils/utils.js @@ -469,10 +469,11 @@ export function getCacheTree(treeName) { } export function exportExcelDownload(chart, snapshot, width, height, loadingWrapper, downloadParams, callBack) { - if (chart.render === 'antv' && !chart.data?.data?.length) { + if ((chart.render === 'echarts' || ['text', 'label'].includes(chart.type)) && !(chart.data?.series?.length && chart.data?.series[0].data?.length)) { + callBack() return - } - if (chart.type === 'echarts' && !(chart.data?.series?.length && chart.data?.series[0].data?.length)) { + } else if ((chart.render === 'antv' && !['text', 'label'].includes(chart.type)) && !chart.data?.data?.length) { + callBack() return } const fields = JSON.parse(JSON.stringify(chart.data.fields)) @@ -504,6 +505,19 @@ export function exportExcelDownload(chart, snapshot, width, height, loadingWrapp }) }) } + if (chart.render === 'echarts' && chart.type === 'table-normal') { + const initTotal = fields.map(i => [2, 3].includes(i.deType) ? 0 : undefined) + initTotal[0] = '合计' + tableRow.reduce((p, n) => { + p.forEach((v, i) => { + if (!isNaN(v)) { + p[i] = v + n[excelHeaderKeys[i]] + } + }) + return p + }, initTotal) + excelData.push(initTotal) + } const request = { proxy: null, viewId: chart.id, diff --git a/core/frontend/src/lang/en.js b/core/frontend/src/lang/en.js index 0ae572294a..50cf3bf5d3 100644 --- a/core/frontend/src/lang/en.js +++ b/core/frontend/src/lang/en.js @@ -173,6 +173,7 @@ export default { default_login: 'Normal' }, commons: { + pwd_will_expired: 'The password will expire in %s days. To avoid any disruption to your normal use, please update it promptly!', component: { input: 'Input', textarea: 'Textarea', @@ -2275,6 +2276,7 @@ export default { back_parent: 'Back to previous' }, panel: { + export_pixel: 'Export pixel', app_export_tips: 'In the current dashboard, [{0}] belongs to a template view and cannot be exported. Please set up the dataset first!', required_tips: 'Cannot be empty!', filter_no_select: 'Filter components do not need to be selected', @@ -2409,7 +2411,7 @@ export default { link_share: 'Share Link', over_time: 'Over time', link_expire: 'Link is expire', - link_share_desc: 'After opening the link, anyone can access the dashboard through this link.', + link_share_desc: 'Anyone can access the dashboard through this link.', share: 'Share', remove_share_confirm: 'Sure removel All share ?', share_in: 'Share With Me', @@ -3226,5 +3228,11 @@ export default { export_from: 'Export source', export_obj: 'Export object', export_time: 'Export time' + }, + link_ticket: { + require: 'Require', + back: 'Back to link', + refresh: 'Refresh', + time_tips: 'Unit: Minutes, Range: [0-1440], 0 represents no expiration, starting from the first use of the ticket' } } diff --git a/core/frontend/src/lang/index.js b/core/frontend/src/lang/index.js index d7c16dfb3b..b0ae68b02d 100644 --- a/core/frontend/src/lang/index.js +++ b/core/frontend/src/lang/index.js @@ -39,7 +39,10 @@ export function getLanguage() { if (chooseLanguage) return chooseLanguage // if has not choose language - const language = (navigator.language || navigator.browserLanguage).toLowerCase() + let language = (navigator.language || navigator.browserLanguage).toLowerCase() + if (language && language === 'en') { + language = 'en_US' + } const locales = Object.keys(messages) for (const locale of locales) { if (language.indexOf(locale) > -1) { diff --git a/core/frontend/src/lang/tw.js b/core/frontend/src/lang/tw.js index 0af5efb46a..4b27333c9e 100644 --- a/core/frontend/src/lang/tw.js +++ b/core/frontend/src/lang/tw.js @@ -173,6 +173,7 @@ export default { default_login: '普通登錄' }, commons: { + pwd_will_expired: '密碼將於%s天後過期,為了不影響正常使用,請及時進行修改!', component: { input: '單行輸入', textarea: '多行輸入', @@ -662,8 +663,8 @@ export default { add_index: '新增索引', index_name: '索引名稱', index_column: '索引字段', - order_asc: '順序', - order_desc: '倒序', + order_asc: '升序', + order_desc: '降序', order_none: '默認排序', add_column: '新增字段', please_insert_start: '請輸入開始時間', @@ -2268,6 +2269,7 @@ export default { back_parent: '返回上一級' }, panel: { + export_pixel: '導出分辨率', app_export_tips: '當前儀表板中[{0}]屬於模板視圖,無法導出,請先設置數據集!', required_tips: '必填項不能爲空!', filter_no_select: '過濾組件無需選擇', @@ -3218,5 +3220,11 @@ export default { export_from: '匯出來源', export_obj: '匯出對象', export_time: '匯出時間' + }, + link_ticket: { + require: '必選', + back: '返回公共鏈接設置頁面', + refresh: '刷新', + time_tips: '單位: 分鐘,範圍: [0-1440],0代表無期限,自首次使用ticket訪問開始' } } diff --git a/core/frontend/src/lang/zh.js b/core/frontend/src/lang/zh.js index 9aa36dcde2..6c586ab605 100644 --- a/core/frontend/src/lang/zh.js +++ b/core/frontend/src/lang/zh.js @@ -173,6 +173,7 @@ export default { default_login: '普通登录' }, commons: { + pwd_will_expired: '密码将于%s天后过期,为了不影响正常使用,请及时进行修改!', component: { input: '单行输入', textarea: '多行输入', @@ -660,8 +661,8 @@ export default { add_index: '新增索引', index_name: '索引名称', index_column: '索引字段', - order_asc: '顺序', - order_desc: '倒序', + order_asc: '升序', + order_desc: '降序', order_none: '默认排序', add_column: '新增字段', please_insert_start: '请输入开始时间', @@ -2269,6 +2270,7 @@ export default { back_parent: '返回上一级' }, panel: { + export_pixel: '导出分辨率', app_export_tips: '当前仪表板中[{0}]属于模版视图,无法导出,请先设置数据集!', required_tips: '必填项不能为空!', filter_no_select: '过滤组件无需选择', @@ -3224,5 +3226,11 @@ export default { no_failed_file: '暂无失败文件', no_file: '暂无文件', no_task: '暂无任务' + }, + link_ticket: { + require: '必选', + back: '返回公共链接设置页面', + refresh: '刷新', + time_tips: '单位: 分钟,范围: [0-1440],0代表无期限,自首次使用ticket访问开始' } } diff --git a/core/frontend/src/layout/components/AiComponent.vue b/core/frontend/src/layout/components/AiComponent.vue index 5f342b59a5..9736251a05 100644 --- a/core/frontend/src/layout/components/AiComponent.vue +++ b/core/frontend/src/layout/components/AiComponent.vue @@ -89,7 +89,8 @@ export default { } } .ai-main-active { - border: 1px solid #d9d9d9; + border: 1px solid rgba(239, 240, 241, 1); + box-shadow: 0px 6px 24px 0px #1f232914; } .ai-main-active-min { min-width: 350px; diff --git a/core/frontend/src/layout/components/AiTips.vue b/core/frontend/src/layout/components/AiTips.vue new file mode 100644 index 0000000000..acd74e3c2d --- /dev/null +++ b/core/frontend/src/layout/components/AiTips.vue @@ -0,0 +1,95 @@ + + + + diff --git a/core/frontend/src/layout/components/PwdExpTips.vue b/core/frontend/src/layout/components/PwdExpTips.vue index 9c70cc3fa6..ed7ae5c891 100644 --- a/core/frontend/src/layout/components/PwdExpTips.vue +++ b/core/frontend/src/layout/components/PwdExpTips.vue @@ -29,11 +29,21 @@ export default { }, computed: { pwdPeriodWarn() { + if (localStorage.getItem('pwd-period-warn')) { + return true + } return this.$store.state.user.validityPeriod > 0 && this.$store.state.user.validityPeriod < 8 }, warnMsg() { + if (localStorage.getItem('pwd-period-warn')) { + const timeText = localStorage.getItem('pwd-period-warn') + const temp = this.$t('commons.pwd_will_expired') + return temp.replace('%s', timeText) + } if (this.$store.state.user.validityPeriod > 0 && this.$store.state.user.validityPeriod < 8) { - return `密码将于${this.$store.state.user.validityPeriod}后过期,为了不影响正常使用,请及时进行修改!` + localStorage.setItem('pwd-period-warn', this.$store.state.user.validityPeriod) + const temp = this.$t('commons.pwd_will_expired') + return temp.replace('%s', this.$store.state.user.validityPeriod) } return null } diff --git a/core/frontend/src/layout/components/Topbar.vue b/core/frontend/src/layout/components/Topbar.vue index 60349c50a3..4134bb3824 100644 --- a/core/frontend/src/layout/components/Topbar.vue +++ b/core/frontend/src/layout/components/Topbar.vue @@ -125,6 +125,8 @@ + +
{ const params = rsp.data if (params && params['ai.baseUrl']) { @@ -529,4 +539,19 @@ export default { display: none; } +.ai-icon-tips { + font-size: 24px !important; + z-index: 10001; +} + +.overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); /* 半透明黑色 */ + z-index: 10000; +} + diff --git a/core/frontend/src/store/modules/user.js b/core/frontend/src/store/modules/user.js index 186699845a..5b82a7823b 100644 --- a/core/frontend/src/store/modules/user.js +++ b/core/frontend/src/store/modules/user.js @@ -98,6 +98,7 @@ const actions = { commit('SET_PASSWORD_MODIFIED', passwordModified) localStorage.setItem('passwordModified', passwordModified) commit('SET_VALIDITY_PERIOD', data.validityPeriod) + localStorage.removeItem('pwd-period-warn') resolve() }).catch(error => { error?.response?.data?.message?.startsWith('pwdValidityPeriod') && commit('SET_LOGIN_MSG', '密码已过期,请联系管理员进行密码重置!') @@ -174,6 +175,7 @@ const actions = { commit('RESET_STATE') resolve(customLogoutUrl || res.data) localStorage.removeItem('passwordModified') + localStorage.removeItem('pwd-period-warn') }).catch(error => { reject(error) if (error?.response?.data?.message) { diff --git a/core/frontend/src/styles/topbar.scss b/core/frontend/src/styles/topbar.scss index 964fd870ac..788f3eb55b 100644 --- a/core/frontend/src/styles/topbar.scss +++ b/core/frontend/src/styles/topbar.scss @@ -4,9 +4,8 @@ top: 0; left: 0; z-index: 1001; - overflow: hidden; border-bottom: 1px solid var(--TopBG, #E6E6E6); - background-color: var(--TopBG, #f1f3f8); + background-color: var(--TopBG, #f1f3f8); .log { padding: 0 16px; line-height: 56px; @@ -71,7 +70,7 @@ padding: 10px 8px; height: 100%; font-size: 18px; - + vertical-align: text-bottom; &.hover-effect { diff --git a/core/frontend/src/views/dataFilling/form/EditFormData.vue b/core/frontend/src/views/dataFilling/form/EditFormData.vue index 85f5f9bc46..ef07bfb1a3 100644 --- a/core/frontend/src/views/dataFilling/form/EditFormData.vue +++ b/core/frontend/src/views/dataFilling/form/EditFormData.vue @@ -77,7 +77,12 @@ export default { name: this.$t('data_fill.form.email'), rules: [{ pattern: EMAIL_REGEX, message: this.$t('user.email_format_is_incorrect'), trigger: ['blur', 'change'] }] } - ] + ], + pickerOptions: { + disabledDate: (time) => { + return time.getTime() < new Date(0).getTime() + } + } } }, watch: {}, @@ -259,7 +264,7 @@ export default { :readonly="readonly" :placeholder="item.settings.placeholder" size="small" - :show-word-limit="item.value !== undefined && item.value.length > 250" + :show-word-limit="item.value !== undefined && item.value !== null && item.value.length > 250" maxlength="255" /> diff --git a/core/frontend/src/views/dataFilling/form/ViewTable.vue b/core/frontend/src/views/dataFilling/form/ViewTable.vue index eee6d8ebea..fc793e5b6a 100644 --- a/core/frontend/src/views/dataFilling/form/ViewTable.vue +++ b/core/frontend/src/views/dataFilling/form/ViewTable.vue @@ -1,5 +1,8 @@