提交 757f9a5c authored 作者: wangjiahao's avatar wangjiahao

Merge remote-tracking branch 'origin/dev' into dev

......@@ -27,7 +27,11 @@ public class DePermissionAnnotationHandler {
@Around(value = "@annotation(io.dataease.auth.annotation.DePermissions)")
public Object PermissionsAround(ProceedingJoinPoint point) {
try {
if (AuthUtils.getUser().getIsAdmin()) {
return point.proceed(point.getArgs());
}
MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod();
DePermissions annotation = method.getAnnotation(DePermissions.class);
......@@ -47,13 +51,13 @@ public class DePermissionAnnotationHandler {
Boolean someAccess = false;
for (int i = 0; i < dePermissions.length; i++) {
DePermission permission = dePermissions[i];
try{
try {
boolean currentAccess = access(args[permission.paramIndex()], permission, 0);
if (currentAccess) {
someAccess = true;
break;
}
}catch (Exception e) {
} catch (Exception e) {
exceptions.add(e);
}
}
......@@ -71,6 +75,9 @@ public class DePermissionAnnotationHandler {
@Around(value = "@annotation(io.dataease.auth.annotation.DePermission)")
public Object PermissionAround(ProceedingJoinPoint point) {
try {
if (AuthUtils.getUser().getIsAdmin()) {
return point.proceed(point.getArgs());
}
MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod();
......@@ -88,20 +95,22 @@ public class DePermissionAnnotationHandler {
}
private Boolean access(Object arg, DePermission annotation, int layer) throws Exception {
if (ObjectUtils.isEmpty(arg)) return true;
if (ObjectUtils.isEmpty(arg))
return true;
String type = annotation.type().name().toLowerCase();
String value = annotation.value();
Integer requireLevel = annotation.level().getLevel();
Set<String> resourceIds = AuthUtils.permissionByType(type).stream().filter(
item -> item.getLevel() >= requireLevel
).map(AuthItem::getAuthSource).collect(Collectors.toSet());
item -> item.getLevel() >= requireLevel).map(AuthItem::getAuthSource).collect(Collectors.toSet());
Class<?> parameterType = arg.getClass();
if (parameterType.isPrimitive() || isWrapClass(parameterType) || isString(parameterType)) {
boolean permissionValid = resourceIds.contains(arg);
if (permissionValid) return true;
throw new UnauthorizedException("Subject does not have permission[" + annotation.level().name() +":"+ annotation.type() + ":" + arg + "]");
if (permissionValid)
return true;
throw new UnauthorizedException("Subject does not have permission[" + annotation.level().name() + ":"
+ annotation.type() + ":" + arg + "]");
} else if (isArray(parameterType)) {
for (int i = 0; i < Array.getLength(arg); i++) {
Object o = Array.get(arg, i);
......@@ -124,7 +133,7 @@ public class DePermissionAnnotationHandler {
Object o = argMap.get(values[layer]);
return access(o, annotation, ++layer);
} else {
//当作自定义类处理
// 当作自定义类处理
String[] values = value.split("u002E");
String fieldName = values[layer];
......@@ -135,7 +144,7 @@ public class DePermissionAnnotationHandler {
return true;
}
private Object getFieldValue(Object o, String fieldName) throws Exception{
private Object getFieldValue(Object o, String fieldName) throws Exception {
Class<?> aClass = o.getClass();
while (null != aClass.getSuperclass()) {
Field[] declaredFields = aClass.getDeclaredFields();
......@@ -183,5 +192,4 @@ public class DePermissionAnnotationHandler {
return Arrays.stream(wrapClasies).anyMatch(item -> StringUtils.equals(item, clz.getName()));
}
}
......@@ -13,6 +13,8 @@ import lombok.ToString;
public class ChartViewWithBLOBs extends ChartView implements Serializable {
@ApiModelProperty("x轴")
private String xAxis;
@ApiModelProperty("x轴(Row)")
private String xAxisExt;
@ApiModelProperty("y轴")
private String yAxis;
@ApiModelProperty("副y轴")
......
......@@ -18,6 +18,7 @@
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.dataease.base.domain.ChartViewWithBLOBs">
<result column="x_axis" jdbcType="LONGVARCHAR" property="xAxis" />
<result column="x_axis_ext" jdbcType="LONGVARCHAR" property="xAxisExt" />
<result column="y_axis" jdbcType="LONGVARCHAR" property="yAxis" />
<result column="y_axis_ext" jdbcType="LONGVARCHAR" property="yAxisExt" />
<result column="ext_stack" jdbcType="LONGVARCHAR" property="extStack" />
......@@ -91,8 +92,8 @@
create_by, create_time, update_time, style_priority
</sql>
<sql id="Blob_Column_List">
x_axis, y_axis, y_axis_ext, ext_stack, ext_bubble, custom_attr, custom_style, custom_filter,
drill_fields, snapshot
x_axis, x_axis_ext, y_axis, y_axis_ext, ext_stack, ext_bubble, custom_attr, custom_style,
custom_filter, drill_fields, snapshot
</sql>
<select id="selectByExampleWithBLOBs" parameterType="io.dataease.base.domain.ChartViewExample" resultMap="ResultMapWithBLOBs">
select
......@@ -147,18 +148,20 @@
table_id, `type`, render,
result_count, result_mode, title,
create_by, create_time, update_time,
style_priority, x_axis, y_axis,
y_axis_ext, ext_stack, ext_bubble,
custom_attr, custom_style, custom_filter,
drill_fields, snapshot)
style_priority, x_axis, x_axis_ext,
y_axis, y_axis_ext, ext_stack,
ext_bubble, custom_attr, custom_style,
custom_filter, drill_fields, snapshot
)
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{sceneId,jdbcType=VARCHAR},
#{tableId,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR}, #{render,jdbcType=VARCHAR},
#{resultCount,jdbcType=INTEGER}, #{resultMode,jdbcType=VARCHAR}, #{title,jdbcType=VARCHAR},
#{createBy,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
#{stylePriority,jdbcType=VARCHAR}, #{xAxis,jdbcType=LONGVARCHAR}, #{yAxis,jdbcType=LONGVARCHAR},
#{yAxisExt,jdbcType=LONGVARCHAR}, #{extStack,jdbcType=LONGVARCHAR}, #{extBubble,jdbcType=LONGVARCHAR},
#{customAttr,jdbcType=LONGVARCHAR}, #{customStyle,jdbcType=LONGVARCHAR}, #{customFilter,jdbcType=LONGVARCHAR},
#{drillFields,jdbcType=LONGVARCHAR}, #{snapshot,jdbcType=LONGVARCHAR})
#{stylePriority,jdbcType=VARCHAR}, #{xAxis,jdbcType=LONGVARCHAR}, #{xAxisExt,jdbcType=LONGVARCHAR},
#{yAxis,jdbcType=LONGVARCHAR}, #{yAxisExt,jdbcType=LONGVARCHAR}, #{extStack,jdbcType=LONGVARCHAR},
#{extBubble,jdbcType=LONGVARCHAR}, #{customAttr,jdbcType=LONGVARCHAR}, #{customStyle,jdbcType=LONGVARCHAR},
#{customFilter,jdbcType=LONGVARCHAR}, #{drillFields,jdbcType=LONGVARCHAR}, #{snapshot,jdbcType=LONGVARCHAR}
)
</insert>
<insert id="insertSelective" parameterType="io.dataease.base.domain.ChartViewWithBLOBs">
insert into chart_view
......@@ -205,6 +208,9 @@
<if test="xAxis != null">
x_axis,
</if>
<if test="xAxisExt != null">
x_axis_ext,
</if>
<if test="yAxis != null">
y_axis,
</if>
......@@ -276,6 +282,9 @@
<if test="xAxis != null">
#{xAxis,jdbcType=LONGVARCHAR},
</if>
<if test="xAxisExt != null">
#{xAxisExt,jdbcType=LONGVARCHAR},
</if>
<if test="yAxis != null">
#{yAxis,jdbcType=LONGVARCHAR},
</if>
......@@ -356,6 +365,9 @@
<if test="record.xAxis != null">
x_axis = #{record.xAxis,jdbcType=LONGVARCHAR},
</if>
<if test="record.xAxisExt != null">
x_axis_ext = #{record.xAxisExt,jdbcType=LONGVARCHAR},
</if>
<if test="record.yAxis != null">
y_axis = #{record.yAxis,jdbcType=LONGVARCHAR},
</if>
......@@ -404,6 +416,7 @@
update_time = #{record.updateTime,jdbcType=BIGINT},
style_priority = #{record.stylePriority,jdbcType=VARCHAR},
x_axis = #{record.xAxis,jdbcType=LONGVARCHAR},
x_axis_ext = #{record.xAxisExt,jdbcType=LONGVARCHAR},
y_axis = #{record.yAxis,jdbcType=LONGVARCHAR},
y_axis_ext = #{record.yAxisExt,jdbcType=LONGVARCHAR},
ext_stack = #{record.extStack,jdbcType=LONGVARCHAR},
......@@ -478,6 +491,9 @@
<if test="xAxis != null">
x_axis = #{xAxis,jdbcType=LONGVARCHAR},
</if>
<if test="xAxisExt != null">
x_axis_ext = #{xAxisExt,jdbcType=LONGVARCHAR},
</if>
<if test="yAxis != null">
y_axis = #{yAxis,jdbcType=LONGVARCHAR},
</if>
......@@ -523,6 +539,7 @@
update_time = #{updateTime,jdbcType=BIGINT},
style_priority = #{stylePriority,jdbcType=VARCHAR},
x_axis = #{xAxis,jdbcType=LONGVARCHAR},
x_axis_ext = #{xAxisExt,jdbcType=LONGVARCHAR},
y_axis = #{yAxis,jdbcType=LONGVARCHAR},
y_axis_ext = #{yAxisExt,jdbcType=LONGVARCHAR},
ext_stack = #{extStack,jdbcType=LONGVARCHAR},
......
......@@ -6,6 +6,8 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ZipUtils {
......@@ -29,7 +31,7 @@ public class ZipUtils {
ZipEntry ze = zis.getNextEntry();
while (ze != null) {
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator + fileName);
File newFile = protectZipSlip(fileName, outputFolder);
//大部分网络上的源码,这里没有判断子目录
if (ze.isDirectory()) {
if (!newFile.mkdirs()) {
......@@ -60,7 +62,7 @@ public class ZipUtils {
while (entry != null) {
File file = new File(out, entry.getName());
File file = protectZipSlip(entry.getName(), out);
if (entry.isDirectory()) {
if (!file.mkdirs()) {
......@@ -130,4 +132,17 @@ public class ZipUtils {
}
}
public static File protectZipSlip(String fileName, String destDir) throws IOException{
Path destPath = Paths.get(destDir);
Path resolvedDest = destPath.resolve(fileName);
Path normalizedPath = resolvedDest.normalize();
// checking whether zipEntry filename has changed the destination
if (!normalizedPath.startsWith(destDir)) {
throw new IOException("Malicious zip entry found: " + fileName);
}
File newFile = normalizedPath.toFile();
return newFile;
}
}
......@@ -29,7 +29,7 @@ public class ColumnPermissionsController {
@ApiOperation("保存")
@PostMapping("save")
public void save(@RequestBody DatasetColumnPermissions datasetColumnPermissions) throws Exception {
public DatasetColumnPermissions save(@RequestBody DatasetColumnPermissions datasetColumnPermissions) throws Exception {
ColumnPermissionService columnPermissionService = SpringContextUtil.getBean(ColumnPermissionService.class);
DataSetColumnPermissionsDTO request = new DataSetColumnPermissionsDTO();
request.setAuthTargetType(datasetColumnPermissions.getAuthTargetType());
......@@ -48,7 +48,7 @@ public class ColumnPermissionsController {
throw new Exception(Translator.get("i18n_cp_exist"));
}
}
columnPermissionService.save(datasetColumnPermissions);
return columnPermissionService.save(datasetColumnPermissions);
}
@ApiOperation("查询")
......
......@@ -282,7 +282,7 @@ public class JdbcProvider extends DatasourceProvider {
String f = metaData.getColumnName(j + 1);
String l = StringUtils.isNotEmpty(metaData.getColumnLabel(j + 1)) ? metaData.getColumnLabel(j + 1) : f;
String t = metaData.getColumnTypeName(j + 1);
if (datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.hive.name())) {
if (datasourceRequest.getDatasource().getType().equalsIgnoreCase(DatasourceTypes.hive.name()) && l.contains("\\.")) {
l = l.split("\\.")[1];
}
TableFiled field = new TableFiled();
......
......@@ -942,24 +942,24 @@ public class EsQueryProvider extends QueryProvider {
}
if (StringUtils.isEmpty(dateStyle)) {
return "YYYY-MM-dd HH:mm:ss";
return "yyyy-MM-dd HH:mm:ss";
}
switch (dateStyle) {
case "y":
return "YYYY";
return "yyyy";
case "y_M":
return "YYYY" + split + "MM";
return "yyyy" + split + "MM";
case "y_M_d":
return "YYYY" + split + "MM" + split + "dd";
return "yyyy" + split + "MM" + split + "dd";
case "H_m_s":
return "HH:mm:ss";
case "y_M_d_H_m":
return "YYYY" + split + "MM" + split + "dd" + " HH:mm";
return "yyyy" + split + "MM" + split + "dd" + " HH:mm";
case "y_M_d_H_m_s":
return "YYYY" + split + "MM" + split + "dd" + " HH:mm:ss";
return "yyyy" + split + "MM" + split + "dd" + " HH:mm:ss";
default:
return "YYYY-MM-dd HH:mm:ss";
return "yyyy-MM-dd HH:mm:ss";
}
}
......
......@@ -21,7 +21,7 @@ public class EsSqlLConstants extends SQLConstants {
public static final String ROUND = "ROUND(%s, %s)";
public static final String DEFAULT_DATE_FORMAT = "YYYY-MM-dd HH:mm:ss";
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String WHERE_VALUE_NULL = "(NULL,'')";
......
......@@ -116,7 +116,7 @@ public class MongoQueryProvider extends QueryProvider {
st_sql.add("isGroup", isGroup);
if (CollectionUtils.isNotEmpty(xFields)) {
st_sql.add("groups", xFields);
// st_sql.add("notUseAs", true);
st_sql.add("notUseAs", true);
}
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
String customWheres = transCustomFilterList(tableObj, fieldCustomFilter);
......@@ -238,7 +238,7 @@ public class MongoQueryProvider extends QueryProvider {
ST st_sql = stg.getInstanceOf("querySql");
if (CollectionUtils.isNotEmpty(xFields)) {
st_sql.add("groups", xFields);
// st_sql.add("notUseAs", true);
st_sql.add("notUseAs", true);
}
if (CollectionUtils.isNotEmpty(yFields)) {
st_sql.add("aggregators", yFields);
......@@ -313,7 +313,7 @@ public class MongoQueryProvider extends QueryProvider {
st_sql.add("isGroup", false);
if (CollectionUtils.isNotEmpty(xFields)) {
st_sql.add("groups", xFields);
// st_sql.add("notUseAs", true);
st_sql.add("notUseAs", true);
}
if (CollectionUtils.isNotEmpty(wheres)) st_sql.add("filters", wheres);
if (ObjectUtils.isNotEmpty(tableObj)) st_sql.add("table", tableObj);
......@@ -431,7 +431,7 @@ public class MongoQueryProvider extends QueryProvider {
ST st_sql = stg.getInstanceOf("querySql");
if (CollectionUtils.isNotEmpty(xFields)) {
st_sql.add("groups", xFields);
// st_sql.add("notUseAs", true);
st_sql.add("notUseAs", true);
}
if (CollectionUtils.isNotEmpty(yFields)) {
st_sql.add("aggregators", yFields);
......@@ -547,7 +547,7 @@ public class MongoQueryProvider extends QueryProvider {
ST st_sql = stg.getInstanceOf("querySql");
if (CollectionUtils.isNotEmpty(xFields)) {
st_sql.add("groups", xFields);
// st_sql.add("notUseAs", true);
st_sql.add("notUseAs", true);
}
if (CollectionUtils.isNotEmpty(yFields)) {
st_sql.add("aggregators", yFields);
......
......@@ -219,6 +219,11 @@ public class ChartViewService {
}
List<ChartViewFieldDTO> xAxis = new Gson().fromJson(view.getXAxis(), new TypeToken<List<ChartViewFieldDTO>>() {
}.getType());
if (StringUtils.equalsIgnoreCase(view.getType(), "table-pivot")) {
List<ChartViewFieldDTO> xAxisExt = new Gson().fromJson(view.getXAxisExt(), new TypeToken<List<ChartViewFieldDTO>>() {
}.getType());
xAxis.addAll(xAxisExt);
}
List<ChartViewFieldDTO> yAxis = new Gson().fromJson(view.getYAxis(), new TypeToken<List<ChartViewFieldDTO>>() {
}.getType());
if (StringUtils.equalsIgnoreCase(view.getType(), "chart-mix")) {
......@@ -305,10 +310,10 @@ public class ChartViewService {
filterRequest.setFieldId(fId);
DatasetTableField datasetTableField = dataSetTableFieldsService.get(fId);
if(datasetTableField == null){
if (datasetTableField == null) {
continue;
}
if(!desensitizationList.contains(datasetTableField.getDataeaseName()) && dataeaseNames.contains(datasetTableField.getDataeaseName())){
if (!desensitizationList.contains(datasetTableField.getDataeaseName()) && dataeaseNames.contains(datasetTableField.getDataeaseName())) {
filterRequest.setDatasetTableField(datasetTableField);
if (StringUtils.equalsIgnoreCase(datasetTableField.getTableId(), view.getTableId())) {
if (CollectionUtils.isNotEmpty(filterRequest.getViewIds())) {
......@@ -329,7 +334,7 @@ public class ChartViewService {
if (ObjectUtils.isNotEmpty(requestList.getLinkageFilters())) {
for (ChartExtFilterRequest request : requestList.getLinkageFilters()) {
DatasetTableField datasetTableField = dataSetTableFieldsService.get(request.getFieldId());
if(!desensitizationList.contains(datasetTableField.getDataeaseName()) && dataeaseNames.contains(datasetTableField.getDataeaseName())){
if (!desensitizationList.contains(datasetTableField.getDataeaseName()) && dataeaseNames.contains(datasetTableField.getDataeaseName())) {
request.setDatasetTableField(datasetTableField);
if (StringUtils.equalsIgnoreCase(datasetTableField.getTableId(), view.getTableId())) {
if (CollectionUtils.isNotEmpty(request.getViewIds())) {
......@@ -814,34 +819,68 @@ public class ChartViewService {
}
}
for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) {
AxisChartDataAntVDTO axisChartDataDTO = new AxisChartDataAntVDTO();
axisChartDataDTO.setField(a.toString());
axisChartDataDTO.setName(a.toString());
if (StringUtils.containsIgnoreCase(view.getType(), "table")) {
for (int i = 0; i < xAxis.size() + yAxis.size(); i++) {
AxisChartDataAntVDTO axisChartDataDTO = new AxisChartDataAntVDTO();
axisChartDataDTO.setField(a.toString());
axisChartDataDTO.setName(a.toString());
List<ChartDimensionDTO> dimensionList = new ArrayList<>();
List<ChartQuotaDTO> quotaList = new ArrayList<>();
List<ChartDimensionDTO> dimensionList = new ArrayList<>();
List<ChartQuotaDTO> quotaList = new ArrayList<>();
for (int j = 0; j < xAxis.size(); j++) {
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
chartDimensionDTO.setId(xAxis.get(j).getId());
chartDimensionDTO.setValue(row[j]);
dimensionList.add(chartDimensionDTO);
for (int j = 0; j < xAxis.size(); j++) {
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
chartDimensionDTO.setId(xAxis.get(j).getId());
chartDimensionDTO.setValue(row[j]);
dimensionList.add(chartDimensionDTO);
}
axisChartDataDTO.setDimensionList(dimensionList);
int j = i - xAxis.size();
if (j > -1) {
ChartQuotaDTO chartQuotaDTO = new ChartQuotaDTO();
chartQuotaDTO.setId(yAxis.get(j).getId());
quotaList.add(chartQuotaDTO);
axisChartDataDTO.setQuotaList(quotaList);
try {
axisChartDataDTO.setValue(StringUtils.isEmpty(row[i]) ? null : new BigDecimal(row[i]));
} catch (Exception e) {
axisChartDataDTO.setValue(new BigDecimal(0));
}
axisChartDataDTO.setCategory(yAxis.get(j).getName());
}
datas.add(axisChartDataDTO);
}
axisChartDataDTO.setDimensionList(dimensionList);
} else {
for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) {
AxisChartDataAntVDTO axisChartDataDTO = new AxisChartDataAntVDTO();
axisChartDataDTO.setField(a.toString());
axisChartDataDTO.setName(a.toString());
int j = i - xAxis.size();
ChartQuotaDTO chartQuotaDTO = new ChartQuotaDTO();
chartQuotaDTO.setId(yAxis.get(j).getId());
quotaList.add(chartQuotaDTO);
axisChartDataDTO.setQuotaList(quotaList);
try {
axisChartDataDTO.setValue(StringUtils.isEmpty(row[i]) ? null : new BigDecimal(row[i]));
} catch (Exception e) {
axisChartDataDTO.setValue(new BigDecimal(0));
List<ChartDimensionDTO> dimensionList = new ArrayList<>();
List<ChartQuotaDTO> quotaList = new ArrayList<>();
for (int j = 0; j < xAxis.size(); j++) {
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
chartDimensionDTO.setId(xAxis.get(j).getId());
chartDimensionDTO.setValue(row[j]);
dimensionList.add(chartDimensionDTO);
}
axisChartDataDTO.setDimensionList(dimensionList);
int j = i - xAxis.size();
ChartQuotaDTO chartQuotaDTO = new ChartQuotaDTO();
chartQuotaDTO.setId(yAxis.get(j).getId());
quotaList.add(chartQuotaDTO);
axisChartDataDTO.setQuotaList(quotaList);
try {
axisChartDataDTO.setValue(StringUtils.isEmpty(row[i]) ? null : new BigDecimal(row[i]));
} catch (Exception e) {
axisChartDataDTO.setValue(new BigDecimal(0));
}
axisChartDataDTO.setCategory(yAxis.get(j).getName());
datas.add(axisChartDataDTO);
}
axisChartDataDTO.setCategory(yAxis.get(j).getName());
datas.add(axisChartDataDTO);
}
}
map.put("datas", datas);
......
......@@ -1697,6 +1697,8 @@ public class DataSetTableService {
if (datasetTableIncrementalConfig == null || StringUtils.isEmpty(datasetTableIncrementalConfig.getTableId())) {
return;
}
datasetTableIncrementalConfig.setIncrementalAdd(datasetTableIncrementalConfig.getIncrementalAdd().trim());
datasetTableIncrementalConfig.setIncrementalDelete(datasetTableIncrementalConfig.getIncrementalDelete().trim());
if (StringUtils.isEmpty(datasetTableIncrementalConfig.getId())) {
datasetTableIncrementalConfig.setId(UUID.randomUUID().toString());
datasetTableIncrementalConfigMapper.insertSelective(datasetTableIncrementalConfig);
......
ALTER TABLE `chart_view` ADD COLUMN `x_axis_ext` LONGTEXT COMMENT 'table-row' AFTER `x_axis`;
UPDATE `chart_view` SET `x_axis_ext` = '[]';
\ No newline at end of file
......@@ -60,6 +60,6 @@
</javaClientGenerator>
<!--要生成的数据库表 -->
<table tableName="dataset_column_permissions"/>
<table tableName="chart_view"/>
</context>
</generatorConfiguration>
......@@ -14,10 +14,7 @@ SELECT
<groups:{group|<if(group)><group.fieldName> AS <group.fieldAlias><endif>}; separator=",\n">
<endif>
<if(groups && aggregators)>,<endif>
<if(aggregators && notUseAs)>
<aggregators:{agg|<if(agg)><agg.fieldName> <endif>}; separator=",\n">
<endif>
<if(aggregators && !notUseAs)>
<if(aggregators)>
<aggregators:{agg|<if(agg)><agg.fieldName> AS <agg.fieldAlias><endif>}; separator=",\n">
<endif>
FROM
......@@ -53,10 +50,7 @@ SELECT
<groups:{group|<if(group)><group.fieldName> AS <group.fieldAlias><endif>}; separator=",\n">
<endif>
<if(groups && aggregators)>,<endif>
<if(aggregators && notUseAs)>
<aggregators:{agg|<if(agg)><agg.fieldName> <endif>}; separator=",\n">
<endif>
<if(aggregators && !notUseAs)>
<if(aggregators)>
<aggregators:{agg|<if(agg)><agg.fieldName> AS <agg.fieldAlias><endif>}; separator=",\n">
<endif>
FROM
......
......@@ -14,7 +14,7 @@
},
"dependencies": {
"@antv/g2plot": "^2.3.32",
"@antv/s2": "^1.6.0",
"@antv/s2": "^1.7.0",
"@riophae/vue-treeselect": "0.4.0",
"@tinymce/tinymce-vue": "^3.2.8",
"axios": "^0.21.1",
......
......@@ -37,6 +37,16 @@
@onChartClick="chartClick"
@onJumpClick="jumpClick"
/>
<chart-component-s2
v-if="charViewS2ShowFlag"
:ref="element.propValue.id"
class="chart-class"
:chart="chart"
:track-menu="trackMenu"
:search-count="searchCount"
@onChartClick="chartClick"
@onJumpClick="jumpClick"
/>
<table-normal
v-if="tableShowFlag"
:ref="element.propValue.id"
......@@ -45,7 +55,7 @@
class="table-class"
/>
<label-normal v-if="labelShowFlag" :ref="element.propValue.id" :chart="chart" class="table-class" />
<div style="position: absolute;left: 20px;bottom:14px;">
<div style="position: absolute;left: 8px;bottom:8px;">
<drill-path :drill-filters="drillFilters" @onDrillJump="drillJump" />
</div>
</div>
......@@ -71,10 +81,11 @@ import { areaMapping } from '@/api/map/map'
import ChartComponentG2 from '@/views/chart/components/ChartComponentG2'
import EditBarView from '@/components/canvas/components/Editor/EditBarView'
import { customAttrTrans, customStyleTrans, recursionTransObj } from '@/components/canvas/utils/style'
import ChartComponentS2 from '@/views/chart/components/ChartComponentS2'
export default {
name: 'UserView',
components: { EditBarView, ChartComponent, TableNormal, LabelNormal, DrillPath, ChartComponentG2 },
components: { ChartComponentS2, EditBarView, ChartComponent, TableNormal, LabelNormal, DrillPath, ChartComponentG2 },
props: {
element: {
type: Object,
......@@ -169,8 +180,11 @@ export default {
charViewG2ShowFlag() {
return this.httpRequest.status && this.chart.type && !this.chart.type.includes('table') && !this.chart.type.includes('text') && this.renderComponent() === 'antv'
},
charViewS2ShowFlag() {
return this.httpRequest.status && this.chart.type && this.chart.type.includes('table') && !this.chart.type.includes('text') && this.renderComponent() === 'antv'
},
tableShowFlag() {
return this.httpRequest.status && this.chart.type && this.chart.type.includes('table')
return this.httpRequest.status && this.chart.type && this.chart.type.includes('table') && this.renderComponent() === 'echarts'
},
labelShowFlag() {
return this.httpRequest.status && this.chart.type && this.chart.type.includes('text')
......
......@@ -70,7 +70,7 @@ class NumberRangeServiceImpl extends WidgetService {
getParam(element) {
if (element.options.value && element.options.value.length > 0) {
const values = this.element.options.value
const values = element.options.value
const min = values[0]
let max = null
if (values.length > 1) {
......
......@@ -82,7 +82,7 @@ class NumberSelectGridServiceImpl extends WidgetService {
})
}
getParam(element) {
const value = element.options.value
const value = this.fillValueDerfault(element)
const param = {
component: element,
value: !value ? [] : Array.isArray(value) ? value : value.toString().split(','),
......@@ -90,6 +90,16 @@ class NumberSelectGridServiceImpl extends WidgetService {
}
return param
}
fillValueDerfault(element) {
const defaultV = element.options.value === null ? '' : element.options.value.toString()
if (element.options.attrs.multiple) {
if (defaultV === null || typeof defaultV === 'undefined' || defaultV === '' || defaultV === '[object Object]') return []
return defaultV.split(',')
} else {
if (defaultV === null || typeof defaultV === 'undefined' || defaultV === '' || defaultV === '[object Object]') return null
return defaultV.split(',')[0]
}
}
}
const numberSelectGridServiceImpl = new NumberSelectGridServiceImpl()
export default numberSelectGridServiceImpl
......@@ -83,7 +83,7 @@ class NumberSelectServiceImpl extends WidgetService {
})
}
getParam(element) {
const value = element.options.value
const value = this.fillValueDerfault(element)
const param = {
component: element,
value: !value ? [] : Array.isArray(value) ? value : value.toString().split(','),
......@@ -91,6 +91,16 @@ class NumberSelectServiceImpl extends WidgetService {
}
return param
}
fillValueDerfault(element) {
const defaultV = element.options.value === null ? '' : element.options.value.toString()
if (element.options.attrs.multiple) {
if (defaultV === null || typeof defaultV === 'undefined' || defaultV === '' || defaultV === '[object Object]') return []
return defaultV.split(',')
} else {
if (defaultV === null || typeof defaultV === 'undefined' || defaultV === '' || defaultV === '[object Object]') return null
return defaultV.split(',')[0]
}
}
}
const numberSelectServiceImpl = new NumberSelectServiceImpl()
export default numberSelectServiceImpl
......@@ -82,7 +82,7 @@ class TextSelectGridServiceImpl extends WidgetService {
})
}
getParam(element) {
const value = element.options.value
const value = this.fillValueDerfault(element)
const param = {
component: element,
value: !value ? [] : Array.isArray(value) ? value : value.toString().split(','),
......@@ -90,6 +90,16 @@ class TextSelectGridServiceImpl extends WidgetService {
}
return param
}
fillValueDerfault(element) {
const defaultV = element.options.value === null ? '' : element.options.value.toString()
if (element.options.attrs.multiple) {
if (defaultV === null || typeof defaultV === 'undefined' || defaultV === '' || defaultV === '[object Object]') return []
return defaultV.split(',')
} else {
if (defaultV === null || typeof defaultV === 'undefined' || defaultV === '' || defaultV === '[object Object]') return null
return defaultV.split(',')[0]
}
}
}
const textSelectGridServiceImpl = new TextSelectGridServiceImpl()
export default textSelectGridServiceImpl
......@@ -82,7 +82,7 @@ class TextSelectServiceImpl extends WidgetService {
}
getParam(element) {
const value = element.options.value
const value = this.fillValueDerfault(element)
const param = {
component: element,
value: !value ? [] : Array.isArray(value) ? value : value.toString().split(','),
......@@ -90,6 +90,17 @@ class TextSelectServiceImpl extends WidgetService {
}
return param
}
fillValueDerfault(element) {
const defaultV = element.options.value === null ? '' : element.options.value.toString()
if (element.options.attrs.multiple) {
if (defaultV === null || typeof defaultV === 'undefined' || defaultV === '' || defaultV === '[object Object]') return []
return defaultV.split(',')
} else {
if (defaultV === null || typeof defaultV === 'undefined' || defaultV === '' || defaultV === '[object Object]') return null
return defaultV.split(',')[0]
}
}
}
const textSelectServiceImpl = new TextSelectServiceImpl()
export default textSelectServiceImpl
......@@ -227,7 +227,7 @@ class TimeDateRangeServiceImpl extends WidgetService {
}
getParam(element) {
let timeArr = []
if (element.options.attrs.default.isDynamic) {
if (element.options.attrs.default && element.options.attrs.default.isDynamic) {
let value = this.dynamicDateFormNow(element)
value = this.formatFilterValue(value)
timeArr = this.formatValues(value, element)
......
......@@ -157,7 +157,7 @@ class TimeDateServiceImpl extends WidgetService {
}
getParam(element) {
let timeArr = []
if (element.options.attrs.default.isDynamic) {
if (element.options.attrs.default && element.options.attrs.default.isDynamic) {
let value = this.dynamicDateFormNow(element)
value = this.formatFilterValue(value)
timeArr = this.formatValues(value, element)
......
......@@ -123,7 +123,7 @@ class TimeMonthServiceImpl extends WidgetService {
}
getParam(element) {
let timeArr = []
if (element.options.attrs.default.isDynamic) {
if (element.options.attrs.default && element.options.attrs.default.isDynamic) {
let value = this.dynamicDateFormNow(element)
value = this.formatFilterValue(value)
timeArr = this.formatValues(value, element)
......
......@@ -114,7 +114,7 @@ class TimeYearServiceImpl extends WidgetService {
}
getParam(element) {
let timeArr = []
if (element.options.attrs.default.isDynamic) {
if (element.options.attrs.default && element.options.attrs.default.isDynamic) {
let value = this.dynamicDateFormNow(element)
value = this.formatFilterValue(value)
timeArr = this.formatValues(value, element)
......
<svg t="1630896178915" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1969" width="200" height="200"><path d="M85.333333 170.666667h853.333334v170.666666H85.333333zM85.333333 384h170.666667v469.333333H85.333333z" p-id="1970"></path><path d="M298.666667 384h640v128H298.666667z" opacity=".6" p-id="1971"></path><path d="M298.666667 554.666667h298.666666v128H298.666667zM640 554.666667h298.666667v128H640z" p-id="1972"></path><path d="M298.666667 725.333333h298.666666v128H298.666667zM640 725.333333h298.666667v128H640z" opacity=".6" p-id="1973"></path></svg>
<svg t="1644288854112" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1947" width="200" height="200"><path d="M85.333333 170.666667h853.333334v170.666666H85.333333zM85.333333 384h170.666667v469.333333H85.333333z" p-id="1948"></path><path d="M298.666667 384h640v128H298.666667z" opacity=".6" p-id="1949"></path><path d="M298.666667 554.666667h640v128H298.666667z" p-id="1950"></path><path d="M298.666667 725.333333h640v128H298.666667z" opacity=".6" p-id="1951"></path></svg>
<svg t="1630896178915" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1969" width="200" height="200"><path d="M85.333333 170.666667h853.333334v170.666666H85.333333zM85.333333 384h170.666667v469.333333H85.333333z" p-id="1970"></path><path d="M298.666667 384h640v128H298.666667z" opacity=".6" p-id="1971"></path><path d="M298.666667 554.666667h298.666666v128H298.666667zM640 554.666667h298.666667v128H640z" p-id="1972"></path><path d="M298.666667 725.333333h298.666666v128H298.666667zM640 725.333333h298.666667v128H640z" opacity=".6" p-id="1973"></path></svg>
......@@ -1016,7 +1016,13 @@ export default {
filter_exp: 'Filter Value',
filter_type: 'Filter Type',
filter_value_can_not_str: 'Value type can not input string',
enum_value_can_not_null: 'Enum Value can not empty.'
enum_value_can_not_null: 'Enum Value can not empty.',
table_config: 'Table Config',
table_column_width_config: 'Column Width',
table_column_adapt: 'Adapt',
table_column_custom: 'Custom',
chart_table_pivot: 'Pivot Table',
table_pivot_row: 'Data Row'
},
dataset: {
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',
......
......@@ -1016,7 +1016,13 @@ export default {
filter_exp: '過濾值',
filter_type: '過濾方式',
filter_value_can_not_str: '數值類型字段過濾值不能包含文本',
enum_value_can_not_null: '字段枚舉值不能為空'
enum_value_can_not_null: '字段枚舉值不能為空',
table_config: '表格配置',
table_column_width_config: '列寬調整',
table_column_adapt: '自適應',
table_column_custom: '自定義',
chart_table_pivot: '透視表',
table_pivot_row: '數據行'
},
dataset: {
sheet_warn: '有多個 Sheet 頁,默認抽取第一個',
......
......@@ -1018,7 +1018,13 @@ export default {
filter_exp: '过滤值',
filter_type: '过滤方式',
filter_value_can_not_str: '数值类型字段过滤值不能包含文本',
enum_value_can_not_null: '字段枚举值不能为空'
enum_value_can_not_null: '字段枚举值不能为空',
table_config: '表格配置',
table_column_width_config: '列宽调整',
table_column_adapt: '自适应',
table_column_custom: '自定义',
chart_table_pivot: '透视表',
table_pivot_row: '数据行'
},
dataset: {
sheet_warn: '有多个 Sheet 页,默认抽取第一个',
......
......@@ -31,6 +31,8 @@ export const DEFAULT_SIZE = {
tableTitleHeight: 36,
tableItemHeight: 36,
tablePageSize: '20',
tableColumnMode: 'adapt',
tableColumnWidth: 100,
gaugeMin: 0,
gaugeMax: 100,
gaugeStartAngle: 225,
......
import { hexColorToRGBA } from '@/views/chart/chart/util'
import { DEFAULT_COLOR_CASE, DEFAULT_SIZE } from '@/views/chart/chart/chart'
export function getCustomTheme(chart) {
const theme = {
background: {
color: '#00000000'
},
cornerCell: {
cell: {
backgroundColor: hexColorToRGBA(DEFAULT_COLOR_CASE.tableHeaderBgColor, DEFAULT_COLOR_CASE.alpha)
},
text: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
},
bolderText: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
}
},
rowCell: {
cell: {
backgroundColor: hexColorToRGBA(DEFAULT_COLOR_CASE.tableHeaderBgColor, DEFAULT_COLOR_CASE.alpha)
},
text: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
},
bolderText: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
}
},
colCell: {
cell: {
backgroundColor: hexColorToRGBA(DEFAULT_COLOR_CASE.tableHeaderBgColor, DEFAULT_COLOR_CASE.alpha)
},
text: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
},
bolderText: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableTitleFontSize
}
},
dataCell: {
cell: {
backgroundColor: hexColorToRGBA(DEFAULT_COLOR_CASE.tableItemBgColor, DEFAULT_COLOR_CASE.alpha)
},
text: {
fill: DEFAULT_COLOR_CASE.tableFontColor,
fontSize: DEFAULT_SIZE.tableItemFontSize
}
}
}
let customAttr = {}
if (chart.customAttr) {
customAttr = JSON.parse(chart.customAttr)
// color
if (customAttr.color) {
const c = JSON.parse(JSON.stringify(customAttr.color))
theme.cornerCell.cell.backgroundColor = hexColorToRGBA(c.tableHeaderBgColor, c.alpha)
theme.cornerCell.bolderText.fill = c.tableFontColor
theme.cornerCell.text.fill = c.tableFontColor
theme.rowCell.cell.backgroundColor = hexColorToRGBA(c.tableHeaderBgColor, c.alpha)
theme.rowCell.bolderText.fill = c.tableFontColor
theme.rowCell.text.fill = c.tableFontColor
theme.colCell.cell.backgroundColor = hexColorToRGBA(c.tableHeaderBgColor, c.alpha)
theme.colCell.bolderText.fill = c.tableFontColor
theme.colCell.text.fill = c.tableFontColor
theme.dataCell.cell.backgroundColor = hexColorToRGBA(c.tableItemBgColor, c.alpha)
theme.dataCell.text.fill = c.tableFontColor
}
// size
if (customAttr.size) {
const s = JSON.parse(JSON.stringify(customAttr.size))
theme.cornerCell.bolderText.fontSize = parseInt(s.tableTitleFontSize)
theme.cornerCell.text.fontSize = parseInt(s.tableTitleFontSize)
theme.rowCell.bolderText.fontSize = parseInt(s.tableTitleFontSize)
theme.rowCell.text.fontSize = parseInt(s.tableTitleFontSize)
theme.colCell.bolderText.fontSize = parseInt(s.tableTitleFontSize)
theme.colCell.text.fontSize = parseInt(s.tableTitleFontSize)
theme.dataCell.text.fontSize = parseInt(s.tableItemFontSize)
}
}
return theme
}
export function getSize(chart) {
const size = {}
let customAttr = {}
if (chart.customAttr) {
customAttr = JSON.parse(chart.customAttr)
// size
if (customAttr.size) {
const s = JSON.parse(JSON.stringify(customAttr.size))
size.colCfg = {
height: s.tableTitleHeight
}
size.cellCfg = {
height: s.tableItemHeight
}
if (!s.tableColumnMode || s.tableColumnMode === 'adapt') {
delete size.cellCfg.width
size.layoutWidthType = 'compact'
} else {
delete size.layoutWidthType
size.cellCfg.width = s.tableColumnWidth
}
}
}
return size
}
import { TableSheet, S2Event, PivotSheet } from '@antv/s2'
import { getCustomTheme, getSize } from '@/views/chart/chart/common/common_table'
export function baseTableInfo(s2, container, chart, action, tableData) {
const containerDom = document.getElementById(container)
// fields
const fields = chart.data.fields
if (!fields || fields.length === 0) {
if (s2) {
s2.destroy()
}
return
}
const columns = []
const meta = []
// add drill list
if (chart.drill) {
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))
const drillExp = drillFilters[drillFilters.length - 1].datasetTableField
// 移除所有下钻字段
const removeField = []
for (let i = 0; i < chart.drillFilters.length; i++) {
const ele = chart.drillFilters[i].datasetTableField
removeField.push(ele.dataeaseName)
}
// build field
fields.forEach(ele => {
if (removeField.indexOf(ele.dataeaseName) < 0) {
// 用下钻字段替换当前字段
if (drillExp.dataeaseName === ele.dataeaseName) {
columns.push(drillField.dataeaseName)
meta.push({
field: drillField.dataeaseName,
name: drillField.name
})
} else {
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
name: ele.name
})
}
}
})
} else {
fields.forEach(ele => {
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
name: ele.name
})
})
}
// data config
const s2DataConfig = {
fields: {
columns: columns
},
meta: meta,
data: tableData
}
// options
const s2Options = {
width: containerDom.offsetWidth,
height: containerDom.offsetHeight,
// showSeriesNumber: true
style: getSize(chart)
}
// 开始渲染
if (s2) {
s2.destroy()
}
s2 = new TableSheet(containerDom, s2DataConfig, s2Options)
// click
s2.on(S2Event.DATA_CELL_CLICK, action)
// theme
const customTheme = getCustomTheme(chart)
s2.setThemeCfg({ theme: customTheme })
return s2
}
export function baseTableNormal(s2, container, chart, action, tableData) {
const containerDom = document.getElementById(container)
// fields
const fields = chart.data.fields
if (!fields || fields.length === 0) {
if (s2) {
s2.destroy()
}
return
}
const columns = []
const meta = []
// add drill list
if (chart.drill) {
const drillFields = JSON.parse(chart.drillFields)
const drillField = drillFields[chart.drillFilters.length]
const drillFilters = JSON.parse(JSON.stringify(chart.drillFilters))
const drillExp = drillFilters[drillFilters.length - 1].datasetTableField
// 移除所有下钻字段
const removeField = []
for (let i = 0; i < chart.drillFilters.length; i++) {
const ele = chart.drillFilters[i].datasetTableField
removeField.push(ele.dataeaseName)
}
// build field
fields.forEach(ele => {
if (removeField.indexOf(ele.dataeaseName) < 0) {
// 用下钻字段替换当前字段
if (drillExp.dataeaseName === ele.dataeaseName) {
columns.push(drillField.dataeaseName)
meta.push({
field: drillField.dataeaseName,
name: drillField.name
})
} else {
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
name: ele.name
})
}
}
})
} else {
fields.forEach(ele => {
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
name: ele.name
})
})
}
// data config
const s2DataConfig = {
fields: {
columns: columns
},
meta: meta,
data: tableData
}
// options
const s2Options = {
width: containerDom.offsetWidth,
height: containerDom.offsetHeight,
// showSeriesNumber: true
style: getSize(chart)
}
// 开始渲染
if (s2) {
s2.destroy()
}
s2 = new TableSheet(containerDom, s2DataConfig, s2Options)
// click
s2.on(S2Event.DATA_CELL_CLICK, action)
// theme
const customTheme = getCustomTheme(chart)
s2.setThemeCfg({ theme: customTheme })
return s2
}
export function baseTablePivot(s2, container, chart, action, tableData) {
const containerDom = document.getElementById(container)
// row and column
const columnFields = JSON.parse(chart.xaxis)
const rowFields = JSON.parse(chart.xaxisExt)
const valueFields = JSON.parse(chart.yaxis)
const c = []; const r = []; const v = []
columnFields.forEach(ele => {
c.push(ele.dataeaseName)
})
rowFields.forEach(ele => {
r.push(ele.dataeaseName)
})
valueFields.forEach(ele => {
v.push(ele.dataeaseName)
})
// fields
const fields = chart.data.fields
if (!fields || fields.length === 0) {
if (s2) {
s2.destroy()
}
return
}
const columns = []
const meta = []
// add drill list
if (chart.drill) {
const drillFields = JSON.parse(chart.drillFields)
const drillField = drillFields[chart.drillFilters.length]
const drillFilters = JSON.parse(JSON.stringify(chart.drillFilters))
const drillExp = drillFilters[drillFilters.length - 1].datasetTableField
// 移除所有下钻字段
const removeField = []
for (let i = 0; i < chart.drillFilters.length; i++) {
const ele = chart.drillFilters[i].datasetTableField
removeField.push(ele.dataeaseName)
}
// build field
fields.forEach(ele => {
if (removeField.indexOf(ele.dataeaseName) < 0) {
// 用下钻字段替换当前字段
if (drillExp.dataeaseName === ele.dataeaseName) {
columns.push(drillField.dataeaseName)
meta.push({
field: drillField.dataeaseName,
name: drillField.name
})
} else {
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
name: ele.name
})
}
}
})
} else {
fields.forEach(ele => {
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
name: ele.name
})
})
}
// data config
const s2DataConfig = {
fields: {
rows: r,
columns: c,
values: v
},
meta: meta,
data: tableData
}
// options
const s2Options = {
width: containerDom.offsetWidth,
height: containerDom.offsetHeight,
style: getSize(chart)
}
// 开始渲染
if (s2) {
s2.destroy()
}
s2 = new PivotSheet(containerDom, s2DataConfig, s2Options)
// click
s2.on(S2Event.DATA_CELL_CLICK, action)
// theme
const customTheme = getCustomTheme(chart)
s2.setThemeCfg({ theme: customTheme })
return s2
}
<template>
<span>
<el-tag v-if="!hasDataPermission('manage',param.privileges)" size="small" class="item-axis" :type="item.groupType === 'q'?'success':''">
<span style="float: left">
<svg-icon v-if="item.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="item.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon v-if="item.deType === 2 || item.deType === 3" icon-class="field_value" class="field-icon-value" />
<svg-icon v-if="item.deType === 5" icon-class="field_location" class="field-icon-location" />
<svg-icon v-if="item.sort === 'asc'" icon-class="sort-asc" class-name="field-icon-sort" />
<svg-icon v-if="item.sort === 'desc'" icon-class="sort-desc" class-name="field-icon-sort" />
</span>
<span class="item-span-style" :title="item.name">{{ item.name }}</span>
<span v-if="item.deType === 1" class="summary-span">
{{ $t('chart.' + item.dateStyle) }}
</span>
</el-tag>
<el-dropdown v-else trigger="click" size="mini" @command="clickItem">
<span class="el-dropdown-link">
<el-tag size="small" class="item-axis" :type="item.groupType === 'q'?'success':''">
<span style="float: left">
<svg-icon v-if="item.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="item.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon v-if="item.deType === 2 || item.deType === 3" icon-class="field_value" class="field-icon-value" />
<svg-icon v-if="item.deType === 5" icon-class="field_location" class="field-icon-location" />
<svg-icon v-if="item.sort === 'asc'" icon-class="sort-asc" class-name="field-icon-sort" />
<svg-icon v-if="item.sort === 'desc'" icon-class="sort-desc" class-name="field-icon-sort" />
</span>
<span class="item-span-style" :title="item.name">{{ item.name }}</span>
<span v-if="item.deType === 1" class="summary-span">
{{ $t('chart.' + item.dateStyle) }}
</span>
<i class="el-icon-arrow-down el-icon--right" style="position: absolute;top: 6px;right: 10px;" />
</el-tag>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<el-dropdown placement="right-start" size="mini" style="width: 100%" @command="sort">
<span class="el-dropdown-link inner-dropdown-menu">
<span>
<i class="el-icon-sort" />
<span>{{ $t('chart.sort') }}</span>
<span class="summary-span-item">({{ $t('chart.'+item.sort) }})</span>
</span>
<i class="el-icon-arrow-right el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="beforeSort('none')">{{ $t('chart.none') }}</el-dropdown-item>
<el-dropdown-item :command="beforeSort('asc')">{{ $t('chart.asc') }}</el-dropdown-item>
<el-dropdown-item :command="beforeSort('desc')">{{ $t('chart.desc') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-dropdown-item>
<el-dropdown-item v-show="item.deType === 1" divided>
<el-dropdown placement="right-start" size="mini" style="width: 100%" @command="dateStyle">
<span class="el-dropdown-link inner-dropdown-menu">
<span>
<i class="el-icon-c-scale-to-original" />
<span>{{ $t('chart.dateStyle') }}</span>
<span class="summary-span-item">({{ $t('chart.'+item.dateStyle) }})</span>
</span>
<i class="el-icon-arrow-right el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="beforeDateStyle('y')">{{ $t('chart.y') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M')">{{ $t('chart.y_M') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M_d')">{{ $t('chart.y_M_d') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('H_m_s')" divided>{{ $t('chart.H_m_s') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M_d_H_m')">{{ $t('chart.y_M_d_H_m') }}</el-dropdown-item>
<el-dropdown-item :command="beforeDateStyle('y_M_d_H_m_s')">{{ $t('chart.y_M_d_H_m_s') }}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-dropdown-item>
<el-dropdown-item v-show="item.deType === 1">
<el-dropdown placement="right-start" size="mini" style="width: 100%" @command="datePattern">
<span class="el-dropdown-link inner-dropdown-menu">
<span>
<i class="el-icon-timer" />
<span>{{ $t('chart.datePattern') }}</span>
<span class="summary-span-item">({{ $t('chart.'+item.datePattern) }})</span>
</span>
<i class="el-icon-arrow-right el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="beforeDatePattern('date_sub')">{{ $t('chart.date_sub') }}(1990-01-01)</el-dropdown-item>
<el-dropdown-item :command="beforeDatePattern('date_split')">{{ $t('chart.date_split') }}(1990/01/01)</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-dropdown-item>
<el-dropdown-item icon="el-icon-edit-outline" divided :command="beforeClickItem('rename')">
<span>{{ $t('chart.show_name_set') }}</span>
</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" divided :command="beforeClickItem('remove')">
<span>{{ $t('chart.delete') }}</span>
</el-dropdown-item>
</el-dropdown-menu>
</span>
</el-dropdown>
</span>
</template>
<script>
export default {
name: 'DimensionExtItem',
props: {
param: {
type: Object,
required: true
},
item: {
type: Object,
required: true
},
index: {
type: Number,
required: true
}
},
data() {
return {
}
},
mounted() {
},
methods: {
clickItem(param) {
if (!param) {
return
}
switch (param.type) {
case 'rename':
this.showRename()
break
case 'remove':
this.removeItem()
break
case 'filter':
this.editFilter()
break
default:
break
}
},
beforeClickItem(type) {
return {
type: type
}
},
sort(param) {
// console.log(param)
this.item.sort = param.type
this.$emit('onDimensionItemChange', this.item)
},
beforeSort(type) {
return {
type: type
}
},
dateStyle(param) {
// console.log(param)
this.item.dateStyle = param.type
this.$emit('onDimensionItemChange', this.item)
},
beforeDateStyle(type) {
return {
type: type
}
},
datePattern(param) {
this.item.datePattern = param.type
this.$emit('onDimensionItemChange', this.item)
},
beforeDatePattern(type) {
return {
type: type
}
},
editFilter() {
this.item.index = this.index
this.$emit('editItemFilter', this.item)
},
showRename() {
this.item.index = this.index
this.item.renameType = 'dimensionExt'
this.$emit('onNameEdit', this.item)
},
removeItem() {
this.item.index = this.index
this.item.removeType = 'dimensionExt'
this.$emit('onDimensionItemRemove', this.item)
}
}
}
</script>
<style scoped>
.item-axis {
padding: 1px 6px;
margin: 0 3px 2px 3px;
text-align: left;
height: 24px;
line-height: 22px;
display: flex;
border-radius: 4px;
box-sizing: border-box;
white-space: nowrap;
width: 159px;
}
.item-axis:hover {
background-color: #fdfdfd;
cursor: pointer;
}
span {
font-size: 12px;
}
.summary-span{
margin-left: 4px;
color: #878d9f;
position: absolute;
right: 25px;
}
.inner-dropdown-menu{
display: flex;
justify-content: space-between;
align-items: center;
width: 100%
}
.item-span-style{
display: inline-block;
width: 70px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.summary-span-item{
margin-left: 4px;
color: #878d9f;
}
</style>
......@@ -190,6 +190,7 @@ export default {
},
removeItem() {
this.item.index = this.index
this.item.removeType = 'dimension'
this.$emit('onDimensionItemRemove', this.item)
}
}
......
......@@ -81,6 +81,16 @@
</el-form>
<el-form v-show="chart.type && chart.type.includes('table')" ref="sizeFormPie" :disabled="param && !hasDataPermission('manage',param.privileges)" :model="sizeForm" label-width="100px" size="mini">
<el-form-item v-show="chart.type && chart.type === 'table-info'" :label="$t('chart.table_page_size')" class="form-item">
<el-select v-model="sizeForm.tablePageSize" :placeholder="$t('chart.table_page_size')" @change="changeBarSizeCase">
<el-option
v-for="item in pageSizeOptions"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('chart.table_title_fontsize')" class="form-item">
<el-select v-model="sizeForm.tableTitleFontSize" :placeholder="$t('chart.table_title_fontsize')" @change="changeBarSizeCase">
<el-option v-for="option in fontSize" :key="option.value" :label="option.name" :value="option.value" />
......@@ -92,20 +102,29 @@
</el-select>
</el-form-item>
<el-form-item :label="$t('chart.table_title_height')" class="form-item form-item-slider">
<el-slider v-model="sizeForm.tableTitleHeight" :min="36" :max="100" show-input :show-input-controls="false" input-size="mini" @change="changeBarSizeCase" />
<el-slider v-model="sizeForm.tableTitleHeight" :min="20" :max="100" show-input :show-input-controls="false" input-size="mini" @change="changeBarSizeCase" />
</el-form-item>
<el-form-item :label="$t('chart.table_item_height')" class="form-item form-item-slider">
<el-slider v-model="sizeForm.tableItemHeight" :min="36" :max="100" show-input :show-input-controls="false" input-size="mini" @change="changeBarSizeCase" />
</el-form-item>
<el-form-item v-show="chart.type && chart.type === 'table-info'" :label="$t('chart.table_page_size')" class="form-item">
<el-select v-model="sizeForm.tablePageSize" :placeholder="$t('chart.table_page_size')" @change="changeBarSizeCase">
<el-option
v-for="item in pageSizeOptions"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-select>
<el-slider v-model="sizeForm.tableItemHeight" :min="20" :max="100" show-input :show-input-controls="false" input-size="mini" @change="changeBarSizeCase" />
</el-form-item>
<el-form-item :label="$t('chart.table_column_width_config')" class="form-item">
<el-radio-group v-model="sizeForm.tableColumnMode" @change="changeBarSizeCase">
<el-radio label="adapt"><span>{{ $t('chart.table_column_adapt') }}</span></el-radio>
<el-radio label="custom">
<span>{{ $t('chart.table_column_custom') }}</span>
</el-radio>
</el-radio-group>
<el-tooltip class="item" effect="dark" placement="bottom">
<div slot="content">
列宽并非任何时候都能生效。
<br>
容器宽度优先级高于列宽,即(表格容器宽度 / 列数 > 指定列宽),则列宽优先取(容器宽度 / 列数)。
</div>
<i class="el-icon-info" style="cursor: pointer;color: #606266;margin-left: 4px;" />
</el-tooltip>
</el-form-item>
<el-form-item v-show="sizeForm.tableColumnMode === 'custom'" label="" class="form-item form-item-slider">
<el-slider v-model="sizeForm.tableColumnWidth" :min="10" :max="500" show-input :show-input-controls="false" input-size="mini" @change="changeBarSizeCase" />
</el-form-item>
</el-form>
......@@ -322,6 +341,9 @@ export default {
this.sizeForm.liquidWaveCount = this.sizeForm.liquidWaveCount ? this.sizeForm.liquidWaveCount : DEFAULT_SIZE.liquidWaveCount
this.sizeForm.tablePageSize = this.sizeForm.tablePageSize ? this.sizeForm.tablePageSize : DEFAULT_SIZE.tablePageSize
this.sizeForm.tableColumnMode = this.sizeForm.tableColumnMode ? this.sizeForm.tableColumnMode : DEFAULT_SIZE.tableColumnMode
this.sizeForm.tableColumnWidth = this.sizeForm.tableColumnWidth ? this.sizeForm.tableColumnWidth : DEFAULT_SIZE.tableColumnWidth
}
}
},
......@@ -361,7 +383,9 @@ export default {
.el-select-dropdown__item{
padding: 0 20px;
}
span{font-size: 12px}
span{
font-size: 12px
}
.el-form-item{
margin-bottom: 6px;
......
......@@ -768,6 +768,7 @@ export default {
})
view.stylePriority = 'view' // 默认样式优先级视图
view.xaxis = JSON.stringify([])
view.xaxisExt = JSON.stringify([])
view.yaxis = JSON.stringify([])
view.yaxisExt = JSON.stringify([])
view.extStack = JSON.stringify([])
......
......@@ -20,7 +20,16 @@
<p class="radio-label">{{ $t('chart.chart_table_info') }}</p>
</el-radio>
</div>
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
<div style="position: relative;display: block;">
<el-radio value="table-pivot" label="table-pivot" border class="radio-style">
<span :title="$t('chart.chart_table_pivot')">
<svg-icon icon-class="table-pivot" class="chart-icon" />
</span>
<p class="radio-label">{{ $t('chart.chart_table_pivot') }}</p>
</el-radio>
</div>
<!--如需要,以下用于占位-->
<!--<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>-->
</div>
</div>
......
<template>
<!-- #ifndef APP-NVUE -->
<view :class="['uni-col', sizeClass, pointClassList]" :style="{
paddingLeft:`${Number(gutter)}rpx`,
paddingRight:`${Number(gutter)}rpx`,
}">
<slot></slot>
</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<!-- 在nvue上,类名样式不生效,换为style -->
<!-- 设置right正值失效,设置 left 负值 -->
<view :class="['uni-col']" :style="{
paddingLeft:`${Number(gutter)}rpx`,
paddingRight:`${Number(gutter)}rpx`,
width:`${nvueWidth}rpx`,
position:'relative',
marginLeft:`${marginLeft}rpx`,
left:`${right === 0 ? left : -right}rpx`
}">
<slot></slot>
</view>
<!-- #endif -->
</template>
<script>
/**
* Col 布局-列
* @description 搭配uni-row使用,构建布局。
* @tutorial https://ext.dcloud.net.cn/plugin?id=3958
*
* @property {span} type = Number 栅格占据的列数
* 默认 24
* @property {offset} type = Number 栅格左侧的间隔格数
* @property {push} type = Number 栅格向右移动格数
* @property {pull} type = Number 栅格向左移动格数
* @property {xs} type = [Number, Object] <768px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {sm} type = [Number, Object] ≥768px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {md} type = [Number, Object] ≥992px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {lg} type = [Number, Object] ≥1200px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
* @property {xl} type = [Number, Object] ≥1920px 响应式栅格数或者栅格属性对象
* @description Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
*/
const ComponentClass = 'uni-col';
// -1 默认值,因为在微信小程序端只给Number会有默认值0
export default {
name: 'uniCol',
// #ifdef MP-WEIXIN
options: {
virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现
},
// #endif
props: {
span: {
type: Number,
default: 24
},
offset: {
type: Number,
default: -1
},
pull: {
type: Number,
default: -1
},
push: {
type: Number,
default: -1
},
xs: [Number, Object],
sm: [Number, Object],
md: [Number, Object],
lg: [Number, Object],
xl: [Number, Object]
},
data() {
return {
gutter: 0,
sizeClass: '',
parentWidth: 0,
nvueWidth: 0,
marginLeft: 0,
right: 0,
left: 0
}
},
created() {
// 字节小程序中,在computed中读取$parent为undefined
let parent = this.$parent;
while (parent && parent.$options.componentName !== 'uniRow') {
parent = parent.$parent;
}
this.updateGutter(parent.gutter)
parent.$watch('gutter', (gutter) => {
this.updateGutter(gutter)
})
// #ifdef APP-NVUE
this.updateNvueWidth(parent.width)
parent.$watch('width', (width) => {
this.updateNvueWidth(width)
})
// #endif
},
computed: {
sizeList() {
let {
span,
offset,
pull,
push
} = this;
return {
span,
offset,
pull,
push
}
},
// #ifndef APP-NVUE
pointClassList() {
let classList = [];
['xs', 'sm', 'md', 'lg', 'xl'].forEach(point => {
const props = this[point];
if (typeof props === 'number') {
classList.push(`${ComponentClass}-${point}-${props}`)
} else if (typeof props === 'object' && props) {
Object.keys(props).forEach(pointProp => {
classList.push(
pointProp === 'span' ?
`${ComponentClass}-${point}-${props[pointProp]}` :
`${ComponentClass}-${point}-${pointProp}-${props[pointProp]}`
)
})
}
});
// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误
return classList.join(' ');
}
// #endif
},
methods: {
updateGutter(parentGutter) {
parentGutter = Number(parentGutter);
if (!isNaN(parentGutter)) {
this.gutter = parentGutter / 2
}
},
// #ifdef APP-NVUE
updateNvueWidth(width) {
// 用于在nvue端,span,offset,pull,push的计算
this.parentWidth = width;
['span', 'offset', 'pull', 'push'].forEach(size => {
const curSize = this[size];
if ((curSize || curSize === 0) && curSize !== -1) {
let RPX = 1 / 24 * curSize * width
RPX = Number(RPX);
switch (size) {
case 'span':
this.nvueWidth = RPX
break;
case 'offset':
this.marginLeft = RPX
break;
case 'pull':
this.right = RPX
break;
case 'push':
this.left = RPX
break;
}
}
});
}
// #endif
},
watch: {
sizeList: {
immediate: true,
handler(newVal) {
// #ifndef APP-NVUE
let classList = [];
for (let size in newVal) {
const curSize = newVal[size];
if ((curSize || curSize === 0) && curSize !== -1) {
classList.push(
size === 'span' ?
`${ComponentClass}-${curSize}` :
`${ComponentClass}-${size}-${curSize}`
)
}
}
// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误
this.sizeClass = classList.join(' ');
// #endif
// #ifdef APP-NVUE
this.updateNvueWidth(this.parentWidth);
// #endif
}
}
}
}
</script>
<style lang='scss' scoped>
/* breakpoints */
$--sm: 768px !default;
$--md: 992px !default;
$--lg: 1200px !default;
$--xl: 1920px !default;
$breakpoints: ('xs' : (max-width: $--sm - 1),
'sm' : (min-width: $--sm),
'md' : (min-width: $--md),
'lg' : (min-width: $--lg),
'xl' : (min-width: $--xl));
$layout-namespace: ".uni-";
$col: $layout-namespace+"col";
@function getSize($size) {
/* TODO 1/24 * $size * 100 * 1%; 使用计算后的值,为了解决 vue3 控制台报错 */
@return 0.04166666666 * $size * 100 * 1%;
}
@mixin res($key, $map:$breakpoints) {
@if map-has-key($map, $key) {
@media screen and #{inspect(map-get($map,$key))} {
@content;
}
}
@else {
@warn "Undeinfed point: `#{$key}`";
}
}
/* #ifndef APP-NVUE */
#{$col} {
float: left;
box-sizing: border-box;
}
#{$col}-0 {
/* #ifdef APP-NVUE */
width: 0;
height: 0;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;
/* #endif */
/* #ifndef APP-NVUE */
display: none;
/* #endif */
}
@for $i from 0 through 24 {
#{$col}-#{$i} {
width: getSize($i);
}
#{$col}-offset-#{$i} {
margin-left: getSize($i);
}
#{$col}-pull-#{$i} {
position: relative;
right: getSize($i);
}
#{$col}-push-#{$i} {
position: relative;
left: getSize($i);
}
}
@each $point in map-keys($breakpoints) {
@include res($point) {
#{$col}-#{$point}-0 {
display: none;
}
@for $i from 0 through 24 {
#{$col}-#{$point}-#{$i} {
width: getSize($i);
}
#{$col}-#{$point}-offset-#{$i} {
margin-left: getSize($i);
}
#{$col}-#{$point}-pull-#{$i} {
position: relative;
right: getSize($i);
}
#{$col}-#{$point}-push-#{$i} {
position: relative;
left: getSize($i);
}
}
}
}
/* #endif */
</style>
export default {
"pulldown": "\ue588",
"refreshempty": "\ue461",
"back": "\ue471",
"forward": "\ue470",
"more": "\ue507",
"more-filled": "\ue537",
"scan": "\ue612",
"qq": "\ue264",
"weibo": "\ue260",
"weixin": "\ue261",
"pengyouquan": "\ue262",
"loop": "\ue565",
"refresh": "\ue407",
"refresh-filled": "\ue437",
"arrowthindown": "\ue585",
"arrowthinleft": "\ue586",
"arrowthinright": "\ue587",
"arrowthinup": "\ue584",
"undo-filled": "\ue7d6",
"undo": "\ue406",
"redo": "\ue405",
"redo-filled": "\ue7d9",
"bars": "\ue563",
"chatboxes": "\ue203",
"camera": "\ue301",
"chatboxes-filled": "\ue233",
"camera-filled": "\ue7ef",
"cart-filled": "\ue7f4",
"cart": "\ue7f5",
"checkbox-filled": "\ue442",
"checkbox": "\ue7fa",
"arrowleft": "\ue582",
"arrowdown": "\ue581",
"arrowright": "\ue583",
"smallcircle-filled": "\ue801",
"arrowup": "\ue580",
"circle": "\ue411",
"eye-filled": "\ue568",
"eye-slash-filled": "\ue822",
"eye-slash": "\ue823",
"eye": "\ue824",
"flag-filled": "\ue825",
"flag": "\ue508",
"gear-filled": "\ue532",
"reload": "\ue462",
"gear": "\ue502",
"hand-thumbsdown-filled": "\ue83b",
"hand-thumbsdown": "\ue83c",
"hand-thumbsup-filled": "\ue83d",
"heart-filled": "\ue83e",
"hand-thumbsup": "\ue83f",
"heart": "\ue840",
"home": "\ue500",
"info": "\ue504",
"home-filled": "\ue530",
"info-filled": "\ue534",
"circle-filled": "\ue441",
"chat-filled": "\ue847",
"chat": "\ue263",
"mail-open-filled": "\ue84d",
"email-filled": "\ue231",
"mail-open": "\ue84e",
"email": "\ue201",
"checkmarkempty": "\ue472",
"list": "\ue562",
"locked-filled": "\ue856",
"locked": "\ue506",
"map-filled": "\ue85c",
"map-pin": "\ue85e",
"map-pin-ellipse": "\ue864",
"map": "\ue364",
"minus-filled": "\ue440",
"mic-filled": "\ue332",
"minus": "\ue410",
"micoff": "\ue360",
"mic": "\ue302",
"clear": "\ue434",
"smallcircle": "\ue868",
"close": "\ue404",
"closeempty": "\ue460",
"paperclip": "\ue567",
"paperplane": "\ue503",
"paperplane-filled": "\ue86e",
"person-filled": "\ue131",
"contact-filled": "\ue130",
"person": "\ue101",
"contact": "\ue100",
"images-filled": "\ue87a",
"phone": "\ue200",
"images": "\ue87b",
"image": "\ue363",
"image-filled": "\ue877",
"location-filled": "\ue333",
"location": "\ue303",
"plus-filled": "\ue439",
"plus": "\ue409",
"plusempty": "\ue468",
"help-filled": "\ue535",
"help": "\ue505",
"navigate-filled": "\ue884",
"navigate": "\ue501",
"mic-slash-filled": "\ue892",
"search": "\ue466",
"settings": "\ue560",
"sound": "\ue590",
"sound-filled": "\ue8a1",
"spinner-cycle": "\ue465",
"download-filled": "\ue8a4",
"personadd-filled": "\ue132",
"videocam-filled": "\ue8af",
"personadd": "\ue102",
"upload": "\ue402",
"upload-filled": "\ue8b1",
"starhalf": "\ue463",
"star-filled": "\ue438",
"star": "\ue408",
"trash": "\ue401",
"phone-filled": "\ue230",
"compose": "\ue400",
"videocam": "\ue300",
"trash-filled": "\ue8dc",
"download": "\ue403",
"chatbubble-filled": "\ue232",
"chatbubble": "\ue202",
"cloud-download": "\ue8e4",
"cloud-upload-filled": "\ue8e5",
"cloud-upload": "\ue8e6",
"cloud-download-filled": "\ue8e9",
"headphones":"\ue8bf",
"shop":"\ue609"
}
<template>
<view :class="[ 'uni-row', typeClass , justifyClass, alignClass, ]" :style="{
marginLeft:`${Number(marginValue)}rpx`,
marginRight:`${Number(marginValue)}rpx`,
}">
<slot></slot>
</view>
</template>
<script>
const ComponentClass = 'uni-row';
const modifierSeparator = '--';
/**
* Row 布局-行
* @description 流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。
* @tutorial https://ext.dcloud.net.cn/plugin?id=3958
*
* @property {gutter} type = Number 栅格间隔
* @property {justify} type = String flex 布局下的水平排列方式
* 可选 start/end/center/space-around/space-between start
* 默认值 start
* @property {align} type = String flex 布局下的垂直排列方式
* 可选 top/middle/bottom
* 默认值 top
* @property {width} type = String|Number nvue下需要自行配置宽度用于计算
* 默认值 750
*/
export default {
name: 'uniRow',
componentName: 'uniRow',
// #ifdef MP-WEIXIN
options: {
virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现,可使用flex布局
},
// #endif
props: {
type: String,
gutter: Number,
justify: {
type: String,
default: 'start'
},
align: {
type: String,
default: 'top'
},
// nvue如果使用span等属性,需要配置宽度
width: {
type: [String, Number],
default: 750
}
},
created() {
// #ifdef APP-NVUE
this.type = 'flex';
// #endif
},
computed: {
marginValue() {
// #ifndef APP-NVUE
if (this.gutter) {
return -(this.gutter / 2);
}
// #endif
return 0;
},
typeClass() {
return this.type === 'flex' ? `${ComponentClass + modifierSeparator}flex` : '';
},
justifyClass() {
return this.justify !== 'start' ? `${ComponentClass + modifierSeparator}flex-justify-${this.justify}` : ''
},
alignClass() {
return this.align !== 'top' ? `${ComponentClass + modifierSeparator}flex-align-${this.align}` : ''
}
}
};
</script>
<style lang="scss">
$layout-namespace: ".uni-";
$row:$layout-namespace+"row";
$modifier-separator: "--";
@mixin utils-clearfix {
$selector: &;
@at-root {
/* #ifndef APP-NVUE */
#{$selector}::before,
#{$selector}::after {
display: table;
content: "";
}
#{$selector}::after {
clear: both;
}
/* #endif */
}
}
@mixin utils-flex ($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: $direction;
}
@mixin set-flex($state) {
@at-root &-#{$state} {
@content
}
}
#{$row} {
position: relative;
flex-direction: row;
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
// 非nvue使用float布局
@include utils-clearfix;
// 在QQ、字节、百度小程序平台,编译后使用shadow dom,不可使用flex布局,使用float
@at-root {
/* #ifndef MP-QQ || MP-TOUTIAO || MP-BAIDU */
&#{$modifier-separator}flex {
@include utils-flex;
flex-wrap: wrap;
flex: 1;
&:before,
&:after {
/* #ifndef APP-NVUE */
display: none;
/* #endif */
}
@include set-flex(justify-center) {
justify-content: center;
}
@include set-flex(justify-end) {
justify-content: flex-end;
}
@include set-flex(justify-space-between) {
justify-content: space-between;
}
@include set-flex(justify-space-around) {
justify-content: space-around;
}
@include set-flex(align-middle) {
align-items: center;
}
@include set-flex(align-bottom) {
align-items: flex-end;
}
}
/* #endif */
}
}
// 字节、QQ配置后不生效
// 此处用法无法使用scoped
/* #ifdef MP-WEIXIN || MP-TOUTIAO || MP-QQ */
:host {
display: block;
}
/* #endif */
</style>
<template>
<view class="page dataease-main">
<uni-list>
<uni-list-item class="person-title" :title="banner.title" />
</uni-list>
<uni-nav-bar :title="banner.title" >
<view slot="right">
<uni-row class="demo-uni-row" >
<uni-col :span="12" @click="enshrine">
<uni-icons v-if="hasStar" type="star-filled" size="18" color="#007AFF"></uni-icons>
<uni-icons v-else type="star" size="18" color="#999"></uni-icons>
</uni-col>
<uni-col :span="12" @click="refresh" style="margin: 0 10rpx;">
<uni-icons type="reload" size="18" color="#999"></uni-icons>
</uni-col>
</uni-row>
</view>
</uni-nav-bar>
<view class="article-content">
<view v-if="url">
<web-view
......@@ -17,19 +29,7 @@
<ad v-if="htmlNodes.length > 0" unit-id="adunit-01b7a010bf53d74e"></ad>
<!-- #endif -->
<view class="card-actions">
<view v-if="banner.index === 2" class="card-actions-item">
</view>
<view v-else class="card-actions-item" @click="enshrine">
<uni-icons v-if="hasStar" type="star-filled" size="18" color="#007AFF"></uni-icons>
<uni-icons v-else type="star" size="18" color="#999"></uni-icons>
</view>
<view class="card-actions-item" @click="refresh">
<uni-icons type="reload" size="18" color="#999"></uni-icons>
</view>
</view>
</view>
</template>
......@@ -271,7 +271,7 @@
}
.article-content {
height: calc(100vh - 110px);
height: 100vh;
margin: 5px 0;
background: #ffffff;
}
......
## 1.3.5(2022-01-24)
- 优化 size 属性可以传入不带单位的字符串数值
## 1.3.4(2022-01-24)
- 优化 size 支持其他单位
## 1.3.3(2022-01-17)
- 修复 nvue 有些图标不显示的bug,兼容老版本图标
## 1.3.2(2021-12-01)
- 优化 示例可复制图标名称
## 1.3.1(2021-11-23)
- 优化 兼容旧组件 type 值
## 1.3.0(2021-11-19)
- 新增 更多图标
- 优化 自定义图标使用方式
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
## 1.1.7(2021-11-08)
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.5(2021-05-12)
- 新增 组件示例地址
## 1.1.4(2021-02-05)
- 调整为uni_modules目录规范
<template>
<!-- #ifdef APP-NVUE -->
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" @click="_onClick">{{unicode}}</text>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
<!-- #endif -->
</template>
<script>
import icons from './icons.js';
const getVal = (val) => {
const reg = /^[0-9]*$/g
return (typeof val === 'number' || reg.test(val) )? val + 'px' : val;
}
// #ifdef APP-NVUE
var domModule = weex.requireModule('dom');
import iconUrl from './uniicons.ttf'
domModule.addRule('fontFace', {
'fontFamily': "uniicons",
'src': "url('"+iconUrl+"')"
});
// #endif
/**
* Icons 图标
* @description 用于展示 icons 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: 'UniIcons',
emits:['click'],
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
customPrefix:{
type: String,
default: ''
}
},
data() {
return {
icons: icons.glyphs
}
},
computed:{
unicode(){
let code = this.icons.find(v=>v.font_class === this.type)
if(code){
return unescape(`%u${code.unicode}`)
}
return ''
},
iconSize(){
return getVal(this.size)
}
},
methods: {
_onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss">
/* #ifndef APP-NVUE */
@import './uniicons.css';
@font-face {
font-family: uniicons;
src: url('./uniicons.ttf') format('truetype');
}
/* #endif */
.uni-icons {
font-family: uniicons;
text-decoration: none;
text-align: center;
}
</style>
.uniui-color:before {
content: "\e6cf";
}
.uniui-wallet:before {
content: "\e6b1";
}
.uniui-settings-filled:before {
content: "\e6ce";
}
.uniui-auth-filled:before {
content: "\e6cc";
}
.uniui-shop-filled:before {
content: "\e6cd";
}
.uniui-staff-filled:before {
content: "\e6cb";
}
.uniui-vip-filled:before {
content: "\e6c6";
}
.uniui-plus-filled:before {
content: "\e6c7";
}
.uniui-folder-add-filled:before {
content: "\e6c8";
}
.uniui-color-filled:before {
content: "\e6c9";
}
.uniui-tune-filled:before {
content: "\e6ca";
}
.uniui-calendar-filled:before {
content: "\e6c0";
}
.uniui-notification-filled:before {
content: "\e6c1";
}
.uniui-wallet-filled:before {
content: "\e6c2";
}
.uniui-medal-filled:before {
content: "\e6c3";
}
.uniui-gift-filled:before {
content: "\e6c4";
}
.uniui-fire-filled:before {
content: "\e6c5";
}
.uniui-refreshempty:before {
content: "\e6bf";
}
.uniui-location-filled:before {
content: "\e6af";
}
.uniui-person-filled:before {
content: "\e69d";
}
.uniui-personadd-filled:before {
content: "\e698";
}
.uniui-back:before {
content: "\e6b9";
}
.uniui-forward:before {
content: "\e6ba";
}
.uniui-arrow-right:before {
content: "\e6bb";
}
.uniui-arrowthinright:before {
content: "\e6bb";
}
.uniui-arrow-left:before {
content: "\e6bc";
}
.uniui-arrowthinleft:before {
content: "\e6bc";
}
.uniui-arrow-up:before {
content: "\e6bd";
}
.uniui-arrowthinup:before {
content: "\e6bd";
}
.uniui-arrow-down:before {
content: "\e6be";
}
.uniui-arrowthindown:before {
content: "\e6be";
}
.uniui-bottom:before {
content: "\e6b8";
}
.uniui-arrowdown:before {
content: "\e6b8";
}
.uniui-right:before {
content: "\e6b5";
}
.uniui-arrowright:before {
content: "\e6b5";
}
.uniui-top:before {
content: "\e6b6";
}
.uniui-arrowup:before {
content: "\e6b6";
}
.uniui-left:before {
content: "\e6b7";
}
.uniui-arrowleft:before {
content: "\e6b7";
}
.uniui-eye:before {
content: "\e651";
}
.uniui-eye-filled:before {
content: "\e66a";
}
.uniui-eye-slash:before {
content: "\e6b3";
}
.uniui-eye-slash-filled:before {
content: "\e6b4";
}
.uniui-info-filled:before {
content: "\e649";
}
.uniui-reload:before {
content: "\e6b2";
}
.uniui-micoff-filled:before {
content: "\e6b0";
}
.uniui-map-pin-ellipse:before {
content: "\e6ac";
}
.uniui-map-pin:before {
content: "\e6ad";
}
.uniui-location:before {
content: "\e6ae";
}
.uniui-starhalf:before {
content: "\e683";
}
.uniui-star:before {
content: "\e688";
}
.uniui-star-filled:before {
content: "\e68f";
}
.uniui-calendar:before {
content: "\e6a0";
}
.uniui-fire:before {
content: "\e6a1";
}
.uniui-medal:before {
content: "\e6a2";
}
.uniui-font:before {
content: "\e6a3";
}
.uniui-gift:before {
content: "\e6a4";
}
.uniui-link:before {
content: "\e6a5";
}
.uniui-notification:before {
content: "\e6a6";
}
.uniui-staff:before {
content: "\e6a7";
}
.uniui-vip:before {
content: "\e6a8";
}
.uniui-folder-add:before {
content: "\e6a9";
}
.uniui-tune:before {
content: "\e6aa";
}
.uniui-auth:before {
content: "\e6ab";
}
.uniui-person:before {
content: "\e699";
}
.uniui-email-filled:before {
content: "\e69a";
}
.uniui-phone-filled:before {
content: "\e69b";
}
.uniui-phone:before {
content: "\e69c";
}
.uniui-email:before {
content: "\e69e";
}
.uniui-personadd:before {
content: "\e69f";
}
.uniui-chatboxes-filled:before {
content: "\e692";
}
.uniui-contact:before {
content: "\e693";
}
.uniui-chatbubble-filled:before {
content: "\e694";
}
.uniui-contact-filled:before {
content: "\e695";
}
.uniui-chatboxes:before {
content: "\e696";
}
.uniui-chatbubble:before {
content: "\e697";
}
.uniui-upload-filled:before {
content: "\e68e";
}
.uniui-upload:before {
content: "\e690";
}
.uniui-weixin:before {
content: "\e691";
}
.uniui-compose:before {
content: "\e67f";
}
.uniui-qq:before {
content: "\e680";
}
.uniui-download-filled:before {
content: "\e681";
}
.uniui-pyq:before {
content: "\e682";
}
.uniui-sound:before {
content: "\e684";
}
.uniui-trash-filled:before {
content: "\e685";
}
.uniui-sound-filled:before {
content: "\e686";
}
.uniui-trash:before {
content: "\e687";
}
.uniui-videocam-filled:before {
content: "\e689";
}
.uniui-spinner-cycle:before {
content: "\e68a";
}
.uniui-weibo:before {
content: "\e68b";
}
.uniui-videocam:before {
content: "\e68c";
}
.uniui-download:before {
content: "\e68d";
}
.uniui-help:before {
content: "\e679";
}
.uniui-navigate-filled:before {
content: "\e67a";
}
.uniui-plusempty:before {
content: "\e67b";
}
.uniui-smallcircle:before {
content: "\e67c";
}
.uniui-minus-filled:before {
content: "\e67d";
}
.uniui-micoff:before {
content: "\e67e";
}
.uniui-closeempty:before {
content: "\e66c";
}
.uniui-clear:before {
content: "\e66d";
}
.uniui-navigate:before {
content: "\e66e";
}
.uniui-minus:before {
content: "\e66f";
}
.uniui-image:before {
content: "\e670";
}
.uniui-mic:before {
content: "\e671";
}
.uniui-paperplane:before {
content: "\e672";
}
.uniui-close:before {
content: "\e673";
}
.uniui-help-filled:before {
content: "\e674";
}
.uniui-paperplane-filled:before {
content: "\e675";
}
.uniui-plus:before {
content: "\e676";
}
.uniui-mic-filled:before {
content: "\e677";
}
.uniui-image-filled:before {
content: "\e678";
}
.uniui-locked-filled:before {
content: "\e668";
}
.uniui-info:before {
content: "\e669";
}
.uniui-locked:before {
content: "\e66b";
}
.uniui-camera-filled:before {
content: "\e658";
}
.uniui-chat-filled:before {
content: "\e659";
}
.uniui-camera:before {
content: "\e65a";
}
.uniui-circle:before {
content: "\e65b";
}
.uniui-checkmarkempty:before {
content: "\e65c";
}
.uniui-chat:before {
content: "\e65d";
}
.uniui-circle-filled:before {
content: "\e65e";
}
.uniui-flag:before {
content: "\e65f";
}
.uniui-flag-filled:before {
content: "\e660";
}
.uniui-gear-filled:before {
content: "\e661";
}
.uniui-home:before {
content: "\e662";
}
.uniui-home-filled:before {
content: "\e663";
}
.uniui-gear:before {
content: "\e664";
}
.uniui-smallcircle-filled:before {
content: "\e665";
}
.uniui-map-filled:before {
content: "\e666";
}
.uniui-map:before {
content: "\e667";
}
.uniui-refresh-filled:before {
content: "\e656";
}
.uniui-refresh:before {
content: "\e657";
}
.uniui-cloud-upload:before {
content: "\e645";
}
.uniui-cloud-download-filled:before {
content: "\e646";
}
.uniui-cloud-download:before {
content: "\e647";
}
.uniui-cloud-upload-filled:before {
content: "\e648";
}
.uniui-redo:before {
content: "\e64a";
}
.uniui-images-filled:before {
content: "\e64b";
}
.uniui-undo-filled:before {
content: "\e64c";
}
.uniui-more:before {
content: "\e64d";
}
.uniui-more-filled:before {
content: "\e64e";
}
.uniui-undo:before {
content: "\e64f";
}
.uniui-images:before {
content: "\e650";
}
.uniui-paperclip:before {
content: "\e652";
}
.uniui-settings:before {
content: "\e653";
}
.uniui-search:before {
content: "\e654";
}
.uniui-redo-filled:before {
content: "\e655";
}
.uniui-list:before {
content: "\e644";
}
.uniui-mail-open-filled:before {
content: "\e63a";
}
.uniui-hand-down-filled:before {
content: "\e63c";
}
.uniui-hand-down:before {
content: "\e63d";
}
.uniui-hand-up-filled:before {
content: "\e63e";
}
.uniui-hand-up:before {
content: "\e63f";
}
.uniui-heart-filled:before {
content: "\e641";
}
.uniui-mail-open:before {
content: "\e643";
}
.uniui-heart:before {
content: "\e639";
}
.uniui-loop:before {
content: "\e633";
}
.uniui-pulldown:before {
content: "\e632";
}
.uniui-scan:before {
content: "\e62a";
}
.uniui-bars:before {
content: "\e627";
}
.uniui-cart-filled:before {
content: "\e629";
}
.uniui-checkbox:before {
content: "\e62b";
}
.uniui-checkbox-filled:before {
content: "\e62c";
}
.uniui-shop:before {
content: "\e62f";
}
.uniui-headphones:before {
content: "\e630";
}
.uniui-cart:before {
content: "\e631";
}
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论