diff --git a/Dockerfile b/Dockerfile index a6ca401801..a7dd1fd772 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,15 @@ FROM registry.cn-qingdao.aliyuncs.com/dataease/fabric8-java-alpine-openjdk8-jre:edge -RUN echo -e 'https://dl-cdn.alpinelinux.org/alpine/edge/main/\nhttps://dl-cdn.alpinelinux.org/alpine/edge/community/' > /etc/apk/repositories +# RUN echo -e 'https://dl-cdn.alpinelinux.org/alpine/edge/main/\nhttps://dl-cdn.alpinelinux.org/alpine/edge/community/' > /etc/apk/repositories -RUN apk add chromium chromium-chromedriver fontconfig --no-cache --allow-untrusted +# RUN apk add chromium chromium-chromedriver fontconfig --no-cache --allow-untrusted -ADD simsun.ttc /usr/share/fonts/ +# ADD simsun.ttc /usr/share/fonts/ -RUN cd /usr/share/fonts/ \ - && mkfontscale \ - && mkfontdir \ - && fc-cache -fv +# RUN cd /usr/share/fonts/ \ +# && mkfontscale \ +# && mkfontdir \ +# && fc-cache -fv ARG IMAGE_TAG diff --git a/backend/pom.xml b/backend/pom.xml index b03cea2f01..1049621672 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -31,7 +31,7 @@ com.google.guava guava - 30.1.1-jre + 31.0.1-jre org.springframework.boot @@ -143,7 +143,7 @@ com.alibaba fastjson - 1.2.72 + 1.2.79 com.auth0 diff --git a/backend/src/main/java/io/dataease/commons/utils/ExcelXlsxReader.java b/backend/src/main/java/io/dataease/commons/utils/ExcelXlsxReader.java index fc96df9a6b..d381e754c7 100644 --- a/backend/src/main/java/io/dataease/commons/utils/ExcelXlsxReader.java +++ b/backend/src/main/java/io/dataease/commons/utils/ExcelXlsxReader.java @@ -142,6 +142,9 @@ public class ExcelXlsxReader extends DefaultHandler { stylesTable = xssfReader.getStylesTable(); SharedStringsTable sst = xssfReader.getSharedStringsTable(); XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); + parser.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + parser.setFeature("http://xml.org/sax/features/external-general-entities", false); + parser.setFeature("http://xml.org/sax/features/external-parameter-entities", false); this.sst = sst; parser.setContentHandler(this); XSSFReader.SheetIterator sheets = (XSSFReader.SheetIterator) xssfReader.getSheetsData(); diff --git a/backend/src/main/java/io/dataease/commons/utils/ServiceUtils.java b/backend/src/main/java/io/dataease/commons/utils/ServiceUtils.java deleted file mode 100644 index b564ad7a1f..0000000000 --- a/backend/src/main/java/io/dataease/commons/utils/ServiceUtils.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.dataease.commons.utils; - -import io.dataease.commons.exception.DEException; -import io.dataease.controller.request.BaseQueryRequest; -import io.dataease.controller.request.OrderRequest; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class ServiceUtils { - - public static List getDefaultOrder(List orders) { - if (orders == null || orders.size() < 1) { - OrderRequest orderRequest = new OrderRequest(); - orderRequest.setName("update_time"); - orderRequest.setType("desc"); - orders = new ArrayList<>(); - orders.add(orderRequest); - return orders; - } - return orders; - } - - /** - * 获取前端全选的id列表 - * @param queryRequest 查询条件 - * @param func 查询id列表的数据库查询 - * @return - */ - public static void getSelectAllIds( T batchRequest, BaseQueryRequest queryRequest, Function> func) { - if (queryRequest.isSelectAll()) { - List ids = func.apply(queryRequest); - if (!ids.isEmpty()) { - ids = ids.stream() - .filter(id -> !queryRequest.getUnSelectIds().contains(id)) - .collect(Collectors.toList()); - } - queryRequest.setIds(ids); - try { - Method setIds = batchRequest.getClass().getDeclaredMethod("setIds", List.class); - setIds.invoke(batchRequest, ids); - } catch (Exception e) { - LogUtil.error(e.getMessage(), e); - DEException.throwException("请求没有setIds方法"); - } - } - } -} diff --git a/backend/src/main/java/io/dataease/controller/sys/I18nController.java b/backend/src/main/java/io/dataease/controller/sys/I18nController.java deleted file mode 100644 index d9f826e0ba..0000000000 --- a/backend/src/main/java/io/dataease/controller/sys/I18nController.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.dataease.controller.sys; - - -import io.dataease.commons.constants.I18nConstants; -import io.dataease.commons.exception.DEException; -import io.dataease.commons.utils.LogUtil; -import io.dataease.i18n.Lang; -import io.dataease.i18n.Translator; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; -import springfox.documentation.annotations.ApiIgnore; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Created by liqiang on 2019/4/1. - */ -@ApiIgnore -@RestController -public class I18nController { - - private static final int FOR_EVER = 3600 * 24 * 30 * 12 * 10; //10 years in second - - @Value("${run.mode:release}") - private String runMode; - - - @GetMapping("lang/change/{lang}") - public void changeLang(@PathVariable String lang, HttpServletRequest request, HttpServletResponse response) { - Lang targetLang = Lang.getLangWithoutDefault(lang); - if (targetLang == null) { - response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE); - LogUtil.error("Invalid parameter: " + lang); - DEException.throwException(Translator.get("error_lang_invalid")); - } - Cookie cookie = new Cookie(I18nConstants.LANG_COOKIE_NAME, targetLang.getDesc()); - cookie.setPath("/"); - cookie.setMaxAge(FOR_EVER); - response.addCookie(cookie); - //重新登录 - if ("release".equals(runMode)) { - Cookie f2cCookie = new Cookie("DE_SESSION_ID", "deleteMe"); - f2cCookie.setPath("/"); - f2cCookie.setMaxAge(0); - response.addCookie(f2cCookie); - } - //本地测试用 - if ("local".equals(runMode)) { - if (request != null) { - request.getSession(true).setAttribute(I18nConstants.LANG_COOKIE_NAME, lang); - } - } - } -} diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java index 63c1a4dbdf..6544ba376a 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -2000,30 +2000,7 @@ public class DataSetTableService { data.add(r); } } - } else if (StringUtils.equalsIgnoreCase(suffix, "csv")) { - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); - String s = reader.readLine();// first line - String[] split = s.split(","); - for (String s1 : split) { - TableField tableField = new TableField(); - tableField.setFieldName(s1); - tableField.setRemarks(s1); - tableField.setFieldType("TEXT"); - fields.add(tableField); - } - int num = 1; - String line; - while ((line = reader.readLine()) != null) { - if (isPreview) { - if (num > 100) { - break; - } - } - data.add(line.split(",")); - num++; - } } - String[] fieldArray = fields.stream().map(TableField::getFieldName).toArray(String[]::new); // 校验excel字段是否重名 diff --git a/backend/src/main/resources/db/migration/V32__1.8.sql b/backend/src/main/resources/db/migration/V32__1.8.sql index 7657d638ed..0eacd3c270 100644 --- a/backend/src/main/resources/db/migration/V32__1.8.sql +++ b/backend/src/main/resources/db/migration/V32__1.8.sql @@ -313,3 +313,7 @@ ADD COLUMN `uuid` varchar(8) NULL COMMENT 'uuid' AFTER `user_id`; ALTER TABLE `chart_view` ADD COLUMN `is_plugin` bit(1) NULL COMMENT '是否插件' AFTER `chart_type`; + + +INSERT INTO `my_plugin` VALUES (2, '视图默认插件', 'default', 0, 20000, 'view', '默认视图插件', '1.0-SNAPSHOT', NULL, 'fit2cloud-chenyw', 0, NULL, NULL, 'deplugin-view-backend', NULL); + diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index 69f5a4ee7c..afb2d2f3bd 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -167,9 +167,7 @@ export default { sourceCustomStyleStr: null } }, - mounted() { - this.bindPluginEvent() - }, + computed: { // 视图 componentBackGround() { @@ -379,6 +377,9 @@ export default { deep: true } }, + mounted() { + this.bindPluginEvent() + }, created() { this.refId = uuid.v1 @@ -390,10 +391,17 @@ export default { }, methods: { bindPluginEvent() { - bus.$on('plugin-chart-click', this.chartClick) - bus.$on('plugin-jump-click', this.jumpClick) - bus.$on('plugin-add-view-track-filter', this.addViewTrackFilter) + bus.$on('plugin-chart-click', param => { + param.viewId && param.viewId === this.element.propValue.viewId && this.chartClick(param) + }) + bus.$on('plugin-jump-click', param => { + param.viewId && param.viewId === this.element.propValue.viewId && this.jumpClick(param) + }) + bus.$on('plugin-add-view-track-filter', param => { + param.viewId && param.viewId === this.element.propValue.viewId && this.addViewTrackFilter(param) + }) }, + addViewTrackFilter(linkageParam) { this.$store.commit('addViewTrackFilter', linkageParam) }, diff --git a/frontend/src/components/widget/DeWidget/DeTabs.vue b/frontend/src/components/widget/DeWidget/DeTabs.vue index c2230c3ed9..99a164d901 100644 --- a/frontend/src/components/widget/DeWidget/DeTabs.vue +++ b/frontend/src/components/widget/DeWidget/DeTabs.vue @@ -2,7 +2,7 @@
- + {{ $t('table.delete') }} @@ -35,7 +35,7 @@
- +
@@ -130,14 +130,15 @@ export default { dialogVisible: false, textarea: '', curItem: null, - viewDialogVisible: false, - tabList: [] + viewDialogVisible: false + } }, computed: { dropdownShow() { return this.isEdit && !this.mobileLayoutStatus }, + ...mapState([ 'curComponent', 'mobileLayoutStatus' @@ -152,8 +153,7 @@ export default { }, created() { bus.$on('add-new-tab', this.addNewTab) - this.tabList = this.element.options && this.element.options.tabList - this.activeTabName = this.tabList[0].name + this.activeTabName = this.element.options.tabList[0].name }, methods: { beforeHandleCommond(item, param) { @@ -192,7 +192,8 @@ export default { const newComponentId = uuid.v1() const componentInfo = { type: 'view', - id: node.id + /* id: node.id */ + id: node.innerId } componentList.forEach(componentTemp => { @@ -239,7 +240,7 @@ export default { while (len--) { if (this.element.options.tabList[len].name === param.name) { this.element.options.tabList.splice(len, 1) - this.tabList = this.element.options.tabList + const activIndex = (len - 1 + this.element.options.tabList.length) % this.element.options.tabList.length this.activeTabName = this.element.options.tabList[activIndex].name } @@ -256,7 +257,7 @@ export default { content: null } this.element.options.tabList.push(tab) - this.tabList = this.element.options.tabList + this.styleChange() }, styleChange() { diff --git a/frontend/src/icons/svg/buddle-map.svg b/frontend/src/icons/svg/buddle-map.svg index a56a4cf8c7..3930ea05b1 100644 --- a/frontend/src/icons/svg/buddle-map.svg +++ b/frontend/src/icons/svg/buddle-map.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index c93e013da1..26b4eb7e5d 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -203,20 +203,35 @@ const data = { for (let index = 0; index < state.componentData.length; index++) { const element = state.componentData[index] + if (element.type && element.type === 'de-tabs') { + for (let idx = 0; idx < element.options.tabList.length; idx++) { + const ele = element.options.tabList[idx].content + if (!ele.type || ele.type !== 'view') continue + const currentFilters = ele.filters || [] + const vidMatch = viewIdMatch(condition.viewIds, ele.propValue.viewId) + + let jdx = currentFilters.length + while (jdx--) { + const filter = currentFilters[jdx] + if (filter.componentId === filterComponentId) { + currentFilters.splice(jdx, 1) + } + } + // 不存在该条件 且 条件有效 直接保存该条件 + // !filterExist && vValid && currentFilters.push(condition) + vidMatch && vValid && currentFilters.push(condition) + ele.filters = currentFilters + } + state.componentData[index] = element + } if (!element.type || element.type !== 'view') continue const currentFilters = element.filters || [] const vidMatch = viewIdMatch(condition.viewIds, element.propValue.viewId) let j = currentFilters.length - // let filterExist = false while (j--) { const filter = currentFilters[j] if (filter.componentId === filterComponentId) { - // filterExist = true - // 已存在该条件 且 条件值有效 直接替换原体检 - // vidMatch && vValid && (currentFilters[j] = condition) - // 已存在该条件 且 条件值无效 直接删除原条件 - // vidMatch && !vValid && (currentFilters.splice(j, 1)) currentFilters.splice(j, 1) } } diff --git a/frontend/src/views/chart/chart/table/table-info.js b/frontend/src/views/chart/chart/table/table-info.js index d5a6f96938..dd6b000952 100644 --- a/frontend/src/views/chart/chart/table/table-info.js +++ b/frontend/src/views/chart/chart/table/table-info.js @@ -116,7 +116,12 @@ export function baseTableNormal(s2, container, chart, action, tableData) { // add drill list if (chart.drill) { - const drillFields = JSON.parse(chart.drillFields) + let drillFields = [] + try { + drillFields = JSON.parse(chart.drillFields) + } catch (err) { + drillFields = JSON.parse(JSON.stringify(chart.drillFields)) + } const drillField = drillFields[chart.drillFilters.length] const drillFilters = JSON.parse(JSON.stringify(chart.drillFilters)) diff --git a/frontend/src/views/chart/components/drag-item/QuotaExtItem.vue b/frontend/src/views/chart/components/drag-item/QuotaExtItem.vue index 28c0ed9cdf..053c311d21 100644 --- a/frontend/src/views/chart/components/drag-item/QuotaExtItem.vue +++ b/frontend/src/views/chart/components/drag-item/QuotaExtItem.vue @@ -180,8 +180,8 @@ export default { const t1 = xAxis.filter(ele => { return ele.deType === 1 }) - // 暂时只支持类别轴/维度的时间类型字段,且视图中有且只有一个时间字段 - if (t1.length === 1 && this.chart.type !== 'text' && this.chart.type !== 'gauge' && this.chart.type !== 'liquid') { + // 暂时只支持类别轴/维度的时间类型字段 + if (t1.length > 0 && this.chart.type !== 'text' && this.chart.type !== 'gauge' && this.chart.type !== 'liquid') { this.disableEditCompare = false } else { this.disableEditCompare = true diff --git a/frontend/src/views/chart/components/drag-item/QuotaItem.vue b/frontend/src/views/chart/components/drag-item/QuotaItem.vue index 5fada430df..66d14db6da 100644 --- a/frontend/src/views/chart/components/drag-item/QuotaItem.vue +++ b/frontend/src/views/chart/components/drag-item/QuotaItem.vue @@ -177,8 +177,8 @@ export default { const t1 = xAxis.filter(ele => { return ele.deType === 1 }) - // 暂时只支持类别轴/维度的时间类型字段,且视图中有且只有一个时间字段 - if (t1.length === 1 && this.chart.type !== 'text' && this.chart.type !== 'gauge' && this.chart.type !== 'liquid') { + // 暂时只支持类别轴/维度的时间类型字段 + if (t1.length > 0 && this.chart.type !== 'text' && this.chart.type !== 'gauge' && this.chart.type !== 'liquid') { this.disableEditCompare = false } else { this.disableEditCompare = true diff --git a/frontend/src/views/panel/filter/filterDialog.vue b/frontend/src/views/panel/filter/filterDialog.vue index b88623d20e..c4a085ae88 100644 --- a/frontend/src/views/panel/filter/filterDialog.vue +++ b/frontend/src/views/panel/filter/filterDialog.vue @@ -387,11 +387,28 @@ export default { return roots }, loadViews() { - const viewIds = this.componentData + /* const viewIds = this.componentData .filter(item => item.type === 'view' && item.propValue && item.propValue.viewId) - .map(item => item.propValue.viewId) + .map(item => item.propValue.viewId) */ + let viewIds = []; let tabViewIds = [] + for (let index = 0; index < this.componentData.length; index++) { + const element = this.componentData[index] + if (element.type && element.propValue && element.propValue.viewId && element.type === 'view') { + viewIds.push(element.propValue.viewId) + } + + if (element.type && element.type === 'de-tabs') { + tabViewIds = element.options.tabList.filter(item => item.content && item.content.type === 'view' && item.content.propValue && item.content.propValue.viewId).map(item => item.content.propValue.viewId) + } + viewIds = [...viewIds, ...tabViewIds] + } viewIds && viewIds.length > 0 && viewsWithIds(viewIds).then(res => { const datas = res.data + /* datas.forEach(item => { + if (tabViewIds.includes(item.id)) { + item.name = 'tabs(' + item.name + ')' + } + }) */ this.viewInfos = datas this.childViews.viewInfos = datas })