Merge branch 'dev' of https://github.com/fit2cloudrd/metersphere-server into dev
This commit is contained in:
commit
98379ac9e1
|
@ -0,0 +1,27 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class LoadTestReportDetail implements Serializable {
|
||||
private String reportId;
|
||||
|
||||
private String content;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public String getReportId() {
|
||||
return reportId;
|
||||
}
|
||||
|
||||
public void setReportId(String reportId) {
|
||||
this.reportId = reportId == null ? null : reportId.trim();
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content == null ? null : content.trim();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,270 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LoadTestReportDetailExample {
|
||||
protected String orderByClause;
|
||||
|
||||
protected boolean distinct;
|
||||
|
||||
protected List<Criteria> oredCriteria;
|
||||
|
||||
public LoadTestReportDetailExample() {
|
||||
oredCriteria = new ArrayList<Criteria>();
|
||||
}
|
||||
|
||||
public void setOrderByClause(String orderByClause) {
|
||||
this.orderByClause = orderByClause;
|
||||
}
|
||||
|
||||
public String getOrderByClause() {
|
||||
return orderByClause;
|
||||
}
|
||||
|
||||
public void setDistinct(boolean distinct) {
|
||||
this.distinct = distinct;
|
||||
}
|
||||
|
||||
public boolean isDistinct() {
|
||||
return distinct;
|
||||
}
|
||||
|
||||
public List<Criteria> getOredCriteria() {
|
||||
return oredCriteria;
|
||||
}
|
||||
|
||||
public void or(Criteria criteria) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
|
||||
public Criteria or() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
oredCriteria.add(criteria);
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public Criteria createCriteria() {
|
||||
Criteria criteria = createCriteriaInternal();
|
||||
if (oredCriteria.size() == 0) {
|
||||
oredCriteria.add(criteria);
|
||||
}
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected Criteria createCriteriaInternal() {
|
||||
Criteria criteria = new Criteria();
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
oredCriteria.clear();
|
||||
orderByClause = null;
|
||||
distinct = false;
|
||||
}
|
||||
|
||||
protected abstract static class GeneratedCriteria {
|
||||
protected List<Criterion> criteria;
|
||||
|
||||
protected GeneratedCriteria() {
|
||||
super();
|
||||
criteria = new ArrayList<Criterion>();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return criteria.size() > 0;
|
||||
}
|
||||
|
||||
public List<Criterion> getAllCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public List<Criterion> getCriteria() {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition) {
|
||||
if (condition == null) {
|
||||
throw new RuntimeException("Value for condition cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value, String property) {
|
||||
if (value == null) {
|
||||
throw new RuntimeException("Value for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value));
|
||||
}
|
||||
|
||||
protected void addCriterion(String condition, Object value1, Object value2, String property) {
|
||||
if (value1 == null || value2 == null) {
|
||||
throw new RuntimeException("Between values for " + property + " cannot be null");
|
||||
}
|
||||
criteria.add(new Criterion(condition, value1, value2));
|
||||
}
|
||||
|
||||
public Criteria andReportIdIsNull() {
|
||||
addCriterion("report_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdIsNotNull() {
|
||||
addCriterion("report_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdEqualTo(String value) {
|
||||
addCriterion("report_id =", value, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdNotEqualTo(String value) {
|
||||
addCriterion("report_id <>", value, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdGreaterThan(String value) {
|
||||
addCriterion("report_id >", value, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("report_id >=", value, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdLessThan(String value) {
|
||||
addCriterion("report_id <", value, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdLessThanOrEqualTo(String value) {
|
||||
addCriterion("report_id <=", value, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdLike(String value) {
|
||||
addCriterion("report_id like", value, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdNotLike(String value) {
|
||||
addCriterion("report_id not like", value, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdIn(List<String> values) {
|
||||
addCriterion("report_id in", values, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdNotIn(List<String> values) {
|
||||
addCriterion("report_id not in", values, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdBetween(String value1, String value2) {
|
||||
addCriterion("report_id between", value1, value2, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andReportIdNotBetween(String value1, String value2) {
|
||||
addCriterion("report_id not between", value1, value2, "reportId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
||||
protected Criteria() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criterion {
|
||||
private String condition;
|
||||
|
||||
private Object value;
|
||||
|
||||
private Object secondValue;
|
||||
|
||||
private boolean noValue;
|
||||
|
||||
private boolean singleValue;
|
||||
|
||||
private boolean betweenValue;
|
||||
|
||||
private boolean listValue;
|
||||
|
||||
private String typeHandler;
|
||||
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object getSecondValue() {
|
||||
return secondValue;
|
||||
}
|
||||
|
||||
public boolean isNoValue() {
|
||||
return noValue;
|
||||
}
|
||||
|
||||
public boolean isSingleValue() {
|
||||
return singleValue;
|
||||
}
|
||||
|
||||
public boolean isBetweenValue() {
|
||||
return betweenValue;
|
||||
}
|
||||
|
||||
public boolean isListValue() {
|
||||
return listValue;
|
||||
}
|
||||
|
||||
public String getTypeHandler() {
|
||||
return typeHandler;
|
||||
}
|
||||
|
||||
protected Criterion(String condition) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.typeHandler = null;
|
||||
this.noValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.typeHandler = typeHandler;
|
||||
if (value instanceof List<?>) {
|
||||
this.listValue = true;
|
||||
} else {
|
||||
this.singleValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value) {
|
||||
this(condition, value, null);
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
|
||||
super();
|
||||
this.condition = condition;
|
||||
this.value = value;
|
||||
this.secondValue = secondValue;
|
||||
this.typeHandler = typeHandler;
|
||||
this.betweenValue = true;
|
||||
}
|
||||
|
||||
protected Criterion(String condition, Object value, Object secondValue) {
|
||||
this(condition, value, secondValue, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package io.metersphere.base.mapper;
|
||||
|
||||
import io.metersphere.base.domain.LoadTestReportDetail;
|
||||
import io.metersphere.base.domain.LoadTestReportDetailExample;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LoadTestReportDetailMapper {
|
||||
long countByExample(LoadTestReportDetailExample example);
|
||||
|
||||
int deleteByExample(LoadTestReportDetailExample example);
|
||||
|
||||
int deleteByPrimaryKey(String reportId);
|
||||
|
||||
int insert(LoadTestReportDetail record);
|
||||
|
||||
int insertSelective(LoadTestReportDetail record);
|
||||
|
||||
List<LoadTestReportDetail> selectByExampleWithBLOBs(LoadTestReportDetailExample example);
|
||||
|
||||
List<LoadTestReportDetail> selectByExample(LoadTestReportDetailExample example);
|
||||
|
||||
LoadTestReportDetail selectByPrimaryKey(String reportId);
|
||||
|
||||
int updateByExampleSelective(@Param("record") LoadTestReportDetail record, @Param("example") LoadTestReportDetailExample example);
|
||||
|
||||
int updateByExampleWithBLOBs(@Param("record") LoadTestReportDetail record, @Param("example") LoadTestReportDetailExample example);
|
||||
|
||||
int updateByExample(@Param("record") LoadTestReportDetail record, @Param("example") LoadTestReportDetailExample example);
|
||||
|
||||
int updateByPrimaryKeySelective(LoadTestReportDetail record);
|
||||
|
||||
int updateByPrimaryKeyWithBLOBs(LoadTestReportDetail record);
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.metersphere.base.mapper.LoadTestReportDetailMapper">
|
||||
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.LoadTestReportDetail">
|
||||
<id column="report_id" jdbcType="VARCHAR" property="reportId" />
|
||||
</resultMap>
|
||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.LoadTestReportDetail">
|
||||
<result column="content" jdbcType="LONGVARCHAR" property="content" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Update_By_Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="example.oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
report_id
|
||||
</sql>
|
||||
<sql id="Blob_Column_List">
|
||||
content
|
||||
</sql>
|
||||
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.LoadTestReportDetailExample" resultMap="ResultMapWithBLOBs">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
,
|
||||
<include refid="Blob_Column_List" />
|
||||
from load_test_report_detail
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.LoadTestReportDetailExample" resultMap="BaseResultMap">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
from load_test_report_detail
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
,
|
||||
<include refid="Blob_Column_List" />
|
||||
from load_test_report_detail
|
||||
where report_id = #{reportId,jdbcType=VARCHAR}
|
||||
</select>
|
||||
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
|
||||
delete from load_test_report_detail
|
||||
where report_id = #{reportId,jdbcType=VARCHAR}
|
||||
</delete>
|
||||
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.LoadTestReportDetailExample">
|
||||
delete from load_test_report_detail
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.LoadTestReportDetail">
|
||||
insert into load_test_report_detail (report_id, content)
|
||||
values (#{reportId,jdbcType=VARCHAR}, #{content,jdbcType=LONGVARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.LoadTestReportDetail">
|
||||
insert into load_test_report_detail
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="reportId != null">
|
||||
report_id,
|
||||
</if>
|
||||
<if test="content != null">
|
||||
content,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="reportId != null">
|
||||
#{reportId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="content != null">
|
||||
#{content,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.LoadTestReportDetailExample" resultType="java.lang.Long">
|
||||
select count(*) from load_test_report_detail
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</select>
|
||||
<update id="updateByExampleSelective" parameterType="map">
|
||||
update load_test_report_detail
|
||||
<set>
|
||||
<if test="record.reportId != null">
|
||||
report_id = #{record.reportId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.content != null">
|
||||
content = #{record.content,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExampleWithBLOBs" parameterType="map">
|
||||
update load_test_report_detail
|
||||
set report_id = #{record.reportId,jdbcType=VARCHAR},
|
||||
content = #{record.content,jdbcType=LONGVARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update load_test_report_detail
|
||||
set report_id = #{record.reportId,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.LoadTestReportDetail">
|
||||
update load_test_report_detail
|
||||
<set>
|
||||
<if test="content != null">
|
||||
content = #{content,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where report_id = #{reportId,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.LoadTestReportDetail">
|
||||
update load_test_report_detail
|
||||
set content = #{content,jdbcType=LONGVARCHAR}
|
||||
where report_id = #{reportId,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -0,0 +1,7 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface ExtLoadTestReportDetailMapper {
|
||||
int appendLine(@Param("reportId") String id, @Param("line") String line);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="io.metersphere.base.mapper.ext.ExtLoadTestReportDetailMapper">
|
||||
<update id="appendLine">
|
||||
UPDATE load_test_report_detail
|
||||
SET content = concat(content, #{line})
|
||||
WHERE report_id = #{reportId}
|
||||
</update>
|
||||
</mapper>
|
|
@ -0,0 +1,5 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
public enum PerformanceTestStatus {
|
||||
Saved, Starting, Running, Completed, Error
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
public enum TestStatus {
|
||||
Starting, Running, Completed, Error
|
||||
}
|
|
@ -4,7 +4,6 @@ import com.github.pagehelper.Page;
|
|||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.controller.request.testplan.*;
|
||||
|
@ -86,10 +85,7 @@ public class PerformanceTestController {
|
|||
|
||||
@PostMapping("/run")
|
||||
public void run(@RequestBody RunTestPlanRequest request) {
|
||||
boolean started = performanceTestService.run(request);
|
||||
if (!started) {
|
||||
MSException.throwException("Start engine error, please check log.");
|
||||
}
|
||||
performanceTestService.run(request);
|
||||
}
|
||||
|
||||
@GetMapping("/file/metadata/{testId}")
|
||||
|
|
|
@ -6,8 +6,8 @@ import com.alibaba.fastjson.JSONObject;
|
|||
import io.metersphere.base.domain.LoadTestWithBLOBs;
|
||||
import io.metersphere.base.domain.TestResource;
|
||||
import io.metersphere.base.domain.TestResourcePool;
|
||||
import io.metersphere.commons.constants.PerformanceTestStatus;
|
||||
import io.metersphere.commons.constants.ResourcePoolTypeEnum;
|
||||
import io.metersphere.commons.constants.TestStatus;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.config.JmeterProperties;
|
||||
|
@ -70,7 +70,7 @@ public abstract class AbstractEngine implements Engine {
|
|||
List<LoadTestWithBLOBs> loadTests = performanceTestService.selectByTestResourcePoolId(loadTest.getTestResourcePoolId());
|
||||
// 使用当前资源池正在运行的测试占用的并发数
|
||||
return loadTests.stream()
|
||||
.filter(t -> TestStatus.Running.name().equals(t.getStatus()))
|
||||
.filter(t -> PerformanceTestStatus.Running.name().equals(t.getStatus()))
|
||||
.map(this::getThreadNum)
|
||||
.reduce(Integer::sum)
|
||||
.orElse(0);
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.engine.EngineContext;
|
|||
import io.metersphere.engine.EngineFactory;
|
||||
import io.metersphere.engine.docker.request.BaseRequest;
|
||||
import io.metersphere.engine.docker.request.TestRequest;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -41,7 +42,7 @@ public class DockerTestEngine extends AbstractEngine {
|
|||
.reduce(Integer::sum)
|
||||
.orElse(0);
|
||||
if (threadNum > totalThreadNum - runningSumThreadNum) {
|
||||
MSException.throwException("Insufficient resources");
|
||||
MSException.throwException(Translator.get("max_thread_insufficient"));
|
||||
}
|
||||
List<Integer> resourceRatio = resourceList.stream()
|
||||
.filter(r -> ResourceStatusEnum.VALID.name().equals(r.getStatus()))
|
||||
|
|
|
@ -15,6 +15,7 @@ import io.metersphere.engine.kubernetes.crds.jmeter.Jmeter;
|
|||
import io.metersphere.engine.kubernetes.crds.jmeter.JmeterSpec;
|
||||
import io.metersphere.engine.kubernetes.provider.ClientCredential;
|
||||
import io.metersphere.engine.kubernetes.provider.KubernetesProvider;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -43,7 +44,7 @@ public class KubernetesTestEngine extends AbstractEngine {
|
|||
Integer maxConcurrency = clientCredential.getMaxConcurrency();
|
||||
// 当前测试需要的并发数大于剩余的并发数报错
|
||||
if (threadNum > maxConcurrency - sumThreadNum) {
|
||||
MSException.throwException("Insufficient resources");
|
||||
MSException.throwException(Translator.get("max_thread_insufficient"));
|
||||
}
|
||||
try {
|
||||
EngineContext context = EngineFactory.createContext(loadTest, threadNum, this.getStartTime(), this.getReportId());
|
||||
|
|
|
@ -24,6 +24,8 @@ import java.util.stream.Collectors;
|
|||
public class JtlResolver {
|
||||
|
||||
private static final Integer ERRORS_TOP_SIZE = 5;
|
||||
private static final String DATE_TIME_PATTERN = "yyyy/MM/dd HH:mm:ss";
|
||||
private static final String TIME_PATTERN = "HH:mm:ss";
|
||||
|
||||
private static List<Metric> resolver(String jtlString) {
|
||||
HeaderColumnNameMappingStrategy<Metric> ms = new HeaderColumnNameMappingStrategy<>();
|
||||
|
@ -102,7 +104,7 @@ public class JtlResolver {
|
|||
String average = decimalFormat.format((float) oneLineElapsedTime / jtlSamplesSize);
|
||||
requestStatistics.setAverage(average);
|
||||
|
||||
/**
|
||||
/*
|
||||
* TP90的计算
|
||||
* 1,把一段时间内全部的请求的响应时间,从小到大排序,获得序列A
|
||||
* 2,总的请求数量,乘以90%,获得90%对应的请求个数C
|
||||
|
@ -121,7 +123,7 @@ public class JtlResolver {
|
|||
requestStatistics.setMax(elapsedList.get(jtlSamplesSize - 1) + "");
|
||||
requestStatistics.setErrors(decimalFormat.format(failSize * 100.0 / jtlSamplesSize) + "%");
|
||||
requestStatistics.setKo(failSize);
|
||||
/**
|
||||
/*
|
||||
* 所有的相同请求的bytes总和 / 1024 / 请求持续运行的时间=sum(bytes)/1024/total time
|
||||
* total time = 最大时间戳 - 最小时间戳 + 最后请求的响应时间
|
||||
*/
|
||||
|
@ -266,20 +268,34 @@ public class JtlResolver {
|
|||
DecimalFormat decimalFormat = new DecimalFormat("0.00");
|
||||
|
||||
List<Metric> totalLineList = JtlResolver.resolver(jtlString);
|
||||
// todo
|
||||
List<Metric> totalLineList2 = JtlResolver.resolver(jtlString);
|
||||
// 时间戳转时间
|
||||
for (Metric metric : totalLineList2) {
|
||||
metric.setTimestamp(stampToDate(DATE_TIME_PATTERN, metric.getTimestamp()));
|
||||
}
|
||||
|
||||
Map<String, List<Metric>> collect2 = Objects.requireNonNull(totalLineList2).stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
||||
List<Map.Entry<String, List<Metric>>> entries = new ArrayList<>(collect2.entrySet());
|
||||
int maxUsers = 0;
|
||||
for (Map.Entry<String, List<Metric>> entry : entries) {
|
||||
List<Metric> metrics = entry.getValue();
|
||||
Map<String, List<Metric>> metricsMap = metrics.stream().collect(Collectors.groupingBy(Metric::getThreadName));
|
||||
if (metricsMap.size() > maxUsers) {
|
||||
maxUsers = metricsMap.size();
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, List<Metric>> collect = totalLineList.stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
||||
Iterator<Map.Entry<String, List<Metric>>> iterator = collect.entrySet().iterator();
|
||||
|
||||
int maxUsers = 0, totalElapsed = 0;
|
||||
int totalElapsed = 0;
|
||||
float totalBytes = 0f;
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, List<Metric>> entry = iterator.next();
|
||||
List<Metric> metricList = entry.getValue();
|
||||
|
||||
if (metricList.size() > maxUsers) {
|
||||
maxUsers = metricList.size();
|
||||
}
|
||||
|
||||
for (Metric metric : metricList) {
|
||||
String elapsed = metric.getElapsed();
|
||||
totalElapsed += Integer.parseInt(elapsed);
|
||||
|
@ -323,7 +339,7 @@ public class JtlResolver {
|
|||
|
||||
if (totalMetricList != null) {
|
||||
for (Metric metric : totalMetricList) {
|
||||
metric.setTimestamp(stampToDate(metric.getTimestamp()));
|
||||
metric.setTimestamp(stampToDate(DATE_TIME_PATTERN, metric.getTimestamp()));
|
||||
}
|
||||
}
|
||||
Map<String, List<Metric>> collect = Objects.requireNonNull(totalMetricList).stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
||||
|
@ -376,7 +392,7 @@ public class JtlResolver {
|
|||
List<Metric> totalMetricList = JtlResolver.resolver(jtlString);
|
||||
|
||||
totalMetricList.forEach(metric -> {
|
||||
metric.setTimestamp(stampToDate(metric.getTimestamp()));
|
||||
metric.setTimestamp(stampToDate(DATE_TIME_PATTERN, metric.getTimestamp()));
|
||||
});
|
||||
|
||||
Map<String, List<Metric>> metricMap = totalMetricList.stream().collect(Collectors.groupingBy(Metric::getTimestamp));
|
||||
|
@ -426,6 +442,11 @@ public class JtlResolver {
|
|||
reportTimeInfo.setStartTime(startTime);
|
||||
reportTimeInfo.setEndTime(endTime);
|
||||
|
||||
Date startDate = new Date(Long.parseLong(startTimeStamp));
|
||||
Date endDate = new Date(Long.parseLong(endTimeStamp));
|
||||
long timestamp = endDate.getTime() - startDate.getTime();
|
||||
reportTimeInfo.setDuration(String.valueOf(timestamp*1.0 / 1000 / 60));
|
||||
|
||||
// todo 时间问题
|
||||
long seconds = Duration.between(Instant.ofEpochMilli(Long.parseLong(startTimeStamp)), Instant.ofEpochMilli(Long.parseLong(endTimeStamp))).getSeconds();
|
||||
reportTimeInfo.setDuration(String.valueOf(seconds));
|
||||
|
@ -433,11 +454,10 @@ public class JtlResolver {
|
|||
return reportTimeInfo;
|
||||
}
|
||||
|
||||
private static String stampToDate(String timeStamp) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
long lt = Long.parseLong(timeStamp);
|
||||
Date date = new Date(lt);
|
||||
return simpleDateFormat.format(date);
|
||||
private static String stampToDate(String pattern, String timeStamp) {
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
|
||||
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(timeStamp)), ZoneId.systemDefault());
|
||||
return localDateTime.format(dateTimeFormatter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -445,8 +465,8 @@ public class JtlResolver {
|
|||
* @return "HH:mm:ss"
|
||||
*/
|
||||
private static String formatDate(String dateString) throws ParseException {
|
||||
SimpleDateFormat before = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
SimpleDateFormat after = new SimpleDateFormat("HH:mm:ss");
|
||||
SimpleDateFormat before = new SimpleDateFormat(DATE_TIME_PATTERN);
|
||||
SimpleDateFormat after = new SimpleDateFormat(TIME_PATTERN);
|
||||
return after.format(before.parse(dateString));
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,10 @@ package io.metersphere.service;
|
|||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtLoadTestMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtLoadTestReportDetailMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
|
||||
import io.metersphere.commons.constants.FileType;
|
||||
import io.metersphere.commons.constants.TestStatus;
|
||||
import io.metersphere.commons.constants.PerformanceTestStatus;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.controller.request.testplan.*;
|
||||
|
@ -48,6 +49,10 @@ public class PerformanceTestService {
|
|||
private LoadTestReportMapper loadTestReportMapper;
|
||||
@Resource
|
||||
private ExtLoadTestReportMapper extLoadTestReportMapper;
|
||||
@Resource
|
||||
private LoadTestReportDetailMapper loadTestReportDetailMapper;
|
||||
@Resource
|
||||
private ExtLoadTestReportDetailMapper extLoadTestReportDetailMapper;
|
||||
|
||||
public List<LoadTestDTO> list(QueryTestPlanRequest request) {
|
||||
return extLoadTestMapper.list(request);
|
||||
|
@ -93,6 +98,7 @@ public class PerformanceTestService {
|
|||
loadTest.setTestResourcePoolId(request.getTestResourcePoolId());
|
||||
loadTest.setLoadConfiguration(request.getLoadConfiguration());
|
||||
loadTest.setAdvancedConfiguration(request.getAdvancedConfiguration());
|
||||
loadTest.setStatus(PerformanceTestStatus.Saved.name());
|
||||
loadTestMapper.insert(loadTest);
|
||||
return loadTest;
|
||||
}
|
||||
|
@ -158,19 +164,22 @@ public class PerformanceTestService {
|
|||
loadTest.setLoadConfiguration(request.getLoadConfiguration());
|
||||
loadTest.setAdvancedConfiguration(request.getAdvancedConfiguration());
|
||||
loadTest.setTestResourcePoolId(request.getTestResourcePoolId());
|
||||
// todo 修改 load_test 的时候排除状态,这里存在修改了 Running 的测试状态的风险
|
||||
// loadTest.setStatus(PerformanceTestStatus.Saved.name());
|
||||
loadTestMapper.updateByPrimaryKeySelective(loadTest);
|
||||
}
|
||||
|
||||
return request.getId();
|
||||
}
|
||||
|
||||
public boolean run(RunTestPlanRequest request) {
|
||||
@Transactional(noRollbackFor = MSException.class)// 保存失败的信息
|
||||
public void run(RunTestPlanRequest request) {
|
||||
final LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(request.getId());
|
||||
if (loadTest == null) {
|
||||
MSException.throwException(Translator.get("run_load_test_not_found") + request.getId());
|
||||
}
|
||||
|
||||
if (StringUtils.equalsAny(loadTest.getStatus(), TestStatus.Running.name(), TestStatus.Starting.name())) {
|
||||
if (StringUtils.equalsAny(loadTest.getStatus(), PerformanceTestStatus.Running.name(), PerformanceTestStatus.Starting.name())) {
|
||||
MSException.throwException(Translator.get("load_test_is_running"));
|
||||
}
|
||||
|
||||
|
@ -181,12 +190,12 @@ public class PerformanceTestService {
|
|||
MSException.throwException(String.format("Test cannot be run,test ID:%s", request.getId()));
|
||||
}
|
||||
|
||||
return startEngine(loadTest, engine);
|
||||
startEngine(loadTest, engine);
|
||||
|
||||
// todo:通过调用stop方法能够停止正在运行的engine,但是如果部署了多个backend实例,页面发送的停止请求如何定位到具体的engine
|
||||
}
|
||||
|
||||
private boolean startEngine(LoadTestWithBLOBs loadTest, Engine engine) {
|
||||
private void startEngine(LoadTestWithBLOBs loadTest, Engine engine) {
|
||||
LoadTestReportWithBLOBs testReport = new LoadTestReportWithBLOBs();
|
||||
testReport.setId(engine.getReportId());
|
||||
testReport.setCreateTime(engine.getStartTime());
|
||||
|
@ -194,31 +203,32 @@ public class PerformanceTestService {
|
|||
testReport.setTestId(loadTest.getId());
|
||||
testReport.setName(loadTest.getName());
|
||||
// 启动测试
|
||||
boolean started = true;
|
||||
|
||||
try {
|
||||
engine.start();
|
||||
// 标记running状态
|
||||
loadTest.setStatus(TestStatus.Starting.name());
|
||||
// 启动正常修改状态 starting
|
||||
loadTest.setStatus(PerformanceTestStatus.Starting.name());
|
||||
loadTestMapper.updateByPrimaryKeySelective(loadTest);
|
||||
|
||||
// 启动正常插入 report
|
||||
testReport.setContent(HEADERS);
|
||||
testReport.setStatus(TestStatus.Starting.name());
|
||||
testReport.setStatus(PerformanceTestStatus.Starting.name());
|
||||
loadTestReportMapper.insertSelective(testReport);
|
||||
|
||||
LoadTestReportDetail reportDetail = new LoadTestReportDetail();
|
||||
reportDetail.setContent(HEADERS);
|
||||
reportDetail.setReportId(testReport.getId());
|
||||
loadTestReportDetailMapper.insertSelective(reportDetail);
|
||||
// append \n
|
||||
extLoadTestReportMapper.appendLine(testReport.getId(), "\n");
|
||||
|
||||
} catch (Exception e) {
|
||||
// append \n
|
||||
extLoadTestReportDetailMapper.appendLine(testReport.getId(), "\n");
|
||||
} catch (MSException e) {
|
||||
LogUtil.error(e);
|
||||
started = false;
|
||||
|
||||
loadTest.setStatus(TestStatus.Error.name());
|
||||
loadTest.setStatus(PerformanceTestStatus.Error.name());
|
||||
loadTest.setDescription(e.getMessage());
|
||||
loadTestMapper.updateByPrimaryKeySelective(loadTest);
|
||||
//
|
||||
testReport.setStatus(TestStatus.Error.name());
|
||||
testReport.setDescription(e.getMessage());
|
||||
loadTestReportMapper.insertSelective(testReport);
|
||||
throw e;
|
||||
}
|
||||
return started;
|
||||
}
|
||||
|
||||
public List<LoadTestDTO> recentTestPlans(QueryTestPlanRequest request) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import io.metersphere.base.domain.LoadTestReportExample;
|
|||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||
import io.metersphere.base.mapper.LoadTestReportMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
|
||||
import io.metersphere.commons.constants.TestStatus;
|
||||
import io.metersphere.commons.constants.PerformanceTestStatus;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.controller.request.ReportRequest;
|
||||
import io.metersphere.dto.ReportDTO;
|
||||
|
@ -112,9 +112,9 @@ public class ReportService {
|
|||
public void checkReportStatus(String reportId) {
|
||||
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
String reportStatus = loadTestReport.getStatus();
|
||||
if (StringUtils.equals(TestStatus.Running.name(), reportStatus)) {
|
||||
if (StringUtils.equals(PerformanceTestStatus.Running.name(), reportStatus)) {
|
||||
MSException.throwException("Reporting in progress...");
|
||||
} else if (StringUtils.equals(TestStatus.Error.name(), reportStatus)) {
|
||||
} else if (StringUtils.equals(PerformanceTestStatus.Error.name(), reportStatus)) {
|
||||
MSException.throwException("Report generation error!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,15 @@ CREATE TABLE IF NOT EXISTS `load_test_report` (
|
|||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_bin;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `load_test_report_detail` (
|
||||
`report_id` varchar(50) NOT NULL,
|
||||
`content` longtext,
|
||||
PRIMARY KEY (`report_id`)
|
||||
)
|
||||
ENGINE=InnoDB
|
||||
DEFAULT CHARSET=utf8mb4
|
||||
COLLATE=utf8mb4_bin;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `organization` (
|
||||
`id` varchar(50) NOT NULL COMMENT 'Organization ID',
|
||||
`name` varchar(64) NOT NULL COMMENT 'Organization name',
|
||||
|
|
|
@ -18,5 +18,6 @@
|
|||
"no_nodes_message": "No node message",
|
||||
"duplicate_node_ip": "Duplicate IPs",
|
||||
"only_one_k8s": "Only one K8s can be added",
|
||||
"organization_id_is_null": "Organization ID cannot be null"
|
||||
"organization_id_is_null": "Organization ID cannot be null",
|
||||
"max_thread_insufficient": "The number of concurrent users exceeds"
|
||||
}
|
|
@ -18,5 +18,6 @@
|
|||
"no_nodes_message": "没有节点信息",
|
||||
"duplicate_node_ip": "节点 IP 重复",
|
||||
"only_one_k8s": "只能添加一个 K8s",
|
||||
"organization_id_is_null": "组织 ID 不能为空"
|
||||
"organization_id_is_null": "组织 ID 不能为空",
|
||||
"max_thread_insufficient": "并发用户数超额"
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package io.metersphere;
|
||||
|
||||
import com.opencsv.bean.CsvToBean;
|
||||
import com.opencsv.bean.CsvToBeanBuilder;
|
||||
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
|
||||
import io.metersphere.base.domain.LoadTestReportDetail;
|
||||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||
import io.metersphere.base.mapper.LoadTestReportDetailMapper;
|
||||
import io.metersphere.base.mapper.LoadTestReportMapper;
|
||||
import io.metersphere.report.base.Metric;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ReportContentTests {
|
||||
@Resource
|
||||
private LoadTestReportDetailMapper loadTestReportDetailMapper;
|
||||
@Resource
|
||||
private LoadTestReportMapper loadTestReportMapper;
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
String reportId = "ba972086-7d74-4f58-99b0-9c014114fd99";
|
||||
LoadTestReportDetail loadTestReportDetail = loadTestReportDetailMapper.selectByPrimaryKey(reportId);
|
||||
LoadTestReportWithBLOBs loadTestReportWithBLOBs = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
|
||||
HeaderColumnNameMappingStrategy<Metric> ms = new HeaderColumnNameMappingStrategy<>();
|
||||
ms.setType(Metric.class);
|
||||
try (Reader reader = new StringReader(loadTestReportDetail.getContent())) {
|
||||
CsvToBean<Metric> cb = new CsvToBeanBuilder<Metric>(reader)
|
||||
.withType(Metric.class)
|
||||
.withSkipLines(0)
|
||||
.withMappingStrategy(ms)
|
||||
.withIgnoreLeadingWhiteSpace(true)
|
||||
.build();
|
||||
System.out.println(cb.parse().size());
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
try (Reader reader = new StringReader(loadTestReportWithBLOBs.getContent())) {
|
||||
CsvToBean<Metric> cb = new CsvToBeanBuilder<Metric>(reader)
|
||||
.withType(Metric.class)
|
||||
.withSkipLines(0)
|
||||
.withMappingStrategy(ms)
|
||||
.withIgnoreLeadingWhiteSpace(true)
|
||||
.build();
|
||||
System.out.println(cb.parse().size());
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,11 +7,11 @@
|
|||
<el-row type="flex" justify="space-between" align="middle">
|
||||
<span class="title">{{$t('commons.test')}}</span>
|
||||
<span class="search">
|
||||
<el-input type="text" size="small" :placeholder="$t('load_test.search_by_name')"
|
||||
prefix-icon="el-icon-search"
|
||||
maxlength="60"
|
||||
v-model="condition" @change="search" clearable/>
|
||||
</span>
|
||||
<el-input type="text" size="small" :placeholder="$t('load_test.search_by_name')"
|
||||
prefix-icon="el-icon-search"
|
||||
maxlength="60"
|
||||
v-model="condition" @change="search" clearable/>
|
||||
</span>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -56,34 +56,21 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
components: {MsTablePagination},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
queryPath: "/api/list",
|
||||
deletePath: "/api/delete",
|
||||
condition: "",
|
||||
projectId: null,
|
||||
|
@ -99,15 +86,15 @@
|
|||
watch: {
|
||||
'$route'(to) {
|
||||
this.projectId = to.params.projectId;
|
||||
this.initTableData();
|
||||
this.search();
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
this.projectId = this.$route.params.projectId;
|
||||
this.initTableData();
|
||||
this.search();
|
||||
},
|
||||
methods: {
|
||||
initTableData() {
|
||||
search() {
|
||||
let param = {
|
||||
name: this.condition,
|
||||
};
|
||||
|
@ -116,26 +103,13 @@
|
|||
param.projectId = this.projectId;
|
||||
}
|
||||
|
||||
this.result = this.$post(this.buildPagePath(this.queryPath), param, response => {
|
||||
let url = "/api/list/" + this.currentPage + "/" + this.pageSize
|
||||
this.result = this.$post(url, param, response => {
|
||||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
});
|
||||
},
|
||||
search() {
|
||||
this.initTableData();
|
||||
},
|
||||
buildPagePath(path) {
|
||||
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.initTableData();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.initTableData();
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val;
|
||||
},
|
||||
|
@ -176,9 +150,5 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.table-page {
|
||||
padding-top: 20px;
|
||||
margin-right: -9px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
TokenKey,
|
||||
WORKSPACE_ID
|
||||
} from '../../../../common/js/constants';
|
||||
import {hasRoles} from "../../../../common/js/utils";
|
||||
import {hasRoles, saveLocalStorage} from "../../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "MsUser",
|
||||
|
@ -136,7 +136,7 @@
|
|||
changeOrg(data) {
|
||||
let orgId = data.id;
|
||||
this.$post("/user/switch/source/org/" + orgId, {}, response => {
|
||||
localStorage.setItem(TokenKey, JSON.stringify(response.data));
|
||||
saveLocalStorage(response);
|
||||
this.$router.push('/');
|
||||
window.location.reload();
|
||||
})
|
||||
|
@ -147,7 +147,7 @@
|
|||
return false;
|
||||
}
|
||||
this.$post("/user/switch/source/ws/" + workspaceId, {}, response => {
|
||||
localStorage.setItem(TokenKey, JSON.stringify(response.data));
|
||||
saveLocalStorage(response);
|
||||
localStorage.setItem("workspace_id", workspaceId);
|
||||
this.$router.push('/');
|
||||
window.location.reload();
|
||||
|
|
|
@ -40,7 +40,9 @@
|
|||
},
|
||||
getRouter: function () {
|
||||
return function (item) {
|
||||
return this.options.router(item);
|
||||
if (this.options.router) {
|
||||
return this.options.router(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<el-row type="flex" justify="end">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="currentPage"
|
||||
:page-sizes="pageSizes"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsTablePagination",
|
||||
props: {
|
||||
page: Object,
|
||||
currentPage: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 5
|
||||
},
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return [5, 10, 20, 50, 100]
|
||||
}
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
change: Function
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange: function (size) {
|
||||
this.$emit('update:pageSize', size)
|
||||
this.change();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.$emit('update:currentPage', current)
|
||||
this.change();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table-page {
|
||||
padding-top: 20px;
|
||||
}
|
||||
</style>
|
|
@ -147,7 +147,9 @@
|
|||
if(data){
|
||||
this.startTime = data.startTime;
|
||||
this.endTime = data.endTime;
|
||||
this.duration = data.duration;
|
||||
let duration = data.duration;
|
||||
this.minutes = Math.floor(duration / 60);
|
||||
this.seconds = duration % 60;
|
||||
}
|
||||
})
|
||||
window.location.reload();
|
||||
|
|
|
@ -53,6 +53,9 @@
|
|||
<el-tag size="mini" type="success" v-else-if="row.status === 'Running'">
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
<el-tag size="mini" type="info" v-else-if="row.status === 'Completed'">
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
<el-tooltip placement="top" v-else-if="row.status === 'Error'" effect="light">
|
||||
<template v-slot:content>
|
||||
<div>{{row.description}}</div>
|
||||
|
@ -61,9 +64,9 @@
|
|||
{{ row.status }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tag size="mini" type="info" v-else>
|
||||
<span v-else>
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
|
@ -75,23 +78,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
|
@ -99,8 +87,11 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
name: "PerformanceTestReport",
|
||||
components: {MsTablePagination},
|
||||
created: function () {
|
||||
this.initTableData();
|
||||
},
|
||||
|
@ -137,14 +128,6 @@
|
|||
buildPagePath(path) {
|
||||
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.initTableData();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.initTableData();
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val;
|
||||
},
|
||||
|
|
|
@ -192,6 +192,7 @@
|
|||
font-size: 20px;
|
||||
color: #8492a6;
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -59,10 +59,10 @@
|
|||
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<chart ref="chart1" :options="loadOption" :autoresize="true"></chart>
|
||||
<chart ref="chart1" :options="loadOption" class="chart-config" :autoresize="true"></chart>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<chart ref="chart2" :options="resOption" :autoresize="true"></chart>
|
||||
<chart ref="chart2" :options="resOption" class="chart-config" :autoresize="true"></chart>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
@ -96,6 +96,10 @@
|
|||
})
|
||||
this.$get("/performance/report/content/load_chart/" + this.id, res => {
|
||||
let data = res.data;
|
||||
let userList = data.filter(m => m.groupName === "users").map(m => m.yAxis);
|
||||
let hitsList = data.filter(m => m.groupName === "hits").map(m => m.yAxis);
|
||||
let userMax = this._getChartMax(userList);
|
||||
let hitsMax = this._getChartMax(hitsList);
|
||||
let loadOption = {
|
||||
title: {
|
||||
text: 'Load',
|
||||
|
@ -105,30 +109,57 @@
|
|||
color: '#65A2FF'
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {},
|
||||
xAxis: {},
|
||||
yAxis: [{
|
||||
name: 'User',
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: userMax,
|
||||
splitNumber: 5,
|
||||
// interval: 10 / 5
|
||||
interval: userMax / 5
|
||||
},
|
||||
{
|
||||
name: 'Hits/s',
|
||||
type: 'value',
|
||||
splitNumber: 5,
|
||||
min: 0,
|
||||
// max: 5,
|
||||
// interval: 5 / 5
|
||||
max: hitsMax,
|
||||
interval: hitsMax / 5
|
||||
}
|
||||
],
|
||||
series: []
|
||||
};
|
||||
let setting = {
|
||||
series: [
|
||||
{
|
||||
name: 'users',
|
||||
color: '#0CA74A',
|
||||
},
|
||||
{
|
||||
name: 'hits',
|
||||
yAxisIndex: '1',
|
||||
color: '#65A2FF',
|
||||
},
|
||||
{
|
||||
name: 'errors',
|
||||
yAxisIndex: '1',
|
||||
color: '#E6113C',
|
||||
}
|
||||
]
|
||||
}
|
||||
this.loadOption = this.generateOption(loadOption, data);
|
||||
this.loadOption = this.generateOption(loadOption, data, setting);
|
||||
})
|
||||
this.$get("/performance/report/content/res_chart/" + this.id, res => {
|
||||
let data = res.data;
|
||||
let userList = data.filter(m => m.groupName === "users").map(m => m.yAxis);
|
||||
let responseTimeList = data.filter(m => m.groupName === "responseTime").map(m => m.yAxis);
|
||||
let userMax = this._getChartMax(userList);
|
||||
let resMax = this._getChartMax(responseTimeList);
|
||||
let resOption = {
|
||||
title: {
|
||||
text: 'Response Time',
|
||||
|
@ -138,28 +169,55 @@
|
|||
color: '#99743C'
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {},
|
||||
xAxis: {},
|
||||
yAxis: [{
|
||||
name: 'User',
|
||||
type: 'value',
|
||||
splitNumber: 5,
|
||||
min: 0
|
||||
min: 0,
|
||||
max: userMax,
|
||||
interval: userMax / 5
|
||||
},
|
||||
{
|
||||
name: 'Response Time',
|
||||
type: 'value',
|
||||
splitNumber: 5,
|
||||
min: 0
|
||||
min: 0,
|
||||
max: resMax,
|
||||
interval: resMax / 5
|
||||
}
|
||||
],
|
||||
series: []
|
||||
}
|
||||
this.resOption = this.generateOption(resOption, data);
|
||||
let setting = {
|
||||
series: [
|
||||
{
|
||||
name: 'users',
|
||||
color: '#0CA74A',
|
||||
},
|
||||
{
|
||||
name: "responseTime",
|
||||
yAxisIndex: '1',
|
||||
color: '#99743C',
|
||||
}
|
||||
]
|
||||
}
|
||||
this.resOption = this.generateOption(resOption, data, setting);
|
||||
})
|
||||
},
|
||||
generateOption(option, data) {
|
||||
generateOption(option, data, setting) {
|
||||
let chartData = data;
|
||||
let seriesArray = [];
|
||||
for (let set in setting) {
|
||||
if (set === "series") {
|
||||
seriesArray = setting[set];
|
||||
continue;
|
||||
}
|
||||
this.$set(option, set, setting[set]);
|
||||
}
|
||||
let legend = [], series = {}, xAxis = [], seriesData = [];
|
||||
chartData.forEach(item => {
|
||||
if (!xAxis.includes(item.xAxis)) {
|
||||
|
@ -183,11 +241,24 @@
|
|||
type: 'line',
|
||||
data: data
|
||||
};
|
||||
let seriesArrayNames = seriesArray.map(m => m.name);
|
||||
if (seriesArrayNames.includes(name)) {
|
||||
for (let j = 0; j < seriesArray.length; j++) {
|
||||
let seriesObj = seriesArray[j];
|
||||
if (seriesObj['name'] === name) {
|
||||
Object.assign(items, seriesObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
seriesData.push(items);
|
||||
}
|
||||
this.$set(option, "series", seriesData);
|
||||
return option;
|
||||
},
|
||||
_getChartMax(arr) {
|
||||
const max = Math.max(...arr);
|
||||
return Math.ceil(max / 4.5) * 5;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
status() {
|
||||
|
@ -276,4 +347,8 @@
|
|||
border-left-width: 3px;
|
||||
}
|
||||
|
||||
.chart-config {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -46,12 +46,18 @@
|
|||
prop="status"
|
||||
:label="$t('commons.status')">
|
||||
<template v-slot:default="{row}">
|
||||
<el-tag size="mini" type="primary" v-if="row.status === 'Starting'">
|
||||
<el-tag size="mini" type="info" v-if="row.status === 'Saved'">
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
<el-tag size="mini" type="primary" v-else-if="row.status === 'Starting'">
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
<el-tag size="mini" type="success" v-else-if="row.status === 'Running'">
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
<el-tag size="mini" type="info" v-else-if="row.status === 'Completed'">
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
<el-tooltip placement="top" v-else-if="row.status === 'Error'" effect="light">
|
||||
<template v-slot:content>
|
||||
<div>{{row.description}}</div>
|
||||
|
@ -60,9 +66,9 @@
|
|||
{{ row.status }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tag size="mini" type="info" v-else>
|
||||
<span v-else>
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
|
@ -74,30 +80,18 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
components: {MsTablePagination},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
|
@ -146,14 +140,6 @@
|
|||
buildPagePath(path) {
|
||||
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.initTableData();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.initTableData();
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val;
|
||||
},
|
||||
|
|
|
@ -27,23 +27,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="list" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
|
||||
<el-dialog :title="title" :visible.sync="createVisible">
|
||||
|
@ -71,10 +56,11 @@
|
|||
import MsCreateBox from "../settings/CreateBox";
|
||||
import {Message} from "element-ui";
|
||||
import {TokenKey} from "../../../common/js/constants";
|
||||
import MsTablePagination from "../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
name: "MsProject",
|
||||
components: {MsCreateBox},
|
||||
components: {MsCreateBox, MsTablePagination},
|
||||
data() {
|
||||
return {
|
||||
createVisible: false,
|
||||
|
@ -186,24 +172,10 @@
|
|||
this.total = data.itemCount;
|
||||
})
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.list();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.list();
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.table-page {
|
||||
padding-top: 20px;
|
||||
margin-right: -9px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div v-loading="result.loading">
|
||||
<el-card>
|
||||
<template v-slot:header>
|
||||
<div >
|
||||
<div>
|
||||
<el-row type="flex" justify="space-between" align="middle">
|
||||
<span class="title">{{$t('commons.member')}}
|
||||
<ms-create-box :tips="btnTips" :exec="create"/>
|
||||
|
@ -28,34 +28,23 @@
|
|||
</el-table-column>
|
||||
<el-table-column>
|
||||
<template v-slot:default="scope">
|
||||
<el-button @click="edit(scope.row)" onkeydown="return false;" type="primary" icon="el-icon-edit" size="mini" circle/>
|
||||
<el-button @click="del(scope.row)" onkeydown="return false;" type="danger" icon="el-icon-delete" size="mini" circle/>
|
||||
<el-button @click="edit(scope.row)" onkeydown="return false;" type="primary" icon="el-icon-edit" size="mini"
|
||||
circle/>
|
||||
<el-button @click="del(scope.row)" onkeydown="return false;" type="danger" icon="el-icon-delete" size="mini"
|
||||
circle/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
|
||||
<el-dialog :title="$t('member.create')" :visible.sync="createVisible" width="30%" :destroy-on-close="true" @close="closeFunc">
|
||||
<el-dialog :title="$t('member.create')" :visible.sync="createVisible" width="30%" :destroy-on-close="true"
|
||||
@close="closeFunc">
|
||||
<el-form :model="form" ref="form" :rules="rules" label-position="right" label-width="100px" size="small">
|
||||
<el-form-item :label="$t('commons.member')" prop="userIds">
|
||||
<el-select v-model="form.userIds" multiple :placeholder="$t('member.please_choose_member')" class="select-width">
|
||||
<el-select v-model="form.userIds" multiple :placeholder="$t('member.please_choose_member')"
|
||||
class="select-width">
|
||||
<el-option
|
||||
v-for="item in form.userList"
|
||||
:key="item.id"
|
||||
|
@ -85,7 +74,8 @@
|
|||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="$t('member.modify')" :visible.sync="updateVisible" width="30%" :destroy-on-close="true" @close="closeFunc">
|
||||
<el-dialog :title="$t('member.modify')" :visible.sync="updateVisible" width="30%" :destroy-on-close="true"
|
||||
@close="closeFunc">
|
||||
<el-form :model="form" label-position="right" label-width="100px" size="small" ref="updateUserForm">
|
||||
<el-form-item label="ID" prop="id">
|
||||
<el-input v-model="form.id" autocomplete="off" :disabled="true"/>
|
||||
|
@ -123,10 +113,11 @@
|
|||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import {TokenKey} from "../../../../common/js/constants";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
name: "MsOrganizationMember",
|
||||
components: {MsCreateBox},
|
||||
components: {MsCreateBox, MsTablePagination},
|
||||
created() {
|
||||
this.initTableData();
|
||||
},
|
||||
|
@ -187,14 +178,6 @@
|
|||
this.form = {};
|
||||
this.initTableData();
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.initTableData();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.initTableData();
|
||||
},
|
||||
edit(row) {
|
||||
this.updateVisible = true;
|
||||
this.form = row;
|
||||
|
@ -214,7 +197,7 @@
|
|||
roleIds: this.form.roleIds,
|
||||
organizationId: this.currentUser().lastOrganizationId
|
||||
}
|
||||
this.result = this.$post("/organization/member/update", param,() => {
|
||||
this.result = this.$post("/organization/member/update", param, () => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: this.$t('commons.modify_success')
|
||||
|
@ -270,7 +253,7 @@
|
|||
roleIds: this.form.roleIds,
|
||||
organizationId: orgId
|
||||
};
|
||||
this.result = this.$post("user/org/member/add", param,() => {
|
||||
this.result = this.$post("user/org/member/add", param, () => {
|
||||
this.initTableData();
|
||||
this.createVisible = false;
|
||||
})
|
||||
|
|
|
@ -33,23 +33,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="list" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
|
||||
<el-dialog :title="$t('workspace.create')" :visible.sync="createVisible" width="30%">
|
||||
|
@ -103,23 +88,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleMemberSizeChange"
|
||||
@current-change="handleMemberCurrentChange"
|
||||
:current-page.sync="currentMemberPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageMemberSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="memberTotal">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="wsMemberList" :current-page.sync="currentMemberPage" :page-size.sync="pageMemberSize"
|
||||
:total="memberTotal"/>
|
||||
</el-dialog>
|
||||
|
||||
<!-- add workspace member dialog -->
|
||||
|
@ -203,10 +173,11 @@
|
|||
import MsCreateBox from "../CreateBox";
|
||||
import {Message} from "element-ui";
|
||||
import {TokenKey} from "../../../../common/js/constants";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
name: "MsOrganizationWorkspace",
|
||||
components: {MsCreateBox},
|
||||
components: {MsCreateBox, MsTablePagination},
|
||||
mounted() {
|
||||
this.list();
|
||||
},
|
||||
|
@ -296,14 +267,6 @@
|
|||
}
|
||||
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.list();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.list();
|
||||
},
|
||||
addMember() {
|
||||
this.addMemberVisible = true;
|
||||
this.memberForm = {};
|
||||
|
@ -337,6 +300,28 @@
|
|||
this.memberTotal = data.itemCount;
|
||||
});
|
||||
},
|
||||
wsMemberList() {
|
||||
let row = this.currentWorkspaceRow;
|
||||
this.memberVisible = true;
|
||||
let param = {
|
||||
name: '',
|
||||
workspaceId: row.id
|
||||
};
|
||||
let path = "/user/ws/member/list";
|
||||
this.result = this.$post(this.buildPagePath(path), param, res => {
|
||||
let data = res.data;
|
||||
this.memberLineData = data.listObject;
|
||||
let url = "/userrole/list/ws/" + row.id;
|
||||
// 填充角色信息
|
||||
for (let i = 0; i < this.memberLineData.length; i++) {
|
||||
this.$get(url + "/" + this.memberLineData[i].id, response => {
|
||||
let roles = response.data;
|
||||
this.$set(this.memberLineData[i], "roles", roles);
|
||||
})
|
||||
}
|
||||
this.memberTotal = data.itemCount;
|
||||
});
|
||||
},
|
||||
closeFunc() {
|
||||
this.form = {};
|
||||
},
|
||||
|
@ -344,14 +329,6 @@
|
|||
this.memberLineData = [];
|
||||
this.list();
|
||||
},
|
||||
handleMemberSizeChange(size) {
|
||||
this.pageMemberSize = size;
|
||||
this.cellClick(this.currentWorkspaceRow);
|
||||
},
|
||||
handleMemberCurrentChange(current) {
|
||||
this.currentMemberPage = current;
|
||||
this.cellClick(this.currentWorkspaceRow);
|
||||
},
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
|
@ -418,7 +395,7 @@
|
|||
});
|
||||
},
|
||||
buildPagePath(path) {
|
||||
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||
return path + "/" + this.currentMemberPage + "/" + this.pageMemberSize;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
|
|
|
@ -29,28 +29,15 @@
|
|||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<el-button @click="edit(scope.row)" onkeydown="return false;" type="primary" icon="el-icon-edit" size="mini" circle/>
|
||||
<el-button @click="del(scope.row)" onkeydown="return false;" type="danger" icon="el-icon-delete" size="mini" circle/>
|
||||
<el-button @click="edit(scope.row)" onkeydown="return false;" type="primary" icon="el-icon-edit" size="mini"
|
||||
circle/>
|
||||
<el-button @click="del(scope.row)" onkeydown="return false;" type="danger" icon="el-icon-delete" size="mini"
|
||||
circle/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
<!-- dialog of organization member -->
|
||||
<el-dialog :visible.sync="memberVisible" width="70%" :destroy-on-close="true" @close="closeMemberFunc">
|
||||
|
@ -79,28 +66,16 @@
|
|||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<el-button @click="editMember(scope.row)" onkeydown="return false;" type="primary" icon="el-icon-edit" size="mini" circle/>
|
||||
<el-button @click="delMember(scope.row)" onkeydown="return false;" type="danger" icon="el-icon-delete" size="mini" circle/>
|
||||
<el-button @click="editMember(scope.row)" onkeydown="return false;" type="primary" icon="el-icon-edit"
|
||||
size="mini" circle/>
|
||||
<el-button @click="delMember(scope.row)" onkeydown="return false;" type="danger" icon="el-icon-delete"
|
||||
size="mini" circle/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleMemberSizeChange"
|
||||
@current-change="handleMemberCurrentChange"
|
||||
:current-page.sync="currentMemberPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageMemberSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="memberTotal">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="orgMemberList" :current-page.sync="currentMemberPage"
|
||||
:page-size.sync="pageMemberSize"
|
||||
:total="memberTotal"/>
|
||||
</el-dialog>
|
||||
|
||||
<!-- add organization form -->
|
||||
|
@ -138,7 +113,8 @@
|
|||
<template v-slot:footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button type="primary" onkeydown="return false;"
|
||||
@click="updateOrganization('updateOrganizationForm')" size="medium">{{$t('organization.modify')}}</el-button>
|
||||
@click="updateOrganization('updateOrganizationForm')"
|
||||
size="medium">{{$t('organization.modify')}}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
@ -174,7 +150,7 @@
|
|||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<span class="dialog-footer">
|
||||
<span class="dialog-footer">
|
||||
<el-button type="primary" onkeydown="return false;"
|
||||
@click="submitForm('form')" size="medium">{{$t('commons.save')}}</el-button>
|
||||
</span>
|
||||
|
@ -222,10 +198,11 @@
|
|||
|
||||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
name: "MsOrganization",
|
||||
components: {MsCreateBox},
|
||||
components: {MsCreateBox, MsTablePagination},
|
||||
data() {
|
||||
return {
|
||||
queryPath: '/organization/list',
|
||||
|
@ -317,7 +294,28 @@
|
|||
organizationId: row.id
|
||||
};
|
||||
let path = "/user/special/org/member/list";
|
||||
this.result = this.$post(this.buildPagePath(path), param, res => {
|
||||
this.result = this.$post(path + "/" + this.currentMemberPage + "/" + this.pageMemberSize, param, res => {
|
||||
let data = res.data;
|
||||
this.memberLineData = data.listObject;
|
||||
let url = "/userrole/list/org/" + row.id;
|
||||
for (let i = 0; i < this.memberLineData.length; i++) {
|
||||
this.$get(url + "/" + this.memberLineData[i].id, response => {
|
||||
let roles = response.data;
|
||||
this.$set(this.memberLineData[i], "roles", roles);
|
||||
})
|
||||
}
|
||||
this.memberTotal = data.itemCount;
|
||||
});
|
||||
},
|
||||
orgMemberList() {
|
||||
let row = this.currentRow;
|
||||
this.memberVisible = true;
|
||||
let param = {
|
||||
name: '',
|
||||
organizationId: row.id
|
||||
};
|
||||
let path = "/user/special/org/member/list";
|
||||
this.result = this.$post(path + "/" + this.currentMemberPage + "/" + this.pageMemberSize, param, res => {
|
||||
let data = res.data;
|
||||
this.memberLineData = data.listObject;
|
||||
let url = "/userrole/list/org/" + row.id;
|
||||
|
@ -409,7 +407,7 @@
|
|||
let param = {
|
||||
name: this.condition
|
||||
};
|
||||
this.result = this.$post(this.buildPagePath(this.queryPath), param, response => {
|
||||
this.result = this.$post(this.queryPath + "/" + this.currentPage + "/" + this.pageSize, param, response => {
|
||||
let data = response.data;
|
||||
this.tableData = data.listObject;
|
||||
for (let i = 0; i < this.tableData.length; i++) {
|
||||
|
@ -433,25 +431,6 @@
|
|||
this.memberLineData = [];
|
||||
this.initTableData();
|
||||
},
|
||||
buildPagePath(path) {
|
||||
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.initTableData();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.initTableData();
|
||||
},
|
||||
handleMemberSizeChange(size) {
|
||||
this.pageMemberSize = size;
|
||||
this.cellClick(this.currentRow);
|
||||
},
|
||||
handleMemberCurrentChange(current) {
|
||||
this.currentMemberPage = current;
|
||||
this.cellClick(this.currentRow);
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val;
|
||||
},
|
||||
|
|
|
@ -35,23 +35,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="list" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
|
||||
<!-- add workspace dialog -->
|
||||
|
@ -139,28 +124,15 @@
|
|||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<el-button @click="editMember(scope.row)" onkeydown="return false;" type="primary" icon="el-icon-edit" size="mini" circle/>
|
||||
<el-button @click="delMember(scope.row)" onkeydown="return false;" type="danger" icon="el-icon-delete" size="mini" circle/>
|
||||
<el-button @click="editMember(scope.row)" onkeydown="return false;" type="primary" icon="el-icon-edit"
|
||||
size="mini" circle/>
|
||||
<el-button @click="delMember(scope.row)" onkeydown="return false;" type="danger" icon="el-icon-delete"
|
||||
size="mini" circle/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleMemberSizeChange"
|
||||
@current-change="handleMemberCurrentChange"
|
||||
:current-page.sync="currentMemberPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageMemberSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="memberTotal">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="wsMemberList" :current-page.sync="currentMemberPage" :page-size.sync="pageMemberSize"
|
||||
:total="memberTotal"/>
|
||||
</el-dialog>
|
||||
|
||||
<!-- add workspace member dialog -->
|
||||
|
@ -243,10 +215,11 @@
|
|||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import {Message} from "element-ui";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
name: "MsSystemWorkspace",
|
||||
components: {MsCreateBox},
|
||||
components: {MsCreateBox, MsTablePagination},
|
||||
mounted() {
|
||||
this.list();
|
||||
},
|
||||
|
@ -308,6 +281,28 @@
|
|||
this.memberTotal = data.itemCount;
|
||||
});
|
||||
},
|
||||
wsMemberList() {
|
||||
let row = this.currentWorkspaceRow;
|
||||
this.memberVisible = true;
|
||||
let param = {
|
||||
name: '',
|
||||
workspaceId: row.id
|
||||
};
|
||||
let path = "/user/special/ws/member/list";
|
||||
this.result = this.$post(this.buildPagePath(path), param, res => {
|
||||
let data = res.data;
|
||||
this.memberLineData = data.listObject;
|
||||
let url = "/userrole/list/ws/" + row.id;
|
||||
// 填充角色信息
|
||||
for (let i = 0; i < this.memberLineData.length; i++) {
|
||||
this.$get(url + "/" + this.memberLineData[i].id, response => {
|
||||
let roles = response.data;
|
||||
this.$set(this.memberLineData[i], "roles", roles);
|
||||
})
|
||||
}
|
||||
this.memberTotal = data.itemCount;
|
||||
});
|
||||
},
|
||||
edit(row) {
|
||||
this.updateVisible = true;
|
||||
// copy user
|
||||
|
@ -376,23 +371,7 @@
|
|||
});
|
||||
},
|
||||
buildPagePath(path) {
|
||||
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.list();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.list();
|
||||
},
|
||||
handleMemberSizeChange(size) {
|
||||
this.pageMemberSize = size;
|
||||
this.cellClick(this.currentWorkspaceRow);
|
||||
},
|
||||
handleMemberCurrentChange(current) {
|
||||
this.currentMemberPage = current;
|
||||
this.cellClick(this.currentWorkspaceRow);
|
||||
return path + "/" + this.currentMemberPage + "/" + this.pageMemberSize;
|
||||
},
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
|
|
|
@ -53,23 +53,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-loading="result.loading"
|
||||
|
@ -239,10 +224,11 @@
|
|||
|
||||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
name: "MsTestResourcePool",
|
||||
components: {MsCreateBox},
|
||||
components: {MsCreateBox, MsTablePagination},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
|
@ -340,12 +326,6 @@
|
|||
search() {
|
||||
this.initTableData();
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
},
|
||||
create() {
|
||||
this.createVisible = true;
|
||||
},
|
||||
|
|
|
@ -46,27 +46,13 @@
|
|||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
|
||||
</el-card>
|
||||
|
||||
<el-dialog :title="$t('user.create')" :visible.sync="createVisible" width="30%" @closed="closeFunc" :destroy-on-close="true">
|
||||
<el-dialog :title="$t('user.create')" :visible.sync="createVisible" width="30%" @closed="closeFunc"
|
||||
:destroy-on-close="true">
|
||||
<el-form :model="form" label-position="right" label-width="100px" size="small" :rules="rule" ref="createUserForm">
|
||||
<el-form-item label="ID" prop="id">
|
||||
<el-input v-model="form.id" autocomplete="off"/>
|
||||
|
@ -89,7 +75,8 @@
|
|||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="$t('user.modify')" :visible.sync="updateVisible" width="30%" :destroy-on-close="true" @close="closeFunc">
|
||||
<el-dialog :title="$t('user.modify')" :visible.sync="updateVisible" width="30%" :destroy-on-close="true"
|
||||
@close="closeFunc">
|
||||
<el-form :model="form" label-position="right" label-width="100px" size="small" :rules="rule" ref="updateUserForm">
|
||||
<el-form-item label="ID" prop="id">
|
||||
<el-input v-model="form.id" autocomplete="off" :disabled="true"/>
|
||||
|
@ -105,7 +92,7 @@
|
|||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<span class="dialog-footer">
|
||||
<span class="dialog-footer">
|
||||
<el-button type="primary" onkeydown="return false;"
|
||||
@click="updateUser('updateUserForm')" size="medium">{{$t('commons.save')}}</el-button>
|
||||
</span>
|
||||
|
@ -117,6 +104,7 @@
|
|||
|
||||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
|
@ -138,12 +126,12 @@
|
|||
form: {},
|
||||
rule: {
|
||||
id: [
|
||||
{ required: true, message: this.$t('user.input_id'), trigger: 'blur'},
|
||||
{ min: 2, max: 20, message: this.$t('commons.input_limit', [2, 20]), trigger: 'blur' }
|
||||
{required: true, message: this.$t('user.input_id'), trigger: 'blur'},
|
||||
{min: 2, max: 20, message: this.$t('commons.input_limit', [2, 20]), trigger: 'blur'}
|
||||
],
|
||||
name: [
|
||||
{required: true, message: this.$t('user.input_name'), trigger: 'blur'},
|
||||
{ min: 2, max: 20, message: this.$t('commons.input_limit', [2, 20]), trigger: 'blur' },
|
||||
{min: 2, max: 20, message: this.$t('commons.input_limit', [2, 20]), trigger: 'blur'},
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[\u4e00-\u9fa5_a-zA-Z0-9.·-]+$/,
|
||||
|
@ -160,7 +148,7 @@
|
|||
}
|
||||
],
|
||||
email: [
|
||||
{ required: true, message: this.$t('user.input_email'), trigger: 'blur' },
|
||||
{required: true, message: this.$t('user.input_email'), trigger: 'blur'},
|
||||
{
|
||||
required: true,
|
||||
pattern: /^([A-Za-z0-9_\-.])+@([A-Za-z0-9]+\.)+[A-Za-z]{2,6}$/,
|
||||
|
@ -172,9 +160,9 @@
|
|||
}
|
||||
},
|
||||
name: "MsUser",
|
||||
components: {MsCreateBox},
|
||||
components: {MsCreateBox, MsTablePagination},
|
||||
created() {
|
||||
this.initTableData();
|
||||
this.search();
|
||||
},
|
||||
methods: {
|
||||
create() {
|
||||
|
@ -195,7 +183,7 @@
|
|||
type: 'success',
|
||||
message: this.$t('commons.delete_success')
|
||||
});
|
||||
this.initTableData();
|
||||
this.search();
|
||||
});
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
|
@ -212,9 +200,9 @@
|
|||
type: 'success',
|
||||
message: this.$t('commons.save_success')
|
||||
});
|
||||
this.initTableData();
|
||||
this.search();
|
||||
this.createVisible = false;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -223,37 +211,34 @@
|
|||
updateUser(updateUserForm) {
|
||||
this.$refs[updateUserForm].validate(valide => {
|
||||
if (valide) {
|
||||
this.result = this.$post(this.updatePath, this.form,() => {
|
||||
this.result = this.$post(this.updatePath, this.form, () => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: this.$t('commons.modify_success')
|
||||
type: 'success',
|
||||
message: this.$t('commons.modify_success')
|
||||
});
|
||||
this.updateVisible = false;
|
||||
this.initTableData();
|
||||
});
|
||||
this.search();
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
search() {
|
||||
this.initTableData();
|
||||
},
|
||||
initTableData() {
|
||||
let param = {
|
||||
name: this.condition
|
||||
};
|
||||
this.result = this.$post(this.buildPagePath(this.queryPath),param,response => {
|
||||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
this.result = this.$post(this.buildPagePath(this.queryPath), param, response => {
|
||||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
})
|
||||
},
|
||||
closeFunc() {
|
||||
this.form = {};
|
||||
},
|
||||
changeSwitch(row) {
|
||||
this.$post(this.updatePath, row,() =>{
|
||||
this.$post(this.updatePath, row, () => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: this.$t('commons.modify_success')
|
||||
|
@ -263,14 +248,6 @@
|
|||
buildPagePath(path) {
|
||||
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.initTableData();
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.initTableData();
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val;
|
||||
}
|
||||
|
|
|
@ -32,23 +32,8 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="22" :offset="1">
|
||||
<div class="table-page">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page.sync="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</el-card>
|
||||
|
||||
<el-dialog title="添加成员" :visible.sync="createVisible" width="30%" :destroy-on-close="true" @close="closeFunc">
|
||||
|
@ -123,10 +108,11 @@
|
|||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import {TokenKey} from "../../../../common/js/constants";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
|
||||
export default {
|
||||
name: "MsMember",
|
||||
components: {MsCreateBox},
|
||||
components: {MsCreateBox, MsTablePagination},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
|
@ -189,12 +175,6 @@
|
|||
search() {
|
||||
this.initTableData();
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
},
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
},
|
||||
closeFunc() {
|
||||
this.form = {};
|
||||
this.initTableData();
|
||||
|
|
|
@ -9,3 +9,19 @@
|
|||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.main-content span.title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-top: 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
|
@ -15,20 +15,7 @@
|
|||
line-height: 40px;
|
||||
color: inherit;
|
||||
}
|
||||
body {
|
||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
.main-content span.title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-top: 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
.header-top-menus.el-menu--horizontal > li {
|
||||
height: 40px;
|
||||
|
|
|
@ -28,3 +28,12 @@ export function checkoutCurrentWorkspace() {
|
|||
// 查看当前用户是否是 lastWorkspaceId 的工作空间用户
|
||||
return user.userRoles.filter(ur => hasRoles(ROLE_TEST_MANAGER, ROLE_TEST_USER, ROLE_TEST_VIEWER) && user.lastWorkspaceId === ur.sourceId).length > 0;
|
||||
}
|
||||
|
||||
export function saveLocalStorage(response) {
|
||||
// 登录信息保存 cookie
|
||||
localStorage.setItem(TokenKey, JSON.stringify(response.data));
|
||||
let rolesArray = response.data.roles;
|
||||
let roles = rolesArray.map(r => r.id);
|
||||
// 保存角色
|
||||
localStorage.setItem("roles", roles);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {TokenKey} from '../common/js/constants';
|
||||
import {saveLocalStorage} from '../common/js/utils';
|
||||
|
||||
|
||||
export default {
|
||||
|
@ -105,12 +105,7 @@
|
|||
this.$refs[form].validate((valid) => {
|
||||
if (valid) {
|
||||
this.$post("signin", this.form, (response) => {
|
||||
// 登录信息保存 cookie
|
||||
localStorage.setItem(TokenKey, JSON.stringify(response.data));
|
||||
let rolesArray = response.data.roles;
|
||||
let roles = rolesArray.map(r => r.id);
|
||||
// 保存角色
|
||||
localStorage.setItem("roles", roles);
|
||||
saveLocalStorage(response);
|
||||
window.location.href = "/"
|
||||
});
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue