This commit is contained in:
扈兆增 2026-08-05 17:12:44 +08:00
commit 7aa98abdfb
106 changed files with 4197 additions and 1404 deletions

View File

@ -22,29 +22,29 @@ public class ResponseResult extends HashMap<String, Object> {
public static ResponseResult error(String msg) { public static ResponseResult error(String msg) {
ResponseResult json = new ResponseResult(); ResponseResult json = new ResponseResult();
json.put((String)"code", "1");//错误 json.put("code", "1");//错误
json.put((String)"msg", msg); json.put("msg", msg);
return json; return json;
} }
public static ResponseResult message(String code, String msg) { public static ResponseResult message(String code, String msg) {
ResponseResult json = new ResponseResult(); ResponseResult json = new ResponseResult();
json.put((String)"code", code); json.put("code", code);
json.put((String)"msg", msg); json.put("msg", msg);
return json; return json;
} }
public static ResponseResult success(String msg) { public static ResponseResult success(String msg) {
ResponseResult json = new ResponseResult(); ResponseResult json = new ResponseResult();
json.put((String)"code", "0");//正常 json.put("code", "0");//正常
json.put((String)"msg", msg); json.put("msg", msg);
return json; return json;
} }
public static ResponseResult successData(Object obj) { public static ResponseResult successData(Object obj) {
ResponseResult json = new ResponseResult(); ResponseResult json = new ResponseResult();
json.put((String)"code", "0");//正常 json.put("code", "0");//正常
json.put((String)"msg", "操作成功"); json.put("msg", "操作成功");
json.put("data", obj); json.put("data", obj);
return json; return json;
} }

View File

@ -63,10 +63,12 @@ public class SecurityConfig {
.requestMatchers("/data/fishDraft/previewFile").permitAll() .requestMatchers("/data/fishDraft/previewFile").permitAll()
.requestMatchers("/tempFile/**").permitAll() .requestMatchers("/tempFile/**").permitAll()
.requestMatchers("/system/user/auditUser").permitAll() .requestMatchers("/system/user/auditUser").permitAll()
.requestMatchers("/register/accessToken").permitAll()
.requestMatchers("/api/oauth2/oauth/token").permitAll() .requestMatchers("/api/oauth2/oauth/token").permitAll()
.requestMatchers("/dict/cache/**").permitAll() .requestMatchers("/dict/cache/**").permitAll()
.requestMatchers("/sys/psbmodulelbb/**").permitAll() .requestMatchers("/sys/psbmodulelbb/**").permitAll()
.requestMatchers("/base/operationLog/**").permitAll() .requestMatchers("/base/operationLog/**").permitAll()
.requestMatchers("/system/**").permitAll()
// .requestMatchers("/eng/**").permitAll() // .requestMatchers("/eng/**").permitAll()
// .requestMatchers("/eq/**").permitAll() // .requestMatchers("/eq/**").permitAll()
// .requestMatchers("/env/**").permitAll() // .requestMatchers("/env/**").permitAll()

View File

@ -12,6 +12,7 @@ import com.yfd.platform.qgc_base.domain.SdEngInfoBHOperateRequest;
import com.yfd.platform.qgc_base.domain.SdFishDictoryB; import com.yfd.platform.qgc_base.domain.SdFishDictoryB;
import com.yfd.platform.qgc_base.service.ISdFishDictoryBService; import com.yfd.platform.qgc_base.service.ISdFishDictoryBService;
import com.yfd.platform.qgc_data.service.AttachmentUploadService; import com.yfd.platform.qgc_data.service.AttachmentUploadService;
import com.yfd.platform.utils.DataSourceRequestUtil;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -55,7 +56,7 @@ public class SdFishDictoryBController {
@PostMapping("/list") @PostMapping("/list")
@Operation(summary = "查询鱼类字典列表(支持动态过滤和排序,不分页)") @Operation(summary = "查询鱼类字典列表(支持动态过滤和排序,不分页)")
public ResponseResult list(@RequestBody DataSourceRequest request) { public ResponseResult list(@RequestBody DataSourceRequest request) {
List<SdFishDictoryB> list = sdFishDictoryBService.list(); List<SdFishDictoryB> list = DataSourceRequestUtil.executeList(request, SdFishDictoryB.class, sdFishDictoryBService);
return ResponseResult.successData(list); return ResponseResult.successData(list);
} }

View File

@ -17,7 +17,8 @@ public interface SdFpssBHMapper extends BaseMapper<SdFpssBH> {
"WHERE 1=1 " + "WHERE 1=1 " +
"<if test='baseId != null and baseId != \"\"'> AND E.BASE_ID = #{baseId} </if>" + "<if test='baseId != null and baseId != \"\"'> AND E.BASE_ID = #{baseId} </if>" +
"<if test='rstcd != null and rstcd != \"\"'> AND F.RSTCD = #{rstcd} </if>" + "<if test='rstcd != null and rstcd != \"\"'> AND F.RSTCD = #{rstcd} </if>" +
"<if test='rvcd != null and rvcd != \"\"'> AND E.REACHCD = #{rvcd} </if>" + "<if test='rvcd != null and rvcd != \"\"'> AND E.RVCD = #{rvcd} </if>" +
"<if test='reachcd != null and reachcd != \"\"'> AND E.REACHCD = #{reachcd} </if>" +
// "<if test='rstcd != null and rstcd != \"\"'> AND F.RSTCD = #{rstcd} </if>" + // "<if test='rstcd != null and rstcd != \"\"'> AND F.RSTCD = #{rstcd} </if>" +
"<if test='stnm != null and stnm != \"\"'> AND F.STNM LIKE '%' || #{stnm} || '%' </if>" + "<if test='stnm != null and stnm != \"\"'> AND F.STNM LIKE '%' || #{stnm} || '%' </if>" +
"ORDER BY F.ORDER_INDEX DESC" + "ORDER BY F.ORDER_INDEX DESC" +

View File

@ -46,6 +46,13 @@ public class FishPassageController {
return ResponseResult.successData(fpRunService.processQgcFpssrlQueryKendoList(dataSourceRequest)); return ResponseResult.successData(fpRunService.processQgcFpssrlQueryKendoList(dataSourceRequest));
} }
@PostMapping("/query/qgc/GetKendoListCustAI")
@Operation(summary = "全过程过鱼自动(AI设备)与人工监测数据查询")
public ResponseResult getQgcFpssrlAiRQueryKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(fpRunService.processQgcFpssrlAiRQueryKendoList(dataSourceRequest));
}
@PostMapping("/fpssTable/qgc/GetKendoListCust") @PostMapping("/fpssTable/qgc/GetKendoListCust")
@Operation(summary = "过鱼设施监测数据查询") @Operation(summary = "过鱼设施监测数据查询")
public ResponseResult getQgcFpssTableKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { public ResponseResult getQgcFpssTableKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {

View File

@ -23,6 +23,8 @@ public interface FpRunService {
DataSourceResult<FpFpssrlQueryVo> processQgcFpssrlQueryKendoList(DataSourceRequest dataSourceRequest); DataSourceResult<FpFpssrlQueryVo> processQgcFpssrlQueryKendoList(DataSourceRequest dataSourceRequest);
DataSourceResult<FpFpssrlQueryVo> processQgcFpssrlAiRQueryKendoList(DataSourceRequest dataSourceRequest);
DataSourceResult<FpTableVo> processQgcFpssTableKendoList(DataSourceRequest dataSourceRequest); DataSourceResult<FpTableVo> processQgcFpssTableKendoList(DataSourceRequest dataSourceRequest);
DataSourceResult<FpRunAnalysisTableVo> getAnalysisData(DataSourceRequest dataSourceRequest); DataSourceResult<FpRunAnalysisTableVo> getAnalysisData(DataSourceRequest dataSourceRequest);

View File

@ -220,6 +220,15 @@ public class FpRunServiceImpl implements FpRunService {
return queryQgcFpssrlGroupList(dataSourceRequest, loadOptions); return queryQgcFpssrlGroupList(dataSourceRequest, loadOptions);
} }
@Override
public DataSourceResult<FpFpssrlQueryVo> processQgcFpssrlAiRQueryKendoList(DataSourceRequest dataSourceRequest) {
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) {
return queryQgcFpssrlAiRDetailList(dataSourceRequest, loadOptions);
}
return queryQgcFpssrlAiRGroupList(dataSourceRequest, loadOptions);
}
@Override @Override
public DataSourceResult<FpTableVo> processQgcFpssTableKendoList(DataSourceRequest dataSourceRequest) { public DataSourceResult<FpTableVo> processQgcFpssTableKendoList(DataSourceRequest dataSourceRequest) {
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
@ -1211,6 +1220,33 @@ public class FpRunServiceImpl implements FpRunService {
return result; return result;
} }
private DataSourceResult<FpFpssrlQueryVo> queryQgcFpssrlAiRDetailList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ")
.append(buildQgcFpssrlDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect()))
.append(" FROM (")
.append(buildQgcFpssrlAiRCoreSql())
.append(") t WHERE 1 = 1 ");
Map<String, Object> paramMap = new HashMap<>();
String filterSql = buildQgcFpssrlFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0});
if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql).append(" ");
}
sql.append(buildQgcFpssrlOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort()));
Page<?> page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
List<FpFpssrlQueryVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(
page, sql.toString(), paramMap, FpFpssrlQueryVo.class
);
DataSourceResult<FpFpssrlQueryVo> result = new DataSourceResult<>();
result.setData(list);
result.setTotal(page != null ? page.getTotal() : list.size());
result.setAggregates(new HashMap<>());
return result;
}
private DataSourceResult<FpFpssrlQueryVo> queryQgcFpssrlGroupList(DataSourceRequest dataSourceRequest, private DataSourceResult<FpFpssrlQueryVo> queryQgcFpssrlGroupList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) { DataSourceLoadOptionsBase loadOptions) {
List<DataSourceRequest.GroupDescriptor> groups = dataSourceRequest.getGroup(); List<DataSourceRequest.GroupDescriptor> groups = dataSourceRequest.getGroup();
@ -1284,6 +1320,79 @@ public class FpRunServiceImpl implements FpRunService {
return result; return result;
} }
private DataSourceResult<FpFpssrlQueryVo> queryQgcFpssrlAiRGroupList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) {
List<DataSourceRequest.GroupDescriptor> groups = dataSourceRequest.getGroup();
GroupingInfo[] groupInfos = loadOptions == null ? new GroupingInfo[0] : loadOptions.getGroup();
StringBuilder sql = new StringBuilder("SELECT ");
List<String> selectItems = new ArrayList<>();
for (DataSourceRequest.GroupDescriptor descriptor : groups) {
if (descriptor == null || StrUtil.isBlank(descriptor.getField())) {
continue;
}
String column = mapQgcFpssrlColumn(descriptor.getField());
if (StrUtil.isBlank(column)) {
continue;
}
selectItems.add(column + " AS " + descriptor.getField().toUpperCase());
selectItems.add("COUNT(*) AS COUNT_" + descriptor.getField().toUpperCase());
if (CollUtil.isNotEmpty(descriptor.getAggregates())) {
for (DataSourceRequest.AggregateDescriptor aggregate : descriptor.getAggregates()) {
String aggregateColumn = mapQgcFpssrlColumn(aggregate.getField());
if (StrUtil.isBlank(aggregateColumn) || StrUtil.isBlank(aggregate.getAggregate())) {
continue;
}
String aggregateSql = buildAggregateSql(aggregate.getAggregate(), aggregateColumn, aggregate.getField());
if (StrUtil.isNotBlank(aggregateSql)) {
selectItems.add(aggregateSql);
}
}
}
}
if (selectItems.isEmpty()) {
selectItems.add("t.STCD AS STCD");
selectItems.add("COUNT(*) AS COUNT_STCD");
}
sql.append(String.join(", ", selectItems))
.append(" FROM (")
.append(buildQgcFpssrlCoreSql())
.append(") t WHERE 1 = 1 ");
Map<String, Object> paramMap = new HashMap<>();
String filterSql = buildQgcFpssrlFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0});
if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql).append(" ");
}
List<String> groupByColumns = new ArrayList<>();
for (DataSourceRequest.GroupDescriptor descriptor : groups) {
if (descriptor == null || StrUtil.isBlank(descriptor.getField())) {
continue;
}
String column = mapQgcFpssrlColumn(descriptor.getField());
if (StrUtil.isNotBlank(column)) {
groupByColumns.add(column);
}
}
if (!groupByColumns.isEmpty()) {
sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" ");
}
sql.append(buildQgcFpssrlGroupOrderBySql(groups));
List<Map<String, Object>> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), paramMap);
DataSourceResult<FpFpssrlQueryVo> result = new DataSourceResult<>();
if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) {
result.setData((List<FpFpssrlQueryVo>) (List<?>) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos)));
} else {
result.setData((List<FpFpssrlQueryVo>) (List<?>) new GroupHelper().group(rows, Arrays.asList(groupInfos)));
}
result.setTotal(0L);
result.setAggregates(new HashMap<>());
return result;
}
private DataSourceResult<FpSdfpssrVo> queryQgcSdfpssrGroupList(DataSourceRequest dataSourceRequest, private DataSourceResult<FpSdfpssrVo> queryQgcSdfpssrGroupList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) { DataSourceLoadOptionsBase loadOptions) {
List<DataSourceRequest.GroupDescriptor> groups = dataSourceRequest.getGroup(); List<DataSourceRequest.GroupDescriptor> groups = dataSourceRequest.getGroup();
@ -1566,6 +1675,161 @@ public class FpRunServiceImpl implements FpRunService {
") src"; ") src";
} }
private String buildQgcFpssrlAiRCoreSql() {
return "SELECT " +
"src.ID AS id, " +
"src.STCD AS stcd, " +
"src.STNM AS stnm, " +
"src.BASEID AS baseId, " +
"src.BASENAME AS baseName, " +
"src.RSTCD AS rstcd, " +
"src.ENNM AS ennm, " +
"src.HBRVCD AS hbrvcd, " +
"src.BASESTEPSORT AS baseStepSort, " +
"src.RVCDSTEPSORT AS rvcdStepSort, " +
"src.SITESTEPSORT AS siteStepSort, " +
"src.RSTCDSTEPSORT AS rstcdStepSort, " +
"src.TM AS tm, " +
"src.YR AS yr, " +
"src.FTP AS ftp, " +
"src.FISHID AS fishId, " +
"src.FSZ AS fsz, " +
"src.LENGTH AS length, " +
"src.WIDTH AS width, " +
"src.FISHSPEED AS fishspeed, " +
"src.DIRECTION AS direction, " +
"src.TEMPERATURE AS temperature, " +
"src.SPEED AS speed, " +
"src.CHANNELNO AS channelno, " +
"src.FCNT AS fcnt, " +
"src.FIRSTIMGURL AS firstimgurl, " +
"src.VIDEOURL AS videourl, " +
"src.MWAY AS mway, " +
"src.STRDT AS strdt, " +
"src.ENDDT AS enddt, " +
"src.STCODE AS stCode, " +
"src.STNAME AS stName " +
"FROM ( " +
" SELECT t.ID AS ID, " +
" t.STCD AS STCD, " +
" fp.STNM AS STNM, " +
" eng.BASE_ID AS BASEID, " +
" hb.BASENAME AS BASENAME, " +
" fp.RSTCD AS RSTCD, " +
" eng.ENNM AS ENNM, " +
" eng.HBRVCD AS HBRVCD, " +
" NVL(hb.ORDER_INDEX, 999999) AS BASESTEPSORT, " +
" NVL(hbrv.ORDER_INDEX, 999999) AS RVCDSTEPSORT, " +
" NVL(fp.ORDER_INDEX, 999999) AS SITESTEPSORT, " +
" NVL(eng.ORDER_INDEX, 999999) AS RSTCDSTEPSORT, " +
" t.TM AS TM, " +
" TO_CHAR(t.TM, 'YYYY') AS YR, " +
" COALESCE(fishRv.NAME, relRv.FISH_NAME, fishZy.NAME, relZy.FISH_NAME, fishDirect.NAME, t.FTP) AS FTP, " +
" t.FTP AS FISHID, " +
" t.FSZ AS FSZ, " +
" TO_CHAR(t.LENGTH) AS LENGTH, " +
" TO_CHAR(t.WIDTH) AS WIDTH, " +
" TO_CHAR(t.FISHSPEED) AS FISHSPEED, " +
" TO_CHAR(t.DIRECTION) AS DIRECTION, " +
" TO_CHAR(t.TEMPERATURE) AS TEMPERATURE, " +
" TO_CHAR(t.SPEED) AS SPEED, " +
" t.CHANNELNO AS CHANNELNO, " +
" TO_CHAR(t.FCNT) AS FCNT, " +
" t.FIRSTIMGURL AS FIRSTIMGURL, " +
" t.VIDEOURL AS VIDEOURL, " +
" 2 AS MWAY, " +
" CAST(NULL AS DATE) AS STRDT, " +
" CAST(NULL AS DATE) AS ENDDT, " +
" fp.STTP AS STCODE, " +
" sttp.STTP_NAME AS STNAME " +
" FROM SD_FPSSRL_AI_R t " +
" INNER JOIN V_MS_STBPRP_T fp ON fp.STCD = t.STCD " +
" LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = fp.STTP AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " +
" LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD " +
" AND hbrv.BASEID = eng.BASE_ID " +
" AND NVL(hbrv.IS_DELETED, 0) = 0 " +
" AND NVL(hbrv.ENABLED, 1) = 1 " +
" LEFT JOIN SD_FISHDICTORY_RLTN_B relRv ON relRv.FISH_ID = t.FTP " +
" AND relRv.RVCD = eng.HBRVCD " +
" AND NVL(relRv.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_FISHDICTORY_B fishRv ON fishRv.ID = relRv.ZY_FISH_ID " +
" AND NVL(fishRv.IS_DELETED, 0) = 0 " +
" AND NVL(fishRv.ENABLE, 1) = 1 " +
" LEFT JOIN SD_FISHDICTORY_RLTN_B relZy ON relZy.FISH_ID = t.FTP " +
" AND relZy.RVCD = 'ZY' " +
" AND NVL(relZy.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_FISHDICTORY_B fishZy ON fishZy.ID = relZy.ZY_FISH_ID " +
" AND NVL(fishZy.IS_DELETED, 0) = 0 " +
" AND NVL(fishZy.ENABLE, 1) = 1 " +
" LEFT JOIN SD_FISHDICTORY_B fishDirect ON fishDirect.ID = t.FTP " +
" AND NVL(fishDirect.IS_DELETED, 0) = 0 " +
" AND NVL(fishDirect.ENABLE, 1) = 1 " +
" WHERE NVL(t.IS_DELETED, 0) = 0 " +
" UNION ALL " +
" SELECT t.ID AS ID, " +
" t.STCD AS STCD, " +
" fp.STNM AS STNM, " +
" eng.BASE_ID AS BASEID, " +
" hb.BASENAME AS BASENAME, " +
" fp.RSTCD AS RSTCD, " +
" eng.ENNM AS ENNM, " +
" eng.HBRVCD AS HBRVCD, " +
" NVL(hb.ORDER_INDEX, 999999) AS BASESTEPSORT, " +
" NVL(hbrv.ORDER_INDEX, 999999) AS RVCDSTEPSORT, " +
" NVL(fp.ORDER_INDEX, 999999) AS SITESTEPSORT, " +
" NVL(eng.ORDER_INDEX, 999999) AS RSTCDSTEPSORT, " +
" t.STRDT AS TM, " +
" TO_CHAR(t.STRDT, 'YYYY') AS YR, " +
" COALESCE(fishRv.NAME, relRv.FISH_NAME, fishZy.NAME, relZy.FISH_NAME, fishDirect.NAME, t.FTP) AS FTP, " +
" t.FTP AS FISHID, " +
" t.FSZ AS FSZ, " +
" CAST(NULL AS VARCHAR2(50)) AS LENGTH, " +
" CAST(NULL AS VARCHAR2(50)) AS WIDTH, " +
" CAST(NULL AS VARCHAR2(50)) AS FISHSPEED, " +
" TO_CHAR(t.DIRECTION) AS DIRECTION, " +
" CAST(NULL AS VARCHAR2(50)) AS TEMPERATURE, " +
" CAST(NULL AS VARCHAR2(50)) AS SPEED, " +
" CAST(NULL AS VARCHAR2(100)) AS CHANNELNO, " +
" TO_CHAR(t.FCNT) AS FCNT, " +
" t.PICPTH AS FIRSTIMGURL, " +
" t.VDPTH AS VIDEOURL, " +
" 1 AS MWAY, " +
" t.STRDT AS STRDT, " +
" t.ENDDT AS ENDDT, " +
" fp.STTP AS STCODE, " +
" sttp.STTP_NAME AS STNAME " +
" FROM SD_FPSS_R t " +
" INNER JOIN SD_FPSS_B_H fp ON fp.STCD = t.STCD " +
" LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = fp.STTP AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " +
" LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD " +
" AND hbrv.BASEID = eng.BASE_ID " +
" AND NVL(hbrv.IS_DELETED, 0) = 0 " +
" AND NVL(hbrv.ENABLED, 1) = 1 " +
" LEFT JOIN SD_FISHDICTORY_RLTN_B relRv ON relRv.FISH_ID = t.FTP " +
" AND relRv.RVCD = eng.HBRVCD " +
" AND NVL(relRv.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_FISHDICTORY_B fishRv ON fishRv.ID = relRv.ZY_FISH_ID " +
" AND NVL(fishRv.IS_DELETED, 0) = 0 " +
" AND NVL(fishRv.ENABLE, 1) = 1 " +
" LEFT JOIN SD_FISHDICTORY_RLTN_B relZy ON relZy.FISH_ID = t.FTP " +
" AND relZy.RVCD = 'ZY' " +
" AND NVL(relZy.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_FISHDICTORY_B fishZy ON fishZy.ID = relZy.ZY_FISH_ID " +
" AND NVL(fishZy.IS_DELETED, 0) = 0 " +
" AND NVL(fishZy.ENABLE, 1) = 1 " +
" LEFT JOIN SD_FISHDICTORY_B fishDirect ON fishDirect.ID = t.FTP " +
" AND NVL(fishDirect.IS_DELETED, 0) = 0 " +
" AND NVL(fishDirect.ENABLE, 1) = 1 " +
" WHERE NVL(t.IS_DELETED, 0) = 0 " +
// " AND (t.TASK_STATUS = 'Approved' OR t.TASK_STATUS IS NULL) " +
") src";
}
private String buildQgcSdfpssrDetailSelectSql(List<String> selectFields) { private String buildQgcSdfpssrDetailSelectSql(List<String> selectFields) {
Map<String, String> selectMap = new LinkedHashMap<>(); Map<String, String> selectMap = new LinkedHashMap<>();
selectMap.put("stcd", "t.stcd AS stcd"); selectMap.put("stcd", "t.stcd AS stcd");

View File

@ -37,6 +37,7 @@ import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -100,8 +101,12 @@ public class LoginController {
Integer status = loginUser.getUser().getStatus(); Integer status = loginUser.getUser().getStatus();
String regStatus = loginUser.getUser().getRegStatus(); String regStatus = loginUser.getUser().getRegStatus();
if (StrUtil.isNotBlank(tenantId)&&!tenantId.equals(loginUser.getUser().getTenantId())) { // 多门户验证用户是否有权限访问指定门户
return ResponseResult.error("账号不存在或密码错误"); if (!loginUser.isSuperAdmin() && StrUtil.isNotBlank(tenantId)) {
List<String> accessibleIds = loginUser.getAccessibleTenantIds();
if (accessibleIds == null || !accessibleIds.contains(tenantId)) {
return ResponseResult.error("账号不存在或密码错误");
}
} }
if (StrUtil.isNotBlank(regStatus)&&"REJECTED".equals(regStatus)) { if (StrUtil.isNotBlank(regStatus)&&"REJECTED".equals(regStatus)) {
@ -149,6 +154,10 @@ public class LoginController {
String token = JWTUtil.createToken(map, "12345678".getBytes()); String token = JWTUtil.createToken(map, "12345678".getBytes());
map.put("token", token); map.put("token", token);
// 返回可访问门户列表和超级管理员标识
map.put("accessibleTenantIds", loginUser.getAccessibleTenantIds());
map.put("superAdmin", loginUser.isSuperAdmin());
map.put("currentTenantId", tenantId);
//把完整的用户信息存入到HuTool缓存中userId作为key //把完整的用户信息存入到HuTool缓存中userId作为key
String jsonStr = JSONUtil.toJsonStr(loginUser); String jsonStr = JSONUtil.toJsonStr(loginUser);
webConfig.loginuserCache().put("login:" + userId, jsonStr); webConfig.loginuserCache().put("login:" + userId, jsonStr);
@ -232,7 +241,7 @@ public class LoginController {
@Operation(summary = "查询当前用户信息") @Operation(summary = "查询当前用户信息")
@ResponseBody @ResponseBody
public ResponseResult getUserInfo() { public ResponseResult getUserInfo() {
ResponseResult responseResult = userService.getLoginUserInfo(); Map<String, Object> responseResult = userService.getLoginUserInfo();
return ResponseResult.successData(responseResult); return ResponseResult.successData(responseResult);
} }

View File

@ -1,7 +1,9 @@
package com.yfd.platform.system.controller; package com.yfd.platform.system.controller;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTUtil; import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.config.WebConfig; import com.yfd.platform.config.WebConfig;
import com.yfd.platform.qgc_data.domain.SysUserDataScope; import com.yfd.platform.qgc_data.domain.SysUserDataScope;
@ -11,6 +13,9 @@ import com.yfd.platform.qgc_base.service.ISdEngInfoBHService;
import com.yfd.platform.qgc_base.service.ISdHbrvDicService; import com.yfd.platform.qgc_base.service.ISdHbrvDicService;
import com.yfd.platform.system.domain.*; import com.yfd.platform.system.domain.*;
import com.yfd.platform.system.mapper.SysMenuMapper; import com.yfd.platform.system.mapper.SysMenuMapper;
import com.yfd.platform.system.mapper.SysOrganizationMapper;
import com.yfd.platform.system.mapper.SysRoleMapper;
import com.yfd.platform.system.mapper.SysUserTenantMapper;
import com.yfd.platform.system.service.ISmsVerifyCodeService; import com.yfd.platform.system.service.ISmsVerifyCodeService;
import com.yfd.platform.system.service.ISysLogService; import com.yfd.platform.system.service.ISysLogService;
import com.yfd.platform.system.service.IUserService; import com.yfd.platform.system.service.IUserService;
@ -60,25 +65,36 @@ public class SmsVerifyCodeController {
@Resource @Resource
private SysMenuMapper sysMenuMapper; private SysMenuMapper sysMenuMapper;
@Resource
private SysOrganizationMapper organizationMapper;
@Resource
private SysRoleMapper roleMapper;
@Resource @Resource
private ISysUserDataScopeService sysUserDataScopeService; private ISysUserDataScopeService sysUserDataScopeService;
@Resource @Resource
private ISdEngInfoBHService engInfoBHService; private ISdEngInfoBHService engInfoBHService;
@Resource
private SysUserTenantMapper sysUserTenantMapper;
@Resource
private SysUserTenantMapper userTenantMapper;
@Resource @Resource
private ISdHbrvDicService hbrvDicService; private ISdHbrvDicService hbrvDicService;
@Value("${rsa.private_key}") @Value("${rsa.private_key}")
private String privateKey; private String privateKey;
private static final String URGE_CONTENT ="根据生态环境部要求,请贵电站尽快完成过鱼数据的报送工作,感谢支持。"; private static final String URGE_CONTENT = "根据生态环境部要求,请贵电站尽快完成过鱼数据的报送工作,感谢支持。";
/** /**
* 发送验证码 * 发送验证码
*/ */
@PostMapping("/sendCode") @PostMapping("/sendCode")
@Operation(summary = "发送验证码") @Operation(summary = "发送验证码")
public ResponseResult sendVerifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { public ResponseResult sendVerifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
String phone = smsVerifyCodeRequest.getPhone(); String phone = smsVerifyCodeRequest.getPhone();
Integer type = smsVerifyCodeRequest.getType(); Integer type = smsVerifyCodeRequest.getType();
@ -91,21 +107,21 @@ public class SmsVerifyCodeController {
// 1. 注册验证码校验 // 1. 注册验证码校验
if (type.equals(SmsVerifyCode.TYPE_REGISTER)) { if (type.equals(SmsVerifyCode.TYPE_REGISTER)) {
SysUser existUser = userService.getUserByPhone(phone,tenantId); SysUser existUser = userService.getUserByPhone(phone, tenantId);
if (existUser != null) { if (existUser != null) {
return ResponseResult.error("该手机号已注册"); return ResponseResult.error("该手机号已注册");
} }
} }
// 2. 找回密码验证码校验 // 2. 找回密码验证码校验
else if (type.equals(SmsVerifyCode.TYPE_FIND_PASSWORD)) { else if (type.equals(SmsVerifyCode.TYPE_FIND_PASSWORD)) {
SysUser existUser = userService.getUserByPhone(phone,tenantId); SysUser existUser = userService.getUserByPhone(phone, tenantId);
if (existUser == null) { if (existUser == null) {
return ResponseResult.error("该手机号未注册"); return ResponseResult.error("该手机号未注册");
} }
} }
// 3. 登录验证码校验新增 // 3. 登录验证码校验新增
else if (type.equals(SmsVerifyCode.TYPE_LOGIN)) { else if (type.equals(SmsVerifyCode.TYPE_LOGIN)) {
SysUser existUser = userService.getUserByPhone(phone,tenantId); SysUser existUser = userService.getUserByPhone(phone, tenantId);
if (existUser == null) { if (existUser == null) {
return ResponseResult.error("该手机号未注册,请先注册"); return ResponseResult.error("该手机号未注册,请先注册");
} }
@ -113,12 +129,11 @@ public class SmsVerifyCodeController {
// if (existUser.getStatus() == 0) { // if (existUser.getStatus() == 0) {
// return ResponseResult.error("账号已被禁用"); // return ResponseResult.error("账号已被禁用");
// } // }
} } else {
else {
return ResponseResult.error("类型错误1-注册 2-找回密码 3-登录"); return ResponseResult.error("类型错误1-注册 2-找回密码 3-登录");
} }
String code = smsVerifyCodeService.sendVerifyCode(phone, type,tenantId); String code = smsVerifyCodeService.sendVerifyCode(phone, type, tenantId);
if (code == null) { if (code == null) {
return ResponseResult.error("验证码发送失败,请稍后重试"); return ResponseResult.error("验证码发送失败,请稍后重试");
} }
@ -132,10 +147,10 @@ public class SmsVerifyCodeController {
*/ */
@PostMapping("/batchSendContent") @PostMapping("/batchSendContent")
@Operation(summary = "批量发送短信") @Operation(summary = "批量发送短信")
public ResponseResult batchSendContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { public ResponseResult batchSendContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
List<String> phoneList = smsVerifyCodeRequest.getPhoneList(); List<String> phoneList = smsVerifyCodeRequest.getPhoneList();
if(phoneList==null){ if (phoneList == null) {
return ResponseResult.error("手机号不能为空"); return ResponseResult.error("手机号不能为空");
} }
@ -148,7 +163,7 @@ public class SmsVerifyCodeController {
*/ */
@PostMapping("/batchUrgeContent") @PostMapping("/batchUrgeContent")
@Operation(summary = "催促") @Operation(summary = "催促")
public ResponseResult batchUrgeContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { public ResponseResult batchUrgeContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
List<String> userIds = smsVerifyCodeRequest.getUserIds(); List<String> userIds = smsVerifyCodeRequest.getUserIds();
String content = smsVerifyCodeRequest.getContent(); String content = smsVerifyCodeRequest.getContent();
@ -161,7 +176,7 @@ public class SmsVerifyCodeController {
} }
try { try {
int successCount = smsVerifyCodeService.urgeByUserIds(tenantId,userIds, content); int successCount = smsVerifyCodeService.urgeByUserIds(tenantId, userIds, content);
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
// result.put("successCount", successCount); // result.put("successCount", successCount);
result.put("totalCount", userIds.size()); result.put("totalCount", userIds.size());
@ -173,14 +188,13 @@ public class SmsVerifyCodeController {
} }
/** /**
* 注册用户 * 注册用户
*/ */
@PostMapping("/register") @PostMapping("/register")
@Operation(summary = "注册用户") @Operation(summary = "注册用户")
@Transactional @Transactional(rollbackFor = Exception.class)
public ResponseResult register(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { public ResponseResult register(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
String code = smsVerifyCodeRequest.getCode(); String code = smsVerifyCodeRequest.getCode();
if (smsVerifyCodeRequest.getPhone() == null || smsVerifyCodeRequest.getPhone().isEmpty()) { if (smsVerifyCodeRequest.getPhone() == null || smsVerifyCodeRequest.getPhone().isEmpty()) {
return ResponseResult.error("手机号不能为空"); return ResponseResult.error("手机号不能为空");
@ -195,12 +209,12 @@ public class SmsVerifyCodeController {
return ResponseResult.error("验证码不能为空"); return ResponseResult.error("验证码不能为空");
} }
boolean verified = smsVerifyCodeService.verifyCode(smsVerifyCodeRequest.getPhone(), code, SmsVerifyCode.TYPE_REGISTER,tenantId); boolean verified = smsVerifyCodeService.verifyCode(smsVerifyCodeRequest.getPhone(), code, SmsVerifyCode.TYPE_REGISTER, tenantId);
if (!verified) { if (!verified) {
return ResponseResult.error("验证码错误或已过期"); return ResponseResult.error("验证码错误或已过期");
} }
SysUser existUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(),tenantId); SysUser existUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(), tenantId);
if (existUser != null) { if (existUser != null) {
return ResponseResult.error("该手机号已注册"); return ResponseResult.error("该手机号已注册");
} }
@ -212,13 +226,15 @@ public class SmsVerifyCodeController {
} catch (Exception e) { } catch (Exception e) {
return ResponseResult.error("密码解密失败"); return ResponseResult.error("密码解密失败");
} }
SysOrganization aDefault = organizationMapper.selectOne(new LambdaQueryWrapper<SysOrganization>().eq(SysOrganization::getCustom1, "default"));
String orgid = aDefault == null ? null : aDefault.getId();
user.setRegStatus("PENDING"); user.setRegStatus("PENDING");
user.setPhone(smsVerifyCodeRequest.getPhone()); user.setPhone(smsVerifyCodeRequest.getPhone());
user.setBelongingUnit(smsVerifyCodeRequest.getBelongingUnit()); user.setBelongingUnit(smsVerifyCodeRequest.getBelongingUnit());
user.setRegTime(new Date()); user.setRegTime(new Date());
user.setNickname(smsVerifyCodeRequest.getRealName()); user.setNickname(smsVerifyCodeRequest.getRealName());
user.setStatus(0); user.setStatus(0);
user.setOrgid("e90063ced25e3d469860e88d920c082f"); user.setOrgid(orgid);
user.setUsertype(1); user.setUsertype(1);
user.setTenantId(tenantId); user.setTenantId(tenantId);
user.setUsername(smsVerifyCodeRequest.getUsername()); user.setUsername(smsVerifyCodeRequest.getUsername());
@ -226,8 +242,14 @@ public class SmsVerifyCodeController {
user.setCompanyCode(smsVerifyCodeRequest.getCompanyCode()); user.setCompanyCode(smsVerifyCodeRequest.getCompanyCode());
boolean success = userService.save(user); boolean success = userService.save(user);
// 给注册用户加上默认权限 // 给注册用户加上默认权限
SysUser savedUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(),tenantId); SysUser savedUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(), tenantId);
if (savedUser != null) { if (savedUser != null) {
SysUserTenant sysUserTenant = new SysUserTenant();
sysUserTenant.setTenantId(tenantId);
sysUserTenant.setUserId(user.getId());
sysUserTenant.setId(user.getId());
// sysUserTenant.setOperateTime(new Date());
userTenantMapper.insert(sysUserTenant);
this.addDefaultRole(savedUser.getId(), smsVerifyCodeRequest); this.addDefaultRole(savedUser.getId(), smsVerifyCodeRequest);
} }
if (success) { if (success) {
@ -237,109 +259,150 @@ public class SmsVerifyCodeController {
} }
} }
/**
* 给用户分配流域/电站数据权限 + 默认角色
* <p>
* 逻辑说明
* 1. 收集前端传入的电站编码按流域分组
* 2. 如果用户选了某流域的所有电站 保存流域权限RVCD
* 3. 如果用户只选了某流域的部分电站 逐个保存电站权限STATION
* 4. 数据库中查不到的孤立电站编码 直接保存电站权限
* <p>
* 示例
* - 选了 A流域全部6个电站 + B流域全部3个电站 + C流域1个电站
* 两条 RVCDAB+ 一条 STATIONC的电站
*/
private boolean addDefaultRole(String userId, SmsVerifyCodeRequest smsVerifyCodeRequest) { private boolean addDefaultRole(String userId, SmsVerifyCodeRequest smsVerifyCodeRequest) {
if (userId == null || userId.isEmpty()) { if (userId == null || userId.isEmpty()) {
return false; return false;
} }
// 1. 收集前端传入的电站编码
String stationCode = smsVerifyCodeRequest.getStationCode(); String stationCode = smsVerifyCodeRequest.getStationCode();
String rvcdCode = smsVerifyCodeRequest.getRvcdCode();
Set<String> selectedStationCodes = new HashSet<>(); Set<String> selectedStationCodes = new HashSet<>();
if (StringUtils.isNotEmpty(stationCode)) { if (StringUtils.isNotEmpty(stationCode)) {
selectedStationCodes.addAll(Arrays.asList(stationCode.split(","))); selectedStationCodes.addAll(Arrays.asList(stationCode.split(",")));
} }
Set<String> selectedBasinCodes = new HashSet<>(); // 2. 如果没有选择任何电站
if (StringUtils.isNotEmpty(rvcdCode)) { if (selectedStationCodes.isEmpty()) {
selectedBasinCodes.addAll(Arrays.asList(rvcdCode.split(","))); // 如果只传了流域直接保存流域权限
String rvcdCode = smsVerifyCodeRequest.getRvcdCode();
if (StringUtils.isNotEmpty(rvcdCode)) {
for (String basinCode : rvcdCode.split(",")) {
if (StringUtils.isNotEmpty(basinCode)) {
addDataScope(userId, "RVCD", basinCode);
}
}
}
assignRoleToUser(userId);
return true;
} }
// Set<String> addedStationCodes = new HashSet<>(); // 3. 批量查询所有选中电站的工程信息获取每个电站所属的流域
List<SdEngInfoBH> selectedStations = engInfoBHService.lambdaQuery()
.in(SdEngInfoBH::getStcd, selectedStationCodes)
.list();
for (String basinCode : selectedBasinCodes) { // 已通过电站权限处理过的电站编码
if (StringUtils.isEmpty(basinCode)) { Set<String> processedStationCodes = new HashSet<>();
continue; // 已通过电站分组处理过的流域编码用于后续差集判断
Set<String> processedBasinCodes = new HashSet<>();
if (!selectedStations.isEmpty()) {
// 4. 按流域分组{rvcd -> Set<stcd>}
Map<String, Set<String>> basinToStations = new LinkedHashMap<>();
for (SdEngInfoBH station : selectedStations) {
String reachcd = station.getReachcd();
String stcd = station.getStcd();
if (StrUtil.isBlank(reachcd)) {
// 无流域归属的电站直接保存电站权限
addDataScope(userId, "STATION", stcd);
processedStationCodes.add(stcd);
continue;
}
basinToStations.computeIfAbsent(reachcd, k -> new HashSet<>()).add(stcd);
} }
List<SdEngInfoBH> allStationsInBasin = engInfoBHService.lambdaQuery() // 5. 对每个流域判断用户是否选中了该流域的全部电站
.eq(SdEngInfoBH::getRvcd, basinCode) for (Map.Entry<String, Set<String>> entry : basinToStations.entrySet()) {
.list(); String basinCode = entry.getKey();
Set<String> selectedInThisBasin = entry.getValue();
if (allStationsInBasin == null || allStationsInBasin.isEmpty()) { // 查询该流域下的所有电站
SysUserDataScope scope = new SysUserDataScope(); List<SdEngInfoBH> allStationsInBasin = engInfoBHService.lambdaQuery()
scope.setUserId(userId); .eq(SdEngInfoBH::getReachcd, basinCode)
scope.setOrgType("RVCD"); .list();
scope.setOrgId(basinCode); Set<String> allStationCodesInBasin = allStationsInBasin.stream()
scope.setStatus(1); .map(SdEngInfoBH::getStcd)
scope.setPermissionType("READ");
sysUserDataScopeService.addDataScope(scope);
continue;
}
Set<String> allStationCodesInBasin = allStationsInBasin.stream()
.map(SdEngInfoBH::getStcd)
.collect(Collectors.toSet());
boolean allStationsSelected = allStationCodesInBasin.containsAll(selectedStationCodes)
&& selectedStationCodes.containsAll(allStationCodesInBasin);
if (allStationsSelected) {
SysUserDataScope scope = new SysUserDataScope();
scope.setUserId(userId);
scope.setOrgType("RVCD");
scope.setOrgId(basinCode);
scope.setStatus(1);
scope.setPermissionType("READ");
sysUserDataScopeService.addDataScope(scope);
// addedStationCodes.add(basinCode);
} else {
Set<String> stationsInBasinAndSelected = allStationCodesInBasin.stream()
.filter(selectedStationCodes::contains)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
for (String stationCd : stationsInBasinAndSelected) { if (allStationCodesInBasin.equals(selectedInThisBasin)) {
SysUserDataScope scope = new SysUserDataScope(); // 全选 保存流域权限
scope.setUserId(userId); addDataScope(userId, "RVCD", basinCode);
scope.setOrgType("STATION"); } else {
scope.setOrgId(stationCd); // 部分选 逐个保存电站权限
scope.setStatus(1); for (String stcd : selectedInThisBasin) {
scope.setPermissionType("READ"); addDataScope(userId, "STATION", stcd);
sysUserDataScopeService.addDataScope(scope); }
// addedStationCodes.add(stationCd); }
processedStationCodes.addAll(selectedInThisBasin);
processedBasinCodes.add(basinCode);
}
}
// 6. 处理数据库中查不到的电站编码孤立的电站直接保存电站权限
for (String stcd : selectedStationCodes) {
if (!processedStationCodes.contains(stcd)) {
addDataScope(userId, "STATION", stcd);
}
}
// 7. 处理前端传了流域但该流域下未匹配到任何选中电站的情况直接保存流域权限
String rvcdCode = smsVerifyCodeRequest.getRvcdCode();
if (StringUtils.isNotEmpty(rvcdCode)) {
for (String basinCode : rvcdCode.split(",")) {
if (StringUtils.isNotEmpty(basinCode) && !processedBasinCodes.contains(basinCode)) {
addDataScope(userId, "RVCD", basinCode);
} }
} }
} }
// Set<String> standaloneStations = selectedStationCodes.stream() // 8. 分配默认角色
// .filter(code -> !addedStationCodes.contains(code)) assignRoleToUser(userId);
// .collect(Collectors.toSet());
//
// for (String stationCd : standaloneStations) {
// if (StringUtils.isEmpty(stationCd)) {
// continue;
// }
// SysUserDataScope scope = new SysUserDataScope();
// scope.setUserId(userId);
// scope.setOrgType("STATION");
// scope.setOrgId(stationCd);
// scope.setStatus(1);
// scope.setPermissionType("READ");
// sysUserDataScopeService.addDataScope(scope);
// }
SysUser user = new SysUser();
user.setId(userId);
userService.updateUserRoles( user,"c13481a486c9ee559cf305284df4d207");
// 加上角色权限
return true; return true;
} }
/**
* 保存一条数据权限
*/
private void addDataScope(String userId, String orgType, String orgId) {
SysUserDataScope scope = new SysUserDataScope();
scope.setUserId(userId);
scope.setOrgType(orgType);
scope.setOrgId(orgId);
scope.setStatus(1);
scope.setPermissionType("READ");
sysUserDataScopeService.addDataScope(scope);
}
/**
* 给用户分配默认角色
*/
private void assignRoleToUser(String userId) {
SysUser user = new SysUser();
SysRole aDefault = roleMapper.selectOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getCustom1, "default"));
String roleids = aDefault == null ? null : aDefault.getId();
user.setId(userId);
userService.updateUserRoles(user, roleids);
}
/** /**
* 找回密码 * 找回密码
*/ */
@PostMapping("/resetPassword") @PostMapping("/resetPassword")
@Operation(summary = "找回密码") @Operation(summary = "找回密码")
public ResponseResult resetPassword(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { public ResponseResult resetPassword(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
String password = smsVerifyCodeRequest.getPassword(); String password = smsVerifyCodeRequest.getPassword();
String phone = smsVerifyCodeRequest.getPhone(); String phone = smsVerifyCodeRequest.getPhone();
String code = smsVerifyCodeRequest.getCode(); String code = smsVerifyCodeRequest.getCode();
@ -353,12 +416,12 @@ public class SmsVerifyCodeController {
return ResponseResult.error("新密码不能为空"); return ResponseResult.error("新密码不能为空");
} }
boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_FIND_PASSWORD,tenantId); boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_FIND_PASSWORD, tenantId);
if (!verified) { if (!verified) {
return ResponseResult.error("验证码错误或已过期"); return ResponseResult.error("验证码错误或已过期");
} }
SysUser existUser = userService.getUserByPhone(phone,tenantId); SysUser existUser = userService.getUserByPhone(phone, tenantId);
if (existUser == null) { if (existUser == null) {
return ResponseResult.error("该手机号未注册"); return ResponseResult.error("该手机号未注册");
} }
@ -383,11 +446,11 @@ public class SmsVerifyCodeController {
*/ */
@PostMapping("/verifyCode") @PostMapping("/verifyCode")
@Operation(summary = "验证验证码") @Operation(summary = "验证验证码")
public ResponseResult verifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { public ResponseResult verifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
String phone = smsVerifyCodeRequest.getPhone(); String phone = smsVerifyCodeRequest.getPhone();
String code = smsVerifyCodeRequest.getCode(); String code = smsVerifyCodeRequest.getCode();
Integer type = smsVerifyCodeRequest.getType(); Integer type = smsVerifyCodeRequest.getType();
boolean valid = smsVerifyCodeService.verifyCode(phone, code, type,tenantId); boolean valid = smsVerifyCodeService.verifyCode(phone, code, type, tenantId);
if (valid) { if (valid) {
return ResponseResult.success(); return ResponseResult.success();
} else { } else {
@ -400,7 +463,7 @@ public class SmsVerifyCodeController {
*/ */
@PostMapping("/login") @PostMapping("/login")
@Operation(summary = "短信验证码登录") @Operation(summary = "短信验证码登录")
public ResponseResult smsLogin(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { public ResponseResult smsLogin(@RequestHeader(value = "Tenant_id", required = false) String tenantId, @RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
String phone = smsVerifyCodeRequest.getPhone(); String phone = smsVerifyCodeRequest.getPhone();
String code = smsVerifyCodeRequest.getCode(); String code = smsVerifyCodeRequest.getCode();
if (phone == null || phone.isEmpty()) { if (phone == null || phone.isEmpty()) {
@ -410,12 +473,12 @@ public class SmsVerifyCodeController {
return ResponseResult.error("验证码不能为空"); return ResponseResult.error("验证码不能为空");
} }
boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_LOGIN,tenantId); boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_LOGIN, tenantId);
if (!verified) { if (!verified) {
return ResponseResult.error("验证码错误或已过期"); return ResponseResult.error("验证码错误或已过期");
} }
SysUser user = userService.getUserByPhone(phone,tenantId); SysUser user = userService.getUserByPhone(phone, tenantId);
if (user == null) { if (user == null) {
return ResponseResult.error("该手机号未注册"); return ResponseResult.error("该手机号未注册");
} }
@ -441,9 +504,15 @@ public class SmsVerifyCodeController {
loginUser.setUser(user); loginUser.setUser(user);
loginUser.setUsername(user.getUsername()); loginUser.setUsername(user.getUsername());
//Todo 根据用户查询权限信息 添加到LoginUser中 //Todo 根据用户查询权限信息 添加到LoginUser中
List<String> permissions = // 加载权限超级管理员加载全部权限普通用户按门户过滤
sysMenuMapper.selectPermsByUserId(user.getId()); boolean isSuperAdmin = userService.isSuperAdmin(user.getId());
loginUser.setPermissions( permissions); List<String> permissions;
if (isSuperAdmin) {
permissions = sysMenuMapper.selectPermsByUserId(user.getId(), null);
} else {
permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId);
}
loginUser.setPermissions(permissions);
HttpServletRequest request = RequestHolder.getHttpServletRequest(); HttpServletRequest request = RequestHolder.getHttpServletRequest();
SysLog sysLog = new SysLog(); SysLog sysLog = new SysLog();
sysLog.setUsercode(user.getUsername()); sysLog.setUsercode(user.getUsername());

View File

@ -101,6 +101,21 @@ public class SysMenuController {
return sysMenuService.permissionAssignment(code, roleId, StrUtil.trimToNull(tenantId)); return sysMenuService.permissionAssignment(code, roleId, StrUtil.trimToNull(tenantId));
} }
/***********************************
* 用途说明权限分配按系统分组附带系统标识和名称
* 参数说明
* roleId 角色ID
* 返回值说明: [{"systemCode":"1","systemName":"Web端","menus":[...]}, ...]
* 系统名称通过字典 PLATFORM_TENANT 获取
***********************************/
@PostMapping("/permissionAssignmentGrouped")
@Operation(summary = "获取分配权限-按系统分组(含系统标识和名称)")
@ResponseBody
public List<Map<String, Object>> permissionAssignmentGrouped(String roleId,
String tenantId) {
return sysMenuService.permissionAssignmentGrouped(roleId, StrUtil.trimToNull(tenantId));
}
/********************************** /**********************************
* 用途说明: 获取当前用户菜单结构树 * 用途说明: 获取当前用户菜单结构树
* 参数说明 * 参数说明
@ -111,11 +126,12 @@ public class SysMenuController {
@ResponseBody @ResponseBody
public List<Map<String, Object>> getMenuTreeByUser(@RequestHeader(value = "Tenant_id", required = false) String tenantId) { public List<Map<String, Object>> getMenuTreeByUser(@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
SysUser userInfo = userService.getUserInfo(); SysUser userInfo = userService.getUserInfo();
boolean superAdmin = userService.isSuperAdmin(userInfo.getId());
String id = ""; String id = "";
if (0 != userInfo.getUsertype()) { if (0 != userInfo.getUsertype() && !superAdmin) {
id = userInfo.getId(); id = userInfo.getId();
} }
return sysMenuService.getMenuTree(id, StrUtil.isNotBlank(tenantId) ? StrUtil.trimToNull(tenantId) : userInfo.getTenantId()); return sysMenuService.getMenuTree(id, tenantId);
} }
/*********************************** /***********************************
@ -148,7 +164,7 @@ public class SysMenuController {
@ResponseBody @ResponseBody
public ResponseResult addMenu(@RequestBody SysMenu sysMenu, public ResponseResult addMenu(@RequestBody SysMenu sysMenu,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
sysMenu.setTenantId(StrUtil.trimToNull(tenantId)); // sysMenu.setTenantId(StrUtil.trimToNull(tenantId));
if(StrUtil.isBlank(sysMenu.getTenantId())){ if(StrUtil.isBlank(sysMenu.getTenantId())){
sysMenu.setTenantId(sysMenu.getSystemcode()); sysMenu.setTenantId(sysMenu.getSystemcode());
} }
@ -178,7 +194,7 @@ public class SysMenuController {
if (sysMenuService.getOne(queryWrapper) == null) { if (sysMenuService.getOne(queryWrapper) == null) {
return ResponseResult.error("未找到对应租户的菜单"); return ResponseResult.error("未找到对应租户的菜单");
} }
sysMenu.setTenantId(StrUtil.trimToNull(tenantId)); // sysMenu.setTenantId(StrUtil.trimToNull(tenantId));
if(StrUtil.isBlank(sysMenu.getTenantId())){ if(StrUtil.isBlank(sysMenu.getTenantId())){
sysMenu.setTenantId(sysMenu.getSystemcode()); sysMenu.setTenantId(sysMenu.getSystemcode());
} }
@ -206,8 +222,8 @@ public class SysMenuController {
public ResponseResult deleteIcon(@RequestParam String id, public ResponseResult deleteIcon(@RequestParam String id,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysMenu::getId, id) queryWrapper.eq(SysMenu::getId, id);
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
if (sysMenuService.getOne(queryWrapper) == null) { if (sysMenuService.getOne(queryWrapper) == null) {
return ResponseResult.error("未找到对应租户的菜单"); return ResponseResult.error("未找到对应租户的菜单");
} }
@ -234,7 +250,7 @@ public class SysMenuController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
UpdateWrapper<SysMenu> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<SysMenu> updateWrapper = new UpdateWrapper<>();
//根据id 修改是否显示 最近修改人最近修改时间 //根据id 修改是否显示 最近修改人最近修改时间
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("isdisplay", isdisplay).set( updateWrapper.eq("id", id).set("isdisplay", isdisplay).set(
"lastmodifier", userService.getUsername()).set( "lastmodifier", userService.getUsername()).set(
"lastmodifydate", "lastmodifydate",
new Timestamp(System.currentTimeMillis())); new Timestamp(System.currentTimeMillis()));
@ -262,12 +278,12 @@ public class SysMenuController {
@RequestParam int orderno, @RequestParam int orderno,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysMenu::getId, id) queryWrapper.eq(SysMenu::getId, id);
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
if (sysMenuService.getOne(queryWrapper) == null) { if (sysMenuService.getOne(queryWrapper) == null) {
return ResponseResult.error("未找到对应租户的菜单"); return ResponseResult.error("未找到对应租户的菜单");
} }
boolean ok = sysMenuService.moveOrderno(parentid, id, orderno, StrUtil.trimToNull(tenantId)); boolean ok = sysMenuService.moveOrderno(parentid, id, orderno, null);
if (ok) { if (ok) {
return ResponseResult.success(); return ResponseResult.success();
} else { } else {
@ -288,8 +304,8 @@ public class SysMenuController {
public ResponseResult deleteById(@RequestParam String id, public ResponseResult deleteById(@RequestParam String id,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysMenu::getId, id) queryWrapper.eq(SysMenu::getId, id);
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
if (sysMenuService.getOne(queryWrapper) == null) { if (sysMenuService.getOne(queryWrapper) == null) {
return ResponseResult.error("未找到对应租户的菜单"); return ResponseResult.error("未找到对应租户的菜单");
} }
@ -321,11 +337,11 @@ public class SysMenuController {
return ResponseResult.error("切换失败!"); return ResponseResult.error("切换失败!");
} }
LambdaQueryWrapper<SysMenu> fromWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysMenu> fromWrapper = new LambdaQueryWrapper<>();
fromWrapper.eq(SysMenu::getId, fromId) fromWrapper.eq(SysMenu::getId, fromId);
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); // fromWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
LambdaQueryWrapper<SysMenu> toWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysMenu> toWrapper = new LambdaQueryWrapper<>();
toWrapper.eq(SysMenu::getId, toId) toWrapper.eq(SysMenu::getId, toId);
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); // toWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
if (sysMenuService.getOne(fromWrapper) == null || sysMenuService.getOne(toWrapper) == null) { if (sysMenuService.getOne(fromWrapper) == null || sysMenuService.getOne(toWrapper) == null) {
return ResponseResult.error("存在不属于当前租户的菜单"); return ResponseResult.error("存在不属于当前租户的菜单");
} }
@ -350,8 +366,8 @@ public class SysMenuController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) throws FileNotFoundException { @RequestHeader(value = "Tenant_id", required = false) String tenantId) throws FileNotFoundException {
if (StrUtil.isNotBlank(menuId)) { if (StrUtil.isNotBlank(menuId)) {
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysMenu::getId, menuId) queryWrapper.eq(SysMenu::getId, menuId);
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
SysMenu sysMenu = sysMenuService.getOne(queryWrapper); SysMenu sysMenu = sysMenuService.getOne(queryWrapper);
if (sysMenu == null) { if (sysMenu == null) {
return ResponseResult.error("未找到对应租户的菜单"); return ResponseResult.error("未找到对应租户的菜单");

View File

@ -53,7 +53,7 @@ public class SysOrganizationController {
@ResponseBody @ResponseBody
public List<Map<String, Object>> getOrgScopeTree(String roleId, public List<Map<String, Object>> getOrgScopeTree(String roleId,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
return organizationService.getOrgScopeTree(roleId, StrUtil.trimToNull(tenantId)); return organizationService.getOrgScopeTree(roleId, null);
} }
/*********************************** /***********************************
@ -67,7 +67,7 @@ public class SysOrganizationController {
public List<Map<String, Object>> getOrgTree(String parentid, public List<Map<String, Object>> getOrgTree(String parentid,
String params, String params,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
return organizationService.getOrgTree(parentid, params, StrUtil.trimToNull(tenantId)); return organizationService.getOrgTree(parentid, params, null);
} }
/*********************************** /***********************************
@ -85,7 +85,7 @@ public class SysOrganizationController {
return ResponseResult.error("查询失败!"); return ResponseResult.error("查询失败!");
} }
List<SysOrganization> sysOrganizations = List<SysOrganization> sysOrganizations =
organizationService.getOrganizationById(id, orgName, StrUtil.trimToNull(tenantId)); organizationService.getOrganizationById(id, orgName, null);
return ResponseResult.successData(sysOrganizations); return ResponseResult.successData(sysOrganizations);
} }
@ -102,8 +102,8 @@ public class SysOrganizationController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysOrganization> queryWrapper = LambdaQueryWrapper<SysOrganization> queryWrapper =
new LambdaQueryWrapper<>(); new LambdaQueryWrapper<>();
queryWrapper.eq(SysOrganization::getId, id) queryWrapper.eq(SysOrganization::getId, id);
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId));
SysOrganization sysOrganization = organizationService.getOne(queryWrapper); SysOrganization sysOrganization = organizationService.getOne(queryWrapper);
return ResponseResult.successData(sysOrganization); return ResponseResult.successData(sysOrganization);
} }
@ -127,7 +127,7 @@ public class SysOrganizationController {
if("".equals(sysOrganization.getId())){ if("".equals(sysOrganization.getId())){
sysOrganization.setId(null); sysOrganization.setId(null);
} }
sysOrganization.setTenantId(StrUtil.trimToNull(tenantId)); // sysOrganization.setTenantId(StrUtil.trimToNull(tenantId));
//填写 当前用户名称 //填写 当前用户名称
sysOrganization.setLastmodifier(userService.getUsername()); sysOrganization.setLastmodifier(userService.getUsername());
//填写 当前日期 //填写 当前日期
@ -155,12 +155,12 @@ public class SysOrganizationController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysOrganization> queryWrapper = LambdaQueryWrapper<SysOrganization> queryWrapper =
new LambdaQueryWrapper<>(); new LambdaQueryWrapper<>();
queryWrapper.eq(SysOrganization::getId, sysOrganization.getId()) queryWrapper.eq(SysOrganization::getId, sysOrganization.getId());
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId));
if (organizationService.getOne(queryWrapper) == null) { if (organizationService.getOne(queryWrapper) == null) {
return ResponseResult.error("未找到对应租户的组织"); return ResponseResult.error("未找到对应租户的组织");
} }
sysOrganization.setTenantId(StrUtil.trimToNull(tenantId)); // sysOrganization.setTenantId(StrUtil.trimToNull(tenantId));
//填写 当前用户名称 //填写 当前用户名称
sysOrganization.setLastmodifier(userService.getUsername()); sysOrganization.setLastmodifier(userService.getUsername());
//填写 当前日期 //填写 当前日期
@ -189,7 +189,7 @@ public class SysOrganizationController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
UpdateWrapper<SysOrganization> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<SysOrganization> updateWrapper = new UpdateWrapper<>();
//根据id 修改是否有效最近修改人最近修改时间 //根据id 修改是否有效最近修改人最近修改时间
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("isvaild", isvaild).set("lastmodifier" updateWrapper.eq("id", id).set("isvaild", isvaild).set("lastmodifier"
, userService.getUsername()).set("lastmodifydate", , userService.getUsername()).set("lastmodifydate",
new Timestamp(System.currentTimeMillis())); new Timestamp(System.currentTimeMillis()));
boolean isOk = organizationService.update(updateWrapper); boolean isOk = organizationService.update(updateWrapper);
@ -216,28 +216,24 @@ public class SysOrganizationController {
for (String orgId : orgIds) { for (String orgId : orgIds) {
LambdaQueryWrapper<SysOrganization> currentWrapper = LambdaQueryWrapper<SysOrganization> currentWrapper =
new LambdaQueryWrapper<>(); new LambdaQueryWrapper<>();
currentWrapper.eq(SysOrganization::getId, orgId) currentWrapper.eq(SysOrganization::getId, orgId);
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)); // currentWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId));
if (organizationService.getOne(currentWrapper) == null) { if (organizationService.getOne(currentWrapper) == null) {
return ResponseResult.error("存在不属于当前租户的组织"); return ResponseResult.error("不存在对应组织");
} }
LambdaQueryWrapper<SysOrganization> queryWrapper = LambdaQueryWrapper<SysOrganization> queryWrapper = new LambdaQueryWrapper<>();
new LambdaQueryWrapper<>(); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId))
List<SysOrganization> list = List<SysOrganization> list =
organizationService.list(queryWrapper.eq(SysOrganization::getParentid, orgId) organizationService.list(queryWrapper.eq(SysOrganization::getParentid, orgId));
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)));
List<String> ids = List<String> ids =
list.stream().map(SysOrganization::getId).collect(Collectors.toList()); list.stream().map(SysOrganization::getId).toList();
boolean isOk = organizationService.remove(new LambdaQueryWrapper<SysOrganization>() boolean isOk = organizationService.remove(new LambdaQueryWrapper<SysOrganization>()
.eq(SysOrganization::getId, orgId) .eq(SysOrganization::getId, orgId));
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)));
if (!isOk) { if (!isOk) {
continue; continue;
} }
for (String oid : ids) { for (String oid : ids) {
organizationService.remove(new LambdaQueryWrapper<SysOrganization>() organizationService.remove(new LambdaQueryWrapper<SysOrganization>().eq(SysOrganization::getId, oid));
.eq(SysOrganization::getId, oid)
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)));
} }
} }
return ResponseResult.success(); return ResponseResult.success();

View File

@ -54,8 +54,23 @@ public class SysRoleController {
@Operation(summary = "查询所有角色") @Operation(summary = "查询所有角色")
@ResponseBody @ResponseBody
public List<SysRole> list(@RequestParam(required = false) String rolename, public List<SysRole> list(@RequestParam(required = false) String rolename,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestParam(required = false) String tenantId) {
return roleService.selectRoleList(rolename, StrUtil.trimToNull(tenantId)); return roleService.selectRoleList(rolename, tenantId);
}
/***********************************
* 用途说明按门户分组查询角色门户 角色两层结构
* 参数说明
* rolename 角色名称可选模糊搜索
* 返回值说明: [{"tenantId":"...","tenantName":"水利门户","roles":[...]}, ...]
* 门户中文名通过字典 PLATFORM_TENANT 获取
***********************************/
@PostMapping("/listGroupedByTenant")
@Operation(summary = "按门户分组查询角色(含门户中文名)")
@ResponseBody
public List<Map<String, Object>> listGroupedByTenant(@RequestParam(required = false) String rolename,
@RequestParam(required = false) String tenantId) {
return roleService.selectRoleListGroupedByTenant(tenantId,rolename);
} }
/*********************************** /***********************************
@ -70,8 +85,8 @@ public class SysRoleController {
public ResponseResult getOneById(String id, public ResponseResult getOneById(String id,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysRole::getId, id) queryWrapper.eq(SysRole::getId, id);
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId)); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
SysRole sysRole = roleService.getOne(queryWrapper); SysRole sysRole = roleService.getOne(queryWrapper);
return ResponseResult.successData(sysRole); return ResponseResult.successData(sysRole);
} }
@ -88,7 +103,7 @@ public class SysRoleController {
@ResponseBody @ResponseBody
public ResponseResult addRole(@RequestBody SysRole sysRole, public ResponseResult addRole(@RequestBody SysRole sysRole,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
sysRole.setTenantId(StrUtil.trimToNull(tenantId)); // sysRole.setTenantId(StrUtil.trimToNull(tenantId));
boolean isOk = roleService.addRole(sysRole); boolean isOk = roleService.addRole(sysRole);
if (isOk) { if (isOk) {
return ResponseResult.success(); return ResponseResult.success();
@ -113,7 +128,7 @@ public class SysRoleController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
//根据id 更新权限最近修改人最近修改时间 //根据id 更新权限最近修改人最近修改时间
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("optscope", optscope).set( updateWrapper.eq("id", id).set("optscope", optscope).set(
"lastmodifier", userService.getUsername()).set( "lastmodifier", userService.getUsername()).set(
"lastmodifydate", LocalDateTime.now()); "lastmodifydate", LocalDateTime.now());
boolean ok = roleService.update(updateWrapper); boolean ok = roleService.update(updateWrapper);
@ -141,8 +156,7 @@ public class SysRoleController {
return ResponseResult.error("参数为空"); return ResponseResult.error("参数为空");
} }
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysRole::getId, id) queryWrapper.eq(SysRole::getId, id);
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
if (roleService.getOne(queryWrapper) == null) { if (roleService.getOne(queryWrapper) == null) {
return ResponseResult.error("未找到对应租户的角色"); return ResponseResult.error("未找到对应租户的角色");
} }
@ -158,8 +172,7 @@ public class SysRoleController {
return ResponseResult.success(); return ResponseResult.success();
} }
long menuCount = sysMenuService.count(new LambdaQueryWrapper<SysMenu>() long menuCount = sysMenuService.count(new LambdaQueryWrapper<SysMenu>()
.in(SysMenu::getId, menuIdList) .in(SysMenu::getId, menuIdList));
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)));
if (menuCount != menuIdList.size()) { if (menuCount != menuIdList.size()) {
return ResponseResult.error("存在不属于当前租户的菜单"); return ResponseResult.error("存在不属于当前租户的菜单");
} }
@ -188,7 +201,7 @@ public class SysRoleController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
//根据id 更新组织范围最近修改人最近修改时间 //根据id 更新组织范围最近修改人最近修改时间
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("orgscope", orgscope).set( updateWrapper.eq("id", id).set("orgscope", orgscope).set(
"lastmodifier", userService.getUsername()).set( "lastmodifier", userService.getUsername()).set(
"lastmodifydate", LocalDateTime.now()); "lastmodifydate", LocalDateTime.now());
boolean ok = roleService.update(updateWrapper); boolean ok = roleService.update(updateWrapper);
@ -215,7 +228,7 @@ public class SysRoleController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
//根据id 更新业务范围最近修改人最近修改时间 //根据id 更新业务范围最近修改人最近修改时间
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("busscope", busscope).set( updateWrapper.eq("id", id).set("busscope", busscope).set(
"lastmodifier", userService.getUsername()).set( "lastmodifier", userService.getUsername()).set(
"lastmodifydate", LocalDateTime.now()); "lastmodifydate", LocalDateTime.now());
boolean ok = roleService.update(updateWrapper); boolean ok = roleService.update(updateWrapper);
@ -240,8 +253,7 @@ public class SysRoleController {
public ResponseResult setRoleUsers(String roleid, String userids, public ResponseResult setRoleUsers(String roleid, String userids,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
roleWrapper.eq(SysRole::getId, roleid) roleWrapper.eq(SysRole::getId, roleid);
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
if (roleService.getOne(roleWrapper) == null) { if (roleService.getOne(roleWrapper) == null) {
return ResponseResult.error("未找到对应租户的角色"); return ResponseResult.error("未找到对应租户的角色");
} }
@ -270,8 +282,7 @@ public class SysRoleController {
@RequestParam String userids, @RequestParam String userids,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
roleWrapper.eq(SysRole::getId, roleid) roleWrapper.eq(SysRole::getId, roleid);
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
if (roleService.getOne(roleWrapper) == null) { if (roleService.getOne(roleWrapper) == null) {
return ResponseResult.error("未找到对应租户的角色"); return ResponseResult.error("未找到对应租户的角色");
} }
@ -298,7 +309,7 @@ public class SysRoleController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
//根据id 更新业务范围最近修改人最近修改时间 //根据id 更新业务范围最近修改人最近修改时间
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("isvaild", isvaild).set("lastmodifier" updateWrapper.eq("id", id).set("isvaild", isvaild).set("lastmodifier"
, userService.getUsername()).set("lastmodifydate", , userService.getUsername()).set("lastmodifydate",
LocalDateTime.now()); LocalDateTime.now());
boolean ok = roleService.update(updateWrapper); boolean ok = roleService.update(updateWrapper);
@ -321,8 +332,7 @@ public class SysRoleController {
public ResponseResult updateById(@RequestBody SysRole sysRole, public ResponseResult updateById(@RequestBody SysRole sysRole,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysRole::getId, sysRole.getId()) queryWrapper.eq(SysRole::getId, sysRole.getId());
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
if (roleService.getOne(queryWrapper) == null) { if (roleService.getOne(queryWrapper) == null) {
return ResponseResult.error("未找到对应租户的角色"); return ResponseResult.error("未找到对应租户的角色");
} }
@ -354,8 +364,7 @@ public class SysRoleController {
String[] roleIds = id.split(","); String[] roleIds = id.split(",");
for (String roleId : roleIds) { for (String roleId : roleIds) {
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysRole::getId, roleId) queryWrapper.eq(SysRole::getId, roleId);
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
if (roleService.getOne(queryWrapper) == null) { if (roleService.getOne(queryWrapper) == null) {
return ResponseResult.error("存在不属于当前租户的角色"); return ResponseResult.error("存在不属于当前租户的角色");
} }
@ -383,7 +392,7 @@ public class SysRoleController {
String rolename, String isvaild, String rolename, String isvaild,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
return roleService.listRoleUsers(orgid, username, status, level, return roleService.listRoleUsers(orgid, username, status, level,
rolename, isvaild, StrUtil.trimToNull(tenantId)); rolename, isvaild, null);
} }
} }

View File

@ -17,6 +17,7 @@ import org.springframework.web.multipart.MultipartFile;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -45,7 +46,7 @@ public class UserController {
public ResponseResult addUser(@RequestBody SysUser user, public ResponseResult addUser(@RequestBody SysUser user,
String roleids, String roleids,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
user.setTenantId(StrUtil.trimToNull(tenantId)); // user.setTenantId(StrUtil.trimToNull(tenantId));
Map reslut = userService.addUser(user, roleids); Map reslut = userService.addUser(user, roleids);
return ResponseResult.successData(reslut); return ResponseResult.successData(reslut);
} }
@ -60,7 +61,7 @@ public class UserController {
if (StrUtil.isEmpty(user.getId())) { if (StrUtil.isEmpty(user.getId())) {
return ResponseResult.error("没有用户ID"); return ResponseResult.error("没有用户ID");
} }
user.setTenantId(StrUtil.trimToNull(tenantId)); // user.setTenantId(StrUtil.trimToNull(tenantId));
//填写 当前用户名称 //填写 当前用户名称
user.setLastmodifier(userService.getUsername()); user.setLastmodifier(userService.getUsername());
//填写 当前日期 //填写 当前日期
@ -79,7 +80,7 @@ public class UserController {
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
Page<SysUser> mapPage = userService.queryUsers(orgid, Page<SysUser> mapPage = userService.queryUsers(orgid,
username, StrUtil.trimToNull(tenantId), page); username, null, page);
return ResponseResult.successData(mapPage); return ResponseResult.successData(mapPage);
} }
@ -115,8 +116,8 @@ public class UserController {
public ResponseResult queryUserById(String id, public ResponseResult queryUserById(String id,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUser::getId, id) queryWrapper.eq(SysUser::getId, id);
.eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, StrUtil.trim(tenantId)); // .eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, StrUtil.trim(tenantId));
SysUser user = userService.getOne(queryWrapper); SysUser user = userService.getOne(queryWrapper);
return ResponseResult.successData(user); return ResponseResult.successData(user);
} }
@ -248,7 +249,57 @@ public class UserController {
String name, String name,
String regStatus, String regStatus,
@RequestHeader(value = "Tenant_id", required = false) String tenantId) { @RequestHeader(value = "Tenant_id", required = false) String tenantId) {
Page<SysUser> result = userService.queryPendingAuditUsers(page, name, regStatus, StrUtil.trimToNull(tenantId)); Page<SysUser> result = userService.queryPendingAuditUsers(page, name, regStatus, null);
return ResponseResult.successData(result); return ResponseResult.successData(result);
} }
// ==================== 多门户管理 ====================
/***********************************
* 用途说明为用户分配门户
* 参数说明 userId 用户ID, tenantIds 门户ID列表逗号分隔
************************************/
@Log(module = "系统用户", value = "分配门户")
@PostMapping("/assignTenant")
@Operation(summary = "为用户分配门户")
@ResponseBody
public ResponseResult assignTenant(String userId, String tenantIds) {
if (StrUtil.isBlank(userId) || StrUtil.isBlank(tenantIds)) {
return ResponseResult.error("用户ID和门户ID不能为空");
}
List<String> tenantIdList = List.of(tenantIds.split(","));
userService.assignTenantsToUser(userId, tenantIdList);
return ResponseResult.success();
}
/***********************************
* 用途说明移除用户的门户关联
* 参数说明 userId 用户ID, tenantId 门户ID
************************************/
@Log(module = "系统用户", value = "移除门户")
@PostMapping("/removeTenant")
@Operation(summary = "移除用户的门户关联")
@ResponseBody
public ResponseResult removeTenant(String userId, String tenantId) {
if (StrUtil.isBlank(userId) || StrUtil.isBlank(tenantId)) {
return ResponseResult.error("用户ID和门户ID不能为空");
}
userService.removeTenantFromUser(userId, tenantId);
return ResponseResult.success();
}
/***********************************
* 用途说明获取用户关联的门户列表
* 参数说明 userId 用户ID
************************************/
@GetMapping("/getUserTenants")
@Operation(summary = "获取用户关联的门户列表")
@ResponseBody
public ResponseResult getUserTenants(String userId) {
if (StrUtil.isBlank(userId)) {
return ResponseResult.error("用户ID不能为空");
}
List<String> tenants = userService.getUserTenants(userId);
return ResponseResult.successData(tenants);
}
} }

View File

@ -22,19 +22,44 @@ public class LoginUser implements UserDetails {
private String username; private String username;
private List<String> permissions=new ArrayList<>(); private List<String> permissions = new ArrayList<>();
/**
* 当前登录的门户ID
*/
private String currentTenantId;
/**
* 用户可访问的门户ID列表用于门户切换
*/
private List<String> accessibleTenantIds;
/**
* 是否超级管理员LEVEL=1
*/
private boolean superAdmin;
/** /**
* 自定义构造函数如果需要特殊逻辑 * 自定义构造函数如果需要特殊逻辑
*/ */
public LoginUser(SysUser user, List<String> permissions) { public LoginUser(SysUser user, List<String> permissions) {
this.user = user; this.user = user;
// 4. 增加非空判断确保 permissions 永远不为 null
if (permissions != null) { if (permissions != null) {
this.permissions = permissions; this.permissions = permissions;
} }
} }
public LoginUser(SysUser user, List<String> permissions,
String currentTenantId, List<String> accessibleTenantIds, boolean superAdmin) {
this.user = user;
if (permissions != null) {
this.permissions = permissions;
}
this.currentTenantId = currentTenantId;
this.accessibleTenantIds = accessibleTenantIds;
this.superAdmin = superAdmin;
}
@JSONField(serialize = false) @JSONField(serialize = false)
private List<SimpleGrantedAuthority> authorities; private List<SimpleGrantedAuthority> authorities;

View File

@ -0,0 +1,39 @@
package com.yfd.platform.system.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户-门户关联表
* </p>
*/
@Data
@TableName("SYS_USER_TENANT")
public class SysUserTenant implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(type = IdType.ASSIGN_UUID)
private String id;
/** 用户ID */
private String userId;
/** 门户ID */
private String tenantId;
@TableField("OPERATOR")
private String operator;
@TableField("OPERATE_TIME")
private Date operateTime;
}

View File

@ -44,7 +44,7 @@ public interface SysMenuMapper extends BaseMapper<SysMenu> {
@Param("tenantId") String tenantId); @Param("tenantId") String tenantId);
List<String> selectPermsByUserId(String userId); List<String> selectPermsByUserId(@Param("userId") String userId, @Param("tenantId") String tenantId);
//List<SysMenu> selectMenuByUserId(String userId); //List<SysMenu> selectMenuByUserId(String userId);
List<SysMenu> selectMenuByUserId(@Param("userId") String userId, @Param("tenantId") String tenantId); List<SysMenu> selectMenuByUserId(@Param("userId") String userId, @Param("tenantId") String tenantId);

View File

@ -29,7 +29,7 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
* userid 用户id * userid 用户id
* 返回值说明: * 返回值说明:
************************************/ ************************************/
boolean addUserRoles(@Param("id")String id,@Param("roleid") String roleid,@Param("userid") String userid); boolean addUserRoles(@Param("operator") String operator,@Param("id")String id,@Param("roleid") String roleid,@Param("userid") String userid);
/*********************************** /***********************************
* 用途说明根据用户id 和角色id 查询 系统角色用户对照表 * 用途说明根据用户id 和角色id 查询 系统角色用户对照表

View File

@ -0,0 +1,47 @@
package com.yfd.platform.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.system.domain.SysUserTenant;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 用户-门户关联表 Mapper 接口
* </p>
*/
@Mapper
public interface SysUserTenantMapper extends BaseMapper<SysUserTenant> {
/**
* 查询用户可访问的门户ID列表
*/
List<String> getTenantIdsByUserId(@Param("userId") String userId);
/**
* 批量删除用户-门户关联
*/
int deleteByUserId(@Param("userId") String userId);
/**
* 批量新增用户-门户关联
*/
int batchInsert(@Param("operator") String operator,@Param("userId") String userId, @Param("tenantIds") List<String> tenantIds);
/**
* 查询某门户下的所有用户ID
*/
List<String> getUserIdsByTenantId(@Param("tenantId") String tenantId);
/**
* 删除指定用户和指定门户的关联
*/
int deleteByUserIdAndTenantId(@Param("userId") String userId, @Param("tenantId") String tenantId);
/**
* 批量查询用户-门户关联用于用户列表展示
*/
List<java.util.Map<String, Object>> getTenantIdsByUserIds(@Param("userIds") List<String> userIds);
}

View File

@ -97,5 +97,14 @@ public interface ISysMenuService extends IService<SysMenu> {
***********************************/ ***********************************/
List<Map<String, Object>> permissionAssignment(String code, String roleId, String tenantId); List<Map<String, Object>> permissionAssignment(String code, String roleId, String tenantId);
/***********************************
* 用途说明权限分配按系统分组附带系统标识和名称
* 参数说明
* roleId 角色ID
* tenantId 门户ID
* 返回值说明: [{"systemCode":"1","systemName":"Web端","menus":[...]}, ...]
***********************************/
List<Map<String, Object>> permissionAssignmentGrouped(String roleId, String tenantId);
String uploadIcon(MultipartFile icon) throws FileNotFoundException; String uploadIcon(MultipartFile icon) throws FileNotFoundException;
} }

View File

@ -67,4 +67,13 @@ public interface ISysRoleService extends IService<SysRole> {
List<SysRole> selectRoleList(String rolename, String tenantId); List<SysRole> selectRoleList(String rolename, String tenantId);
List<SysRole> queryRolesList(String roleName, String tenantId); List<SysRole> queryRolesList(String roleName, String tenantId);
/***********************************
* 用途说明按门户分组查询角色门户 角色两层结构
* 参数说明
* rolename 角色名称可选模糊搜索
* 返回值说明: [{"tenantId":"...","tenantName":"水利门户","roles":[...]}, ...]
* 门户中文名通过字典 PLATFORM_TENANT 获取
***********************************/
List<Map<String, Object>> selectRoleListGroupedByTenant(String tenantId,String rolename);
} }

View File

@ -33,7 +33,7 @@ public interface IUserService extends IService<SysUser> {
************************************/ ************************************/
Map<String, String> getNameInfo(); Map<String, String> getNameInfo();
//获取当前用户信息带权限 //获取当前用户信息带权限
ResponseResult getLoginUserInfo(); Map<String, Object> getLoginUserInfo();
/*********************************** /***********************************
* 用途说明新增用户 * 用途说明新增用户
@ -184,4 +184,23 @@ public interface IUserService extends IService<SysUser> {
Page<SysUser> queryPendingAuditUsers(Page<SysUser> page, String name, String regStatus, String tenantId); Page<SysUser> queryPendingAuditUsers(Page<SysUser> page, String name, String regStatus, String tenantId);
List<SysUser> queryUsersList(String name, String tenantId); List<SysUser> queryUsersList(String name, String tenantId);
// ==================== 多门户管理 ====================
/**
* 为用户分配门户
*/
void assignTenantsToUser(String userId, List<String> tenantIds);
/**
* 移除用户的某个门户关联
*/
void removeTenantFromUser(String userId, String tenantId);
/**
* 获取用户关联的门户ID列表
*/
List<String> getUserTenants(String userId);
boolean isSuperAdmin(String userId);
} }

View File

@ -38,17 +38,17 @@ public class AdminAuthServiceImpl implements IAdminAuthService {
public List<String> getSuperAdminUsernames() { public List<String> getSuperAdminUsernames() {
// 获取当前请求 // 获取当前请求
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); // ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUser::getUsertype, 0).select(SysUser::getUsername); queryWrapper.eq(SysUser::getUsertype, 0).select(SysUser::getUsername);
//根据用户名称或手机号查询用户信息 //根据用户名称或手机号查询用户信息
if (attributes != null) { // if (attributes != null) {
HttpServletRequest request = attributes.getRequest(); // HttpServletRequest request = attributes.getRequest();
String tenantId = request.getHeader("Tenant_Id"); // String tenantId = request.getHeader("Tenant_Id");
if(StrUtil.isNotBlank(tenantId)){ // if(StrUtil.isNotBlank(tenantId)){
queryWrapper.eq(SysUser::getTenantId, tenantId); // queryWrapper.eq(SysUser::getTenantId, tenantId);
} // }
} // }
List<SysUser> userList = userMapper.selectList(queryWrapper); List<SysUser> userList = userMapper.selectList(queryWrapper);
if (CollUtil.isEmpty(userList)) { if (CollUtil.isEmpty(userList)) {
return new ArrayList<>(); return new ArrayList<>();
@ -74,6 +74,8 @@ public class AdminAuthServiceImpl implements IAdminAuthService {
@Override @Override
public boolean isCurrentManagedAdmin() { public boolean isCurrentManagedAdmin() {
return isManagedAdminUsername(SecurityUtils.getCurrentUsername()); String maxLevel = userMapper.getMaxLevel(SecurityUtils.getUserId());
boolean adminRole = "1".equals(maxLevel);
return adminRole||isManagedAdminUsername(SecurityUtils.getCurrentUsername());
} }
} }

View File

@ -48,7 +48,7 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl<SmsVerifyCodeMapper, S
LambdaQueryWrapper<SmsVerifyCode> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SmsVerifyCode> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SmsVerifyCode::getPhone, phone) queryWrapper.eq(SmsVerifyCode::getPhone, phone)
.eq(SmsVerifyCode::getType, type) .eq(SmsVerifyCode::getType, type)
.gt(SmsVerifyCode::getTenantId, tenantId) .eq(SmsVerifyCode::getTenantId, tenantId)
.eq(SmsVerifyCode::getStatus, SmsVerifyCode.STATUS_UNUSED); .eq(SmsVerifyCode::getStatus, SmsVerifyCode.STATUS_UNUSED);
this.remove(queryWrapper); this.remove(queryWrapper);
@ -161,7 +161,7 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl<SmsVerifyCodeMapper, S
} }
List<String> ids = userIds.stream().distinct().toList(); List<String> ids = userIds.stream().distinct().toList();
List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getId, ids) List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getId, ids)
.eq(SysUser::getRegStatus, "APPROVED").eq(SysUser::getTenantId, tenantId).eq(SysUser::getStatus,1).select(SysUser::getPhone)); .eq(SysUser::getRegStatus, "APPROVED").eq(SysUser::getStatus,1).select(SysUser::getPhone));
if (sysUsers.isEmpty()) { if (sysUsers.isEmpty()) {
log.warn("催促短信发送失败未找到有效的手机号userIds: {}", ids); log.warn("催促短信发送失败未找到有效的手机号userIds: {}", ids);

View File

@ -7,10 +7,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.system.domain.SysDictionary;
import com.yfd.platform.system.domain.SysDictionaryItems;
import com.yfd.platform.system.domain.SysMenu; import com.yfd.platform.system.domain.SysMenu;
import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.domain.SysRole;
import com.yfd.platform.system.mapper.SysMenuMapper; import com.yfd.platform.system.mapper.SysMenuMapper;
import com.yfd.platform.system.mapper.SysRoleMapper; import com.yfd.platform.system.mapper.SysRoleMapper;
import com.yfd.platform.system.service.ISysDictionaryItemsService;
import com.yfd.platform.system.service.ISysDictionaryService;
import com.yfd.platform.system.service.ISysMenuService; import com.yfd.platform.system.service.ISysMenuService;
import com.yfd.platform.utils.FileUtil; import com.yfd.platform.utils.FileUtil;
import com.yfd.platform.config.FileSpaceProperties; import com.yfd.platform.config.FileSpaceProperties;
@ -47,6 +51,12 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
@Resource @Resource
private UserServiceImpl currentUser; private UserServiceImpl currentUser;
@Resource
private ISysDictionaryService sysDictionaryService;
@Resource
private ISysDictionaryItemsService sysDictionaryItemsService;
@Resource @Resource
private SysRoleMapper sysRoleMapper; private SysRoleMapper sysRoleMapper;
@ -443,6 +453,9 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
} else { } else {
sysMenuList = sysMenuMapper.selectMenuByUserId(id, tenantId); sysMenuList = sysMenuMapper.selectMenuByUserId(id, tenantId);
} }
if (sysMenuList==null||sysMenuList.isEmpty()) {
throw new RuntimeException("无菜单");
}
// SysMenu 转换为 Map 并构建树 // SysMenu 转换为 Map 并构建树
List<Map<String, Object>> list = sysMenuList.stream() List<Map<String, Object>> list = sysMenuList.stream()
.map(menu -> { .map(menu -> {
@ -502,6 +515,77 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
return listTree; return listTree;
} }
/***********************************
* 用途说明权限分配按系统分组附带系统标识和名称
* 参数说明
* roleId 角色ID
* tenantId 门户ID
* 返回值说明: [{"systemCode":"1","systemName":"Web端","menus":[...]}, ...]
***********************************/
@Override
public List<Map<String, Object>> permissionAssignmentGrouped(String roleId, String tenantId) {
// 1. 查询 PLATFORM_TENANT 字典项构建 systemCode systemName 映射
Map<String, String> systemNameMap = new HashMap<>();
SysDictionary tenantDict = sysDictionaryService.getByDictCode("PLATFORM_TENANT");
if (tenantDict != null) {
List<SysDictionaryItems> items = sysDictionaryItemsService.listByDictId(tenantDict.getId());
if (items != null) {
for (SysDictionaryItems item : items) {
if (StrUtil.isNotBlank(item.getItemCode())) {
systemNameMap.put(item.getItemCode(), item.getDictName());
}
}
}
}
// 2. 查询所有菜单不按 systemcode 过滤按租户过滤
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.select(SysMenu::getId, SysMenu::getParentid, SysMenu::getName,
SysMenu::getSystemcode, SysMenu::getOrderno)
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, tenantId)
.orderByAsc(SysMenu::getSystemcode, SysMenu::getOrderno);
List<Map<String, Object>> mapList = sysMenuMapper.selectMaps(queryWrapper);
List<Map<String, Object>> listAll = ObjectConverterUtil.convertMapFieldsToEntityFormat(SysMenu.class, mapList);
// 3. 获取角色已有的菜单ID列表
List<String> listRole = sysMenuMapper.selectMenuByRoleId(roleId, tenantId);
// 4. 标记 checkinfo
for (Map<String, Object> map : listAll) {
String id = (String) map.get("id");
map.put("checkinfo", listRole != null && listRole.contains(id));
}
// 5. systemcode 分组
Map<String, List<Map<String, Object>>> groupedBySystem = new LinkedHashMap<>();
for (Map<String, Object> menu : listAll) {
String sysCode = (String) menu.get("systemcode");
if (StrUtil.isBlank(sysCode)) {
sysCode = "1"; // 默认归属到 web 系统
}
groupedBySystem.computeIfAbsent(sysCode, k -> new ArrayList<>()).add(menu);
}
// 6. 按系统分组构建树并附加 systemCode systemName
List<Map<String, Object>> result = new ArrayList<>();
for (Map.Entry<String, List<Map<String, Object>>> entry : groupedBySystem.entrySet()) {
String sysCode = entry.getKey();
List<Map<String, Object>> sysMenuList = entry.getValue();
// 构建菜单树
List<Map<String, Object>> menuTree = buildTrees(sysMenuList);
// 组装结果
Map<String, Object> systemGroup = new HashMap<>();
systemGroup.put("systemCode", sysCode);
systemGroup.put("systemName", systemNameMap.getOrDefault(sysCode, sysCode));
systemGroup.put("menus", menuTree);
result.add(systemGroup);
}
return result;
}
// 另一种方法 // 另一种方法
/*public List<Map<String, Object>> permissionAssignment(String roleId) { /*public List<Map<String, Object>> permissionAssignment(String roleId) {

View File

@ -66,7 +66,8 @@ public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMappe
// 构建权限过滤条件 // 构建权限过滤条件
Set<String> allowedOrgIds = new HashSet<>(); Set<String> allowedOrgIds = new HashSet<>();
if (userInfo.getUsertype() != 0) { boolean superAdmin = userService.isSuperAdmin(userInfo.getId());
if (userInfo.getUsertype() != 0 && !superAdmin) {
List<SysRole> roleByUserId = sysRoleMapper.getRoleByUserId(userInfo.getId()); List<SysRole> roleByUserId = sysRoleMapper.getRoleByUserId(userInfo.getId());
for (SysRole sysRole : roleByUserId) { for (SysRole sysRole : roleByUserId) {
String orgscope = sysRole.getOrgscope(); String orgscope = sysRole.getOrgscope();
@ -81,8 +82,7 @@ public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMappe
// 查询这些组织的父级ID // 查询这些组织的父级ID
List<SysOrganization> list = sysOrganizationMapper.selectList( List<SysOrganization> list = sysOrganizationMapper.selectList(
new LambdaQueryWrapper<SysOrganization>() new LambdaQueryWrapper<SysOrganization>()
.in(SysOrganization::getId, stringList) .in(SysOrganization::getId, stringList));
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, tenantId));
for (SysOrganization org : list) { for (SysOrganization org : list) {
if (org.getParentid() != null) { if (org.getParentid() != null) {
allowedOrgIds.add(org.getParentid()); allowedOrgIds.add(org.getParentid());
@ -97,9 +97,9 @@ public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMappe
if (!allowedOrgIds.isEmpty()) { if (!allowedOrgIds.isEmpty()) {
queryWrapper.in("id", allowedOrgIds); queryWrapper.in("id", allowedOrgIds);
} }
if (StrUtil.isNotBlank(tenantId)) { // if (StrUtil.isNotBlank(tenantId)) {
queryWrapper.eq("tenant_id", tenantId); // queryWrapper.eq("tenant_id", tenantId);
} // }
if (StrUtil.isNotEmpty(params)) { if (StrUtil.isNotEmpty(params)) {
queryWrapper.like("orgname", params); queryWrapper.like("orgname", params);
} }
@ -254,7 +254,8 @@ public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMappe
// 收集所有允许的组织ID // 收集所有允许的组织ID
Set<String> allowedOrgIds = new HashSet<>(); Set<String> allowedOrgIds = new HashSet<>();
if (userInfo.getUsertype() != 0) { boolean superAdmin = userService.isSuperAdmin(userInfo.getId());
if (userInfo.getUsertype() != 0 && !superAdmin) {
List<SysRole> roleByUserId = sysRoleMapper.getRoleByUserId(userInfo.getId()); List<SysRole> roleByUserId = sysRoleMapper.getRoleByUserId(userInfo.getId());
for (SysRole sysRole : roleByUserId) { for (SysRole sysRole : roleByUserId) {
String orgscope = sysRole.getOrgscope(); String orgscope = sysRole.getOrgscope();
@ -274,7 +275,7 @@ public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMappe
// 构建查询条件 // 构建查询条件
LambdaQueryWrapper<SysOrganization> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysOrganization> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysOrganization::getParentid, id); queryWrapper.eq(SysOrganization::getParentid, id);
queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, tenantId); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, tenantId);
if (StrUtil.isNotBlank(orgName)) { if (StrUtil.isNotBlank(orgName)) {
queryWrapper.like(SysOrganization::getOrgname, orgName); queryWrapper.like(SysOrganization::getOrgname, orgName);

View File

@ -6,8 +6,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.system.domain.SysDictionary;
import com.yfd.platform.system.domain.SysDictionaryItems;
import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.domain.SysRole;
import com.yfd.platform.system.mapper.SysRoleMapper; import com.yfd.platform.system.mapper.SysRoleMapper;
import com.yfd.platform.system.service.ISysDictionaryItemsService;
import com.yfd.platform.system.service.ISysDictionaryService;
import com.yfd.platform.system.service.ISysRoleService; import com.yfd.platform.system.service.ISysRoleService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -16,8 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.List; import java.util.*;
import java.util.Map;
/** /**
* <p> * <p>
@ -37,6 +40,12 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
@Resource @Resource
private UserServiceImpl currentuser; private UserServiceImpl currentuser;
@Resource
private ISysDictionaryService sysDictionaryService;
@Resource
private ISysDictionaryItemsService sysDictionaryItemsService;
/*********************************** /***********************************
* 用途说明新增角色 * 用途说明新增角色
* 参数说明 * 参数说明
@ -185,4 +194,57 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
return sysRoleList; return sysRoleList;
} }
/***********************************
* 用途说明按门户分组查询角色门户 角色两层结构
* 参数说明
* rolename 角色名称可选模糊搜索
* 返回值说明: [{"tenantId":"...","tenantName":"水利门户","roles":[...]}, ...]
* 门户中文名通过字典 PLATFORM_TENANT 获取
***********************************/
@Override
public List<Map<String, Object>> selectRoleListGroupedByTenant(String tenantId,String rolename) {
// 1. 查询所有角色排除超级管理员级别支持角色名称模糊搜索
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, tenantId);
queryWrapper.like(StrUtil.isNotBlank(rolename), SysRole::getRolename, rolename);
// queryWrapper.ne(SysRole::getLevel, "1");
queryWrapper.orderByAsc(SysRole::getTenantId).orderByAsc(SysRole::getLevel);
List<SysRole> roleList = this.list(queryWrapper);
// 2. 查询 PLATFORM_TENANT 字典项构建 tenantId tenantName 映射
Map<String, String> tenantNameMap = new HashMap<>();
SysDictionary tenantDict = sysDictionaryService.getByDictCode("PLATFORM_TENANT");
if (tenantDict != null) {
List<SysDictionaryItems> items = sysDictionaryItemsService.list(new LambdaQueryWrapper<SysDictionaryItems>().eq(SysDictionaryItems::getDictId, tenantDict.getId()).eq(StrUtil.isNotBlank(tenantId),SysDictionaryItems::getItemCode, tenantId).select(SysDictionaryItems::getItemCode, SysDictionaryItems::getDictName));
if (items != null) {
for (SysDictionaryItems item : items) {
if (StrUtil.isNotBlank(item.getItemCode())) {
tenantNameMap.put(item.getItemCode(), item.getDictName());
}
}
}
}
// 3. tenantId 分组跳过无门户的角色
Map<String, List<SysRole>> grouped = new LinkedHashMap<>();
for (SysRole role : roleList) {
String code = role.getTenantId();
if (StrUtil.isBlank(code)) {
continue;
}
grouped.computeIfAbsent(code, k -> new ArrayList<>()).add(role);
}
// 4. 组装两层结构门户 角色
List<Map<String, Object>> result = new ArrayList<>();
for (Map.Entry<String, List<SysRole>> entry : grouped.entrySet()) {
Map<String, Object> group = new HashMap<>();
group.put("tenantId", entry.getKey());
group.put("tenantName", tenantNameMap.getOrDefault(entry.getKey(), entry.getKey()));
group.put("roles", entry.getValue());
result.add(group);
}
return result;
}
} }

View File

@ -3,12 +3,13 @@ package com.yfd.platform.system.service.impl;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yfd.platform.datasource.DataSource;
import com.yfd.platform.datasource.DataSourceKeys;
import com.yfd.platform.datasource.TargetDataSource; import com.yfd.platform.datasource.TargetDataSource;
import com.yfd.platform.system.domain.LoginUser; import com.yfd.platform.system.domain.LoginUser;
import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.domain.SysUser;
import com.yfd.platform.system.mapper.SysMenuMapper; import com.yfd.platform.system.mapper.SysMenuMapper;
import com.yfd.platform.system.mapper.SysUserMapper;
import com.yfd.platform.system.mapper.SysUserTenantMapper;
import com.yfd.platform.system.service.IAdminAuthService;
import com.yfd.platform.system.service.IUserService; import com.yfd.platform.system.service.IUserService;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
@ -20,11 +21,14 @@ import jakarta.annotation.Resource;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* <p> * <p>
* 用户服务实现类 继承UserDetailsService 实现接口 * 用户服务实现类 继承UserDetailsService 实现接口
* 支持多门户登录用户可关联多个门户登录时选择其中一个门户
* 超级管理员LEVEL=1拥有跨所有门户的权限
* </p> * </p>
* *
* @author zhengsl * @author zhengsl
@ -35,35 +39,74 @@ public class UserDetailsServiceImpl implements UserDetailsService {
@Resource @Resource
private IUserService userService; private IUserService userService;
@Resource
private IAdminAuthService adminAuthService;
@Resource @Resource
private SysMenuMapper sysMenuMapper; private SysMenuMapper sysMenuMapper;
@Resource
private SysUserTenantMapper sysUserTenantMapper;
@Resource
private SysUserMapper sysUserMapper;
@Override @Override
@TargetDataSource() @TargetDataSource()
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 获取当前请求 // 获取当前请求
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//根据用户名称或手机号查询用户信息
// 根据用户名称或手机号查询用户信息不加tenantId过滤支持跨门户登录
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>(); QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
queryWrapper.and(wrapper -> wrapper.eq("username", username).or().eq("phone", username)); queryWrapper.and(wrapper -> wrapper.eq("username", username).or().eq("phone", username));
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
String tenantId = request.getHeader("Tenant_Id");
if(StrUtil.isNotBlank(tenantId)){
queryWrapper.eq("TENANT_ID", tenantId);
}
}
SysUser user = userService.getOne(queryWrapper); SysUser user = userService.getOne(queryWrapper);
if (ObjectUtil.isEmpty(user)) { if (ObjectUtil.isEmpty(user)) {
throw new RuntimeException("用户账号不存在!"); throw new RuntimeException("用户账号不存在!");
} }
//Todo 根据用户查询权限信息 添加到LoginUser中
List<String> permissions =
sysMenuMapper.selectPermsByUserId(user.getId());
//封装成UserDetails对象返回 // 获取请求中的门户ID
return new LoginUser(user,permissions); String tenantId = null;
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
tenantId = request.getHeader("Tenant_Id");
}
// 判断是否为超级管理员LEVEL=1
boolean isSuperAdmin = (isSuperAdmin(user.getId())||user.getUsertype()==0);
// 查询用户可访问的门户列表
List<String> accessibleTenantIds = sysUserTenantMapper.getTenantIdsByUserId(user.getId());
// 非超级管理员必须指定门户且必须在可访问列表中
if (!isSuperAdmin) {
if (StrUtil.isBlank(tenantId)) {
throw new RuntimeException("用户无权限访问该平台");
}
if (accessibleTenantIds == null || !accessibleTenantIds.contains(tenantId)) {
throw new RuntimeException("用户无权限访问该平台");
}
}
// 加载权限超级管理员加载全部权限普通用户按门户过滤
List<String> permissions;
if (isSuperAdmin) {
permissions = sysMenuMapper.selectPermsByUserId(user.getId(), null);
} else {
permissions = sysMenuMapper.selectPermsByUserId(user.getId(), tenantId);
}
// 封装成UserDetails对象返回包含当前门户和可访问门户列表
return new LoginUser(user, permissions, tenantId, accessibleTenantIds, isSuperAdmin);
}
/**
* 判断用户是否为超级管理员拥有LEVEL=1的角色
*/
private boolean isSuperAdmin(String userId) {
String maxLevel = sysUserMapper.getMaxLevel(userId);
return "1".equals(maxLevel);
} }
} }

View File

@ -20,8 +20,10 @@ import com.yfd.platform.qgc_base.mapper.SdRvcdDicMapper;
import com.yfd.platform.system.domain.LoginUser; import com.yfd.platform.system.domain.LoginUser;
import com.yfd.platform.system.domain.SysRole; import com.yfd.platform.system.domain.SysRole;
import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.domain.SysUser;
import com.yfd.platform.system.domain.SysUserTenant;
import com.yfd.platform.system.mapper.SysRoleMapper; import com.yfd.platform.system.mapper.SysRoleMapper;
import com.yfd.platform.system.mapper.SysUserMapper; import com.yfd.platform.system.mapper.SysUserMapper;
import com.yfd.platform.system.mapper.SysUserTenantMapper;
import com.yfd.platform.system.service.IAdminAuthService; import com.yfd.platform.system.service.IAdminAuthService;
import com.yfd.platform.system.service.IUserService; import com.yfd.platform.system.service.IUserService;
import com.yfd.platform.utils.FileUtil; import com.yfd.platform.utils.FileUtil;
@ -81,6 +83,9 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
@Resource @Resource
private SysUserDataScopeMapper sysUserDataScopeMapper; private SysUserDataScopeMapper sysUserDataScopeMapper;
@Resource
private SysUserTenantMapper sysUserTenantMapper;
@Resource @Resource
private IAdminAuthService adminAuthService; private IAdminAuthService adminAuthService;
@ -122,7 +127,7 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
} }
@Override @Override
public ResponseResult getLoginUserInfo() { public Map<String, Object> getLoginUserInfo() {
UsernamePasswordAuthenticationToken authentication = UsernamePasswordAuthenticationToken authentication =
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
LoginUser loginuser = (LoginUser) authentication.getPrincipal(); LoginUser loginuser = (LoginUser) authentication.getPrincipal();
@ -138,7 +143,8 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
if(user.getUsertype()==0){ if(user.getUsertype()==0){
collect.add("超级管理员"); collect.add("超级管理员");
} }
ResponseResult responseResult = new ResponseResult(); // 新写法推荐
Map<String, Object> responseResult = new HashMap<>();
responseResult.put("userInfo", userInfo); responseResult.put("userInfo", userInfo);
responseResult.put("roles", collect); responseResult.put("roles", collect);
responseResult.put("permissions", loginuser.getPermissions()); responseResult.put("permissions", loginuser.getPermissions());
@ -169,7 +175,7 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
//账号有效 //账号有效
sysUser.setStatus(1); sysUser.setStatus(1);
//判断注册的登录账号是否存在 //判断注册的登录账号是否存在
if (isExistAccount(sysUser.getUsername(),sysUser.getTenantId() )) { if (isExistAccount(sysUser.getUsername())) {
//新增用户 //新增用户
boolean ok = this.save(sysUser); boolean ok = this.save(sysUser);
//新增用户分配权限 //新增用户分配权限
@ -179,12 +185,24 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
//系统生成id //系统生成id
String id = IdUtil.fastSimpleUUID(); String id = IdUtil.fastSimpleUUID();
//新增sys_role_users表数据 //新增sys_role_users表数据
ok = ok && sysUserMapper.addUserRoles(id, roleid, ok = ok && sysUserMapper.addUserRoles(SecurityUtils.getUserId(),id, roleid, sysUser.getId());
sysUser.getId());
} }
} }
//判断新增是否成功 消息提示 //判断新增是否成功 消息提示
if (ok) { if (ok) {
// 插入用户-门户关联
List<String> ids = StrUtil.split(roleids, ",");
if(!ids.isEmpty()) {
List<SysRole> selectedList = sysRoleMapper.selectList(new LambdaQueryWrapper<SysRole>().in(SysRole::getId, ids).select(SysRole::getTenantId));
List<String> tenantIds = selectedList.stream().map(SysRole::getTenantId).distinct().toList();
sysUserTenantMapper.batchInsert(SecurityUtils.getUserId(), sysUser.getId(), tenantIds);
}
// String tenantId = sysUser.getTenantId();
// if (StrUtil.isNotBlank(tenantId)) {
// List<String> tenantIds = new ArrayList<>();
// tenantIds.add(tenantId);
// sysUserTenantMapper.batchInsert(SecurityUtils.getUserId(),sysUser.getId(), tenantIds);
// }
result.put("status", "sucess"); result.put("status", "sucess");
result.put("msg", "新增用户成功!"); result.put("msg", "新增用户成功!");
@ -270,6 +288,14 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
return result; return result;
} }
// 根据角色给用户分配门户
sysUserTenantMapper.deleteByUserId(sysUser.getId());
if(StrUtil.isNotBlank(roleids)) {
List<String> ids = StrUtil.split(roleids, ",");
List<SysRole> selectedList = sysRoleMapper.selectList(new LambdaQueryWrapper<SysRole>().in(SysRole::getId, ids).select(SysRole::getTenantId));
List<String> tenantIds = selectedList.stream().map(SysRole::getTenantId).distinct().toList();
sysUserTenantMapper.batchInsert(SecurityUtils.getUserId(), sysUser.getId(), tenantIds);
}
// 处理角色分配 // 处理角色分配
String userId = sysUser.getId(); String userId = sysUser.getId();
if (StrUtil.isNotEmpty(roleids)) { if (StrUtil.isNotEmpty(roleids)) {
@ -345,12 +371,21 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
// 解析新角色列表 // 解析新角色列表
String[] newRoles = roleIds.split(","); String[] newRoles = roleIds.split(",");
String operator;
try {
operator = SecurityUtils.getUserId();
} catch (Exception e) {
// 记录日志方便排查
log.error("获取当前用户ID失败", e);
// 根据业务需求处理可返回默认值抛出业务异常或置空
operator = null; // "anonymous" 等默认值
}
// 需要新增的角色新角色 - 当前角色 // 需要新增的角色新角色 - 当前角色
for (String roleId : newRoles) { for (String roleId : newRoles) {
if (!currentRoleSet.contains(roleId)) { if (!currentRoleSet.contains(roleId)) {
String id = IdUtil.fastSimpleUUID(); String id = IdUtil.fastSimpleUUID();
sysUserMapper.addUserRoles(id, roleId, userId);
sysUserMapper.addUserRoles(operator,id, roleId, userId);
} }
} }
@ -407,7 +442,7 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
//系统生成id //系统生成id
String id = IdUtil.fastSimpleUUID(); String id = IdUtil.fastSimpleUUID();
//新增sys_role_users表数据 //新增sys_role_users表数据
isOk = isOk && sysUserMapper.addUserRoles(id, roleid, userid); isOk = isOk && sysUserMapper.addUserRoles(SecurityUtils.getUserId(),id, roleid, userid);
} }
} }
return isOk; return isOk;
@ -434,6 +469,8 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
if (isOk) { if (isOk) {
//根据用户id 删除该用户角色关联 //根据用户id 删除该用户角色关联
sysUserMapper.delRoleUsersByUserid(id); sysUserMapper.delRoleUsersByUserid(id);
// 删除用户-门户关联
sysUserTenantMapper.deleteByUserId(id);
//判断是否存在 账号头像 存在删除 //判断是否存在 账号头像 存在删除
if (StrUtil.isNotEmpty(sysUser.getAvatar())) { if (StrUtil.isNotEmpty(sysUser.getAvatar())) {
FileUtil.del(imgName); FileUtil.del(imgName);
@ -580,7 +617,7 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
//系统生成id //系统生成id
String id = IdUtil.fastSimpleUUID(); String id = IdUtil.fastSimpleUUID();
//新增sys_role_users表数据 //新增sys_role_users表数据
isOk = sysUserMapper.addUserRoles(id, roleid, userid); isOk = sysUserMapper.addUserRoles(SecurityUtils.getUserId(),id, roleid, userid);
} }
return isOk; return isOk;
} }
@ -636,6 +673,10 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
} }
// 根据ID删除用户与角色的关联信息 // 根据ID删除用户与角色的关联信息
sysUserMapper.delRoleUsersByUserIds(ids); sysUserMapper.delRoleUsersByUserIds(ids);
// 删除用户-门户关联
for (String userId : ids) {
sysUserTenantMapper.deleteByUserId(userId);
}
List<String> avatars = List<String> avatars =
sysUsers.stream().map(SysUser::getAvatar).collect(Collectors.toList()); sysUsers.stream().map(SysUser::getAvatar).collect(Collectors.toList());
if (avatars.size() > 0) { if (avatars.size() > 0) {
@ -654,7 +695,7 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
public SysUser getUserByPhone(String phone,String tenantId) { public SysUser getUserByPhone(String phone,String tenantId) {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUser::getPhone, phone); queryWrapper.eq(SysUser::getPhone, phone);
queryWrapper.eq(SysUser::getTenantId, tenantId); // queryWrapper.eq(SysUser::getTenantId, tenantId);
return this.getOne(queryWrapper); return this.getOne(queryWrapper);
} }
@ -893,15 +934,14 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
} }
/*********************************** /***********************************
* 用途说明:比较登录名称是否有重复 * 用途说明:比较登录名称是否有重复全局唯一不区分门户
* 参数说明 * 参数说明
* account 登录名称 * account 登录名称
* 返回值说明: 重复返回 false 否则返回 true * 返回值说明: 重复返回 false 否则返回 true
************************************/ ************************************/
private boolean isExistAccount(String username,String tenantId) { private boolean isExistAccount(String username) {
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>(); QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
if (this.list(queryWrapper.eq("username", username).eq("TENANT_ID", tenantId)).size() > 0) { if (this.list(queryWrapper.eq("username", username)).size() > 0) {
//判断 查询登录账号 结果集是否为null 重复返回 false 否则返回 tree
return false; return false;
} else { } else {
return true; return true;
@ -912,7 +952,7 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
@Override @Override
public List<SysUser> queryUsersList(String name, String tenantId) { public List<SysUser> queryUsersList(String name, String tenantId) {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, tenantId); // queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, tenantId);
queryWrapper.eq(SysUser::getStatus, 1); queryWrapper.eq(SysUser::getStatus, 1);
queryWrapper.and(StrUtil.isNotBlank(name), wrapper -> queryWrapper.and(StrUtil.isNotBlank(name), wrapper ->
wrapper.like(SysUser::getNickname, name) wrapper.like(SysUser::getNickname, name)
@ -923,4 +963,49 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
List<SysUser> sysUserList = this.list( queryWrapper); List<SysUser> sysUserList = this.list( queryWrapper);
return sysUserList; return sysUserList;
} }
// ==================== 多门户管理 ====================
/**
* 为用户分配门户
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void assignTenantsToUser(String userId, List<String> tenantIds) {
if (StrUtil.isBlank(userId) || tenantIds == null || tenantIds.isEmpty()) {
throw new RuntimeException("用户ID和门户ID列表不能为空");
}
sysUserTenantMapper.batchInsert(SecurityUtils.getUserId(),userId, tenantIds);
}
/**
* 移除用户的某个门户关联
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void removeTenantFromUser(String userId, String tenantId) {
if (StrUtil.isBlank(userId) || StrUtil.isBlank(tenantId)) {
throw new RuntimeException("用户ID和门户ID不能为空");
}
sysUserTenantMapper.deleteByUserIdAndTenantId(userId, tenantId);
}
/**
* 获取用户关联的门户ID列表
*/
@Override
public List<String> getUserTenants(String userId) {
if (StrUtil.isBlank(userId)) {
return new ArrayList<>();
}
return sysUserTenantMapper.getTenantIdsByUserId(userId);
}
public boolean isSuperAdmin(String userId) {
String maxLevel = sysUserMapper.getMaxLevel(userId);
SysUser sysUser = sysUserMapper.selectById(userId);
return (sysUser!=null && sysUser.getUsertype()==0) || "1".equals(maxLevel);
}
} }

View File

@ -92,6 +92,8 @@ public class DataSourceRequestUtil {
List<String> excludes = excludeFields != null ? excludeFields : new ArrayList<>(); List<String> excludes = excludeFields != null ? excludeFields : new ArrayList<>();
applySelect(request, wrapper, entityClass, fieldMapping, excludes);
applyFilters(request.getFilter(), wrapper, entityClass, fieldMapping, excludes, "and"); applyFilters(request.getFilter(), wrapper, entityClass, fieldMapping, excludes, "and");
applySort(request.getSort(), wrapper, entityClass); applySort(request.getSort(), wrapper, entityClass);
@ -145,6 +147,49 @@ public class DataSourceRequestUtil {
return service.list(wrapper); return service.list(wrapper);
} }
/**
* 应用查询字段select / distinctSelect
* distinctSelect 优先于 select并附带 DISTINCT 去重
*/
private static <T> void applySelect(DataSourceRequest request,
QueryWrapper<T> wrapper,
Class<T> entityClass,
Map<String, String> fieldMapping,
List<String> excludeFields) {
List<String> selectFields = request.getSelect();
boolean distinct = false;
if (CollectionUtil.isNotEmpty(request.getDistinctSelect())) {
selectFields = request.getDistinctSelect();
distinct = true;
}
if (CollectionUtil.isEmpty(selectFields)) {
return;
}
List<String> columns = new ArrayList<>();
for (String field : selectFields) {
if (StrUtil.isBlank(field) || excludeFields.contains(field)) {
continue;
}
String columnName = getColumnName(field, entityClass, fieldMapping);
if (columnName != null) {
columns.add(columnName);
}
}
if (columns.isEmpty()) {
return;
}
String[] columnArray = columns.toArray(new String[0]);
if (distinct) {
// MyBatis-Plus 3.5.16 wrapper.distinct() 方法在首个查询列前加 DISTINCT 关键字实现去重
columnArray[0] = "DISTINCT " + columnArray[0];
}
wrapper.select(columnArray);
}
private static <T> void applyFilters(DataSourceRequest.FilterDescriptor filter, private static <T> void applyFilters(DataSourceRequest.FilterDescriptor filter,
QueryWrapper<T> wrapper, QueryWrapper<T> wrapper,
Class<T> entityClass, Class<T> entityClass,

View File

@ -19,6 +19,7 @@ import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.yfd.platform.exception.BadRequestException; import com.yfd.platform.exception.BadRequestException;
import com.yfd.platform.system.domain.LoginUser;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -105,4 +106,40 @@ public class SecurityUtils {
.anyMatch(auth -> permission.equals(auth.getAuthority())); .anyMatch(auth -> permission.equals(auth.getAuthority()));
} }
/**
* 获取当前登录用户的门户ID
* @return 门户ID超级管理员可能返回null
*/
public static String getCurrentTenantId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) {
return null;
}
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
return loginUser.getCurrentTenantId();
}
/**
* 判断当前用户是否为超级管理员
*/
public static boolean isSuperAdmin() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) {
return false;
}
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
return loginUser.isSuperAdmin();
}
/**
* 获取当前用户可访问的门户ID列表
*/
public static List<String> getAccessibleTenantIds() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) {
return null;
}
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
return loginUser.getAccessibleTenantIds();
}
} }

View File

@ -197,7 +197,7 @@ logging:
level: level:
root: info root: info
com.yfd.platform: info com.yfd.platform: info
com.yfd.platform.common.MicroservicDynamicSQLMapper: debug com.yfd.platform.common.MicroservicDynamicSQLMapper: info
# ... existing code ... # ... existing code ...
# com.yfd.platform.*.mapper: trace # com.yfd.platform.*.mapper: trace

View File

@ -27,7 +27,7 @@
</update> </update>
<select id="selectPermsByUserId" resultType="java.lang.String"> <select id="selectPermsByUserId" resultType="java.lang.String">
SELECT SELECT
permission permission
FROM FROM
sys_role_users ru sys_role_users ru
@ -38,7 +38,10 @@
r.isvaild = 1 r.isvaild = 1
AND ru.userid = #{userId} AND ru.userid = #{userId}
AND permission IS NOT NULL AND permission IS NOT NULL
-- AND permission != '' <if test="tenantId != null and tenantId != ''">
AND r.tenant_id = #{tenantId}
AND m.tenant_id = #{tenantId}
</if>
</select> </select>
<select id="selectMenuByUserId" <select id="selectMenuByUserId"

View File

@ -123,7 +123,7 @@
FROM sys_role_users FROM sys_role_users
WHERE userid = #{id} WHERE userid = #{id}
</select> </select>
<!--查询角色列表Oracle 兼容版)--> <!--查询角色列表Oracle 兼容版) AND r."LEVEL" != '1'-->
<select id="selectRoleList" resultType="com.yfd.platform.system.domain.SysRole"> <select id="selectRoleList" resultType="com.yfd.platform.system.domain.SysRole">
SELECT r.id, r.rolecode, r.rolename, r."LEVEL", r.description, SELECT r.id, r.rolecode, r.rolename, r."LEVEL", r.description,
r.orgscope, r.optscope, r.busscope, r.isvaild, r.orgscope, r.optscope, r.busscope, r.isvaild,
@ -136,7 +136,6 @@
<if test="tenantId != null and tenantId != ''"> <if test="tenantId != null and tenantId != ''">
AND r.tenant_id = #{tenantId} AND r.tenant_id = #{tenantId}
</if> </if>
AND r."LEVEL" != '1'
</where> </where>
ORDER BY r."LEVEL" ASC, lastmodifydate ASC ORDER BY r."LEVEL" ASC, lastmodifydate ASC
</select> </select>

View File

@ -29,7 +29,7 @@
<!--用户分配角色 系统角色用户对照新增数据--> <!--用户分配角色 系统角色用户对照新增数据-->
<insert id="addUserRoles"> <insert id="addUserRoles">
insert into sys_role_users values (#{id},#{roleid},#{userid}) insert into sys_role_users(operator,id,roleid,userid) values (#{operator},#{id},#{roleid},#{userid})
</insert> </insert>
<!--根据用户id 和角色id 查询 系统角色用户对照表--> <!--根据用户id 和角色id 查询 系统角色用户对照表-->
@ -73,20 +73,22 @@
u.lastmodifydate u.lastmodifydate
FROM FROM
sys_user u sys_user u
LEFT JOIN SYS_USER_TENANT ut ON u.id = ut.USER_ID
WHERE WHERE
1 = 1 1 = 1
AND ( ( u.REG_STATUS != 'PENDING' AND u.REG_STATUS != 'REJECTED' ) OR u.REG_STATUS IS NULL ) AND ( ( u.REG_STATUS != 'PENDING' AND u.REG_STATUS != 'REJECTED' ) OR u.REG_STATUS IS NULL )
AND u.usertype != 0 -- AND u.usertype != 0
AND u.username != 'admin'
<if test="orgid != null"> <if test="orgid != null">
and u.orgid = #{orgid} and u.orgid = #{orgid}
</if> </if>
<if test="username != null"> <if test="username != null">
and u.username LIKE '%' || #{username} || '%' and (u.username LIKE '%' || #{username} || '%' OR u.nickname LIKE '%' || #{username} || '%' OR u.phone LIKE '%' || #{username} || '%')
</if> </if>
<if test="tenantId != null and tenantId != ''"> <if test="tenantId != null and tenantId != ''">
and u.tenant_id = #{tenantId} and (ut.TENANT_ID = #{tenantId} OR u.tenant_id = #{tenantId})
</if> </if>
ORDER BY u.lastmodifydate DESC ORDER BY u.username
</select> </select>
<select id="getOrganizationByid" resultType="java.util.Map"> <select id="getOrganizationByid" resultType="java.util.Map">
SELECT DISTINCT SELECT DISTINCT

View File

@ -0,0 +1,58 @@
<?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="com.yfd.platform.system.mapper.SysUserTenantMapper">
<!-- 查询用户可访问的门户ID列表 -->
<select id="getTenantIdsByUserId" resultType="java.lang.String">
SELECT TENANT_ID
FROM SYS_USER_TENANT
WHERE USER_ID = #{userId}
</select>
<!-- 批量删除用户-门户关联 -->
<delete id="deleteByUserId">
DELETE FROM SYS_USER_TENANT WHERE USER_ID = #{userId}
</delete>
<!-- 批量新增用户-门户关联(使用 MERGE 兼容 Oracle -->
<insert id="batchInsert">
MERGE INTO SYS_USER_TENANT T
USING (
<foreach collection="tenantIds" item="tenantId" index="index" separator="UNION ALL">
SELECT
#{userId, jdbcType=VARCHAR} AS USER_ID,
#{operator} AS OPERATOR,
#{tenantId, jdbcType=VARCHAR} AS TENANT_ID
FROM DUAL
</foreach>
) S
ON (T.USER_ID = S.USER_ID AND T.TENANT_ID = S.TENANT_ID)
WHEN NOT MATCHED THEN
INSERT (ID, USER_ID, TENANT_ID, OPERATOR)
VALUES (SYS_GUID(), S.USER_ID, S.TENANT_ID, S.OPERATOR)
</insert>
<!-- 删除指定用户和指定门户的关联 -->
<delete id="deleteByUserIdAndTenantId">
DELETE FROM SYS_USER_TENANT WHERE USER_ID = #{userId} AND TENANT_ID = #{tenantId}
</delete>
<!-- 查询某门户下的所有用户ID -->
<select id="getUserIdsByTenantId" resultType="java.lang.String">
SELECT USER_ID FROM SYS_USER_TENANT WHERE TENANT_ID = #{tenantId}
</select>
<!-- 批量查询用户-门户关联 -->
<select id="getTenantIdsByUserIds" resultType="java.util.HashMap">
SELECT
USER_ID AS "userId",
TENANT_ID AS "tenantId"
FROM SYS_USER_TENANT
WHERE USER_ID IN
<foreach collection="userIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
</mapper>

View File

@ -11,9 +11,9 @@ VITE_APP_BASE_URL = 'http://localhost:8093'
# 测试环境 # 测试环境
# VITE_APP_BASE_URL = 'http://172.16.21.142:8093' # VITE_APP_BASE_URL = 'http://172.16.21.142:8093'
# 汤伟 # 汤伟
# VITE_APP_BASE_URL = 'http://10.84.111.235:8093' VITE_APP_BASE_URL = 'http://10.84.111.235:8093'
# 李林 # 李林
VITE_APP_BASE_URL = 'http://10.84.111.25:8093' # VITE_APP_BASE_URL = 'http://10.84.111.25:8093'
## 开发环境 附件服务地址 ## 开发环境 附件服务地址
VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125' VITE_APP_ATTACHMENT_URL = 'https://211.99.26.225:12125'

View File

@ -51,6 +51,14 @@ export function assignmentPer (queryParams:any){
params: queryParams params: queryParams
}); });
} }
//获取分配权限(改动之后)
export function permissionAssignmentGrouped (queryParams:any){
return request({
url:'/system/menu/permissionAssignmentGrouped' ,
method: 'post',
params: queryParams
});
}
//发出分配权限 //发出分配权限
export function setMenuById (queryParams:any){ export function setMenuById (queryParams:any){
return request({ return request({

View File

@ -33,6 +33,14 @@ export function getRvcdDropdown(params: any) {
params: params params: params
}); });
} }
// /、鱼类资源
export function selectForDropdown(data:any) {
return request({
url: '/env/fishDictory/list',
method: 'post',
data
});
}
//电站下拉列表 //电站下拉列表
export function getEngInfoDropdown(data: any) { export function getEngInfoDropdown(data: any) {
return request({ return request({

View File

@ -57,6 +57,14 @@ export function getRole (queryParams:any) {
params: queryParams params: queryParams
}); });
} }
//获取角色
export function listGroupedByTenant (queryParams:any) {
return request({
url: '/system/role/listGroupedByTenant',
method: 'POST',
data: queryParams
});
}
//新建用户 //新建用户
export function addUsers (queryParams:any,roleids:any) { export function addUsers (queryParams:any,roleids:any) {
return request({ return request({

View File

@ -105,6 +105,7 @@
</a-select> --> </a-select> -->
<!-- 流域下拉框 --> <!-- 流域下拉框 -->
<a-select <a-select
:key="`rvcd-ly-${shuJuTianBaoStore.lyOption.length}`"
:value="formData.rvcd" :value="formData.rvcd"
placeholder="请选择" placeholder="请选择"
@change="lyChange" @change="lyChange"

View File

@ -359,6 +359,7 @@ const getData = async () => {
try { try {
if (props.url && modelStore.params.stcd) { if (props.url && modelStore.params.stcd) {
let res: any = await getStcdDetail(props.url, modelStore.params.stcd); let res: any = await getStcdDetail(props.url, modelStore.params.stcd);
// debugger
if (res && res.code) { if (res && res.code) {
let data = res.data; let data = res.data;
data2.value = data; data2.value = data;

View File

@ -19,7 +19,18 @@ service.interceptors.request.use(
`Expected 'config' and 'config.headers' not to be undefined` `Expected 'config' and 'config.headers' not to be undefined`
); );
} }
const menuPaths = [
'/system/menu/getMenuButtonTree',
'/system/menu/addMenu',
'/system/menu/updateById',
'/system/menu/deleteById',
'/system/menu/changeMenuOrder',
'/system/menu/uploadIcon',
'/system/menu/deleteIcon'
];
if (!menuPaths.some(p => config.url.includes(p))) {
config.headers.tenant_id = '2'; config.headers.tenant_id = '2';
}
if ( if (
config.url.includes('/dec-lygk-base-server') || config.url.includes('/dec-lygk-base-server') ||
config.url.includes('/wmp-env-server') || config.url.includes('/wmp-env-server') ||

View File

@ -129,7 +129,7 @@ const dvtp = ref([]);
const initSearchData = { const initSearchData = {
rvcd: 'all', rvcd: 'all',
rstcd: null, rstcd: null,
topHynm: null, topHycd: null,
hycd: null, hycd: null,
baseId: null, baseId: null,
hbrvcd: null, hbrvcd: null,
@ -157,7 +157,7 @@ const searchList: any = computed(() => [
}, },
{ {
type: 'Select', type: 'Select',
name: 'topHynm', name: 'topHycd',
label: '所属集团', label: '所属集团',
width: 140, width: 140,
fieldProps: { fieldProps: {

View File

@ -8,10 +8,10 @@
@ok="handleDataSourceConfirm" @ok="handleDataSourceConfirm"
> >
<div> <div>
<p style="color: red; margin-bottom: 8px">请输入修改依据以继续删除操作</p> <p style="color: red; margin-bottom: 8px">请输入删除依据以继续删除操作</p>
<a-textarea <a-textarea
v-model:value="dataSource" v-model:value="dataSource"
placeholder="请输入修改依据" placeholder="请输入删除依据"
:rows="4" :rows="4"
/> />
</div> </div>

View File

@ -1131,6 +1131,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const formRules = computed(() => ({ const formRules = computed(() => ({
stcd: props.isAdd stcd: props.isAdd
? [{ required: true, message: '请输入电站编码', trigger: 'blur' }] ? [{ required: true, message: '请输入电站编码', trigger: 'blur' }]
@ -1196,7 +1197,7 @@ const bldsttCodeOptions = ref<any[]>([
{ label: '已建', value: 2 } { label: '已建', value: 2 }
]); // TODO: ]); // TODO:
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter(item => item.wbsCode !== 'all') // "" .filter(item => item.wbsCode !== 'all') // ""
.map(item => ({ .map(item => ({
@ -1263,7 +1264,7 @@ watch(
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -1300,6 +1301,14 @@ watch(
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveSelectLabel(key, converted[key]);
}
}
originalLabels.value = labels;
} }
}, },
{ deep: true } { deep: true }

View File

@ -93,10 +93,12 @@ import { getEngInfoById } from '@/api/select';
import { calcTableScrollY } from '@/utils/index'; import { calcTableScrollY } from '@/utils/index';
import { useModelStore } from '@/store/modules/model'; import { useModelStore } from '@/store/modules/model';
import { useUserStore } from "@/store/modules/user"; import { useUserStore } from "@/store/modules/user";
import { useShuJuTianBaoStore } from '@/store/modules/shuJuTianBao';
const modelStore = useModelStore(); const modelStore = useModelStore();
const userStore = useUserStore(); const userStore = useUserStore();
const shuJuTianBaoStore = useShuJuTianBaoStore();
const sort = ref<any>([ const sort = ref<any>([
{ {
@ -360,12 +362,12 @@ const buildSearchParams = (values: any) => {
value: values.hycd value: values.hycd
} }
: null, : null,
values.topHynm values.topHycd
? { ? {
field: 'topHynm', field: 'topHycd',
operator: 'eq', operator: 'eq',
dataType: 'string', dataType: 'string',
value: values.topHynm value: values.topHycd
} }
: null, : null,
values.ttpwr && values.ttpwr.min values.ttpwr && values.ttpwr.min
@ -472,6 +474,8 @@ const handleEdit = (record: any) => {
// //
const handleEditSuccess = () => { const handleEditSuccess = () => {
const rvcd = searchRef.value?.searchData?.rvcd ?? 'all';
shuJuTianBaoStore.getEngOption(rvcd, 'rvcd');
initTable(currentSearchParams.value); initTable(currentSearchParams.value);
}; };

View File

@ -290,6 +290,8 @@
<a-textarea <a-textarea
v-model:value="formData.shapedesc" v-model:value="formData.shapedesc"
placeholder="请输入形态描述" placeholder="请输入形态描述"
:maxlength="500"
show-count
:rows="3" :rows="3"
/> />
</a-form-item> </a-form-item>
@ -299,6 +301,8 @@
<a-textarea <a-textarea
v-model:value="formData.description" v-model:value="formData.description"
placeholder="请输入内容" placeholder="请输入内容"
:maxlength="100"
show-count
:rows="3" :rows="3"
/> />
</a-form-item> </a-form-item>
@ -337,7 +341,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message, Upload } from 'ant-design-vue'; import { message, Upload } from 'ant-design-vue';
import { PlusOutlined } from '@ant-design/icons-vue'; import { PlusOutlined } from '@ant-design/icons-vue';
import { addFishDictoryInfo, updateFishDictoryInfo } from '@/api/DataQueryMenuModule'; import { addFishDictoryInfo, updateFishDictoryInfo } from '@/api/DataQueryMenuModule';
@ -366,6 +370,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
// //
@ -489,6 +494,11 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
//
const resolveOriginalLabel = (field: string): string => {
return resolveSelectLabel(field, originalRecord.value[field]);
};
// formData // formData
watch( watch(
() => formData.value, () => formData.value,
@ -516,7 +526,7 @@ watch(
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -588,9 +598,23 @@ watch(
newRecord => { newRecord => {
if (newRecord) { if (newRecord) {
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// //
if (converted.inffile) { if (converted.inffile) {
const ids = converted.inffile.split(',').filter(Boolean); const ids = converted.inffile.split(',').filter(Boolean);
@ -609,6 +633,22 @@ watch(
{ deep: true } { deep: true }
); );
// record code
watch(
() => shuJuTianBaoStore.lyOption,
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
watch( watch(
() => props.open, () => props.open,
val => { val => {

View File

@ -222,6 +222,8 @@
<a-textarea <a-textarea
v-model:value="formData.introduce" v-model:value="formData.introduce"
placeholder="请输入简介" placeholder="请输入简介"
:maxlength="1000"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -231,6 +233,8 @@
<a-textarea <a-textarea
v-model:value="formData.remark" v-model:value="formData.remark"
placeholder="请输入备注" placeholder="请输入备注"
:maxlength="150"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -249,7 +253,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addAiboxInfo, updateAiboxInfo } from '@/api/DataQueryMenuModule'; import { addAiboxInfo, updateAiboxInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -276,23 +280,22 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
stcd: [{ required: true, message: '请输入站码', trigger: 'blur' }], stcd: [{ required: true, message: '请输入站码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入站名', trigger: 'blur' }] stnm: [{ required: true, message: '请输入站名', trigger: 'blur' }],
sttp: [{ required: true, message: '请输入站类', trigger: 'blur' }],
}); });
// //
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
label: item.wbsName,
value: item.wbsCode
}))
); );
const engLoading = ref(false); const engLoading = ref(false);
@ -355,6 +358,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -387,7 +400,7 @@ watch(
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -416,17 +429,51 @@ watch(
); );
// record // record
watch( const isInitLoading = ref(false);
() => props.record, watch(() => props.record, newRecord => {
newRecord => { if (newRecord) {
if (newRecord) { isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
originalRecord.value = { ...converted }; // "-" null date-picker Invalid Date
formData.value = { ...converted }; for (const key in converted) {
changeOrder.value = []; if (converted[key] === '-') {
converted[key] = null;
}
} }
}, originalRecord.value = { ...converted };
{ deep: true } formData.value = { ...converted };
changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
}
}, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
); );
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
@ -442,17 +489,11 @@ const loadEngOptions = async (baseId?: string) => {
} }
}; };
//
const loadDropdownData = () => {
baseNameOptions.value = jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
};
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });
@ -461,7 +502,6 @@ watch(
() => props.open, () => props.open,
val => { val => {
if (val) { if (val) {
loadDropdownData();
if (props.isAdd) { if (props.isAdd) {
formData.value = {}; formData.value = {};
originalRecord.value = {}; originalRecord.value = {};

View File

@ -187,6 +187,8 @@
<a-textarea <a-textarea
v-model:value="formData.introduce" v-model:value="formData.introduce"
placeholder="请输入简介" placeholder="请输入简介"
:maxlength="1000"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -196,6 +198,8 @@
<a-textarea <a-textarea
v-model:value="formData.remark" v-model:value="formData.remark"
placeholder="请输入备注" placeholder="请输入备注"
:maxlength="150"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -214,7 +218,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addOtweInfo, updateOtweInfo } from '@/api/DataQueryMenuModule'; import { addOtweInfo, updateOtweInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -242,6 +246,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -253,13 +258,10 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
label: item.wbsName,
value: item.wbsCode
}))
); );
const engLoading = ref(false); const engLoading = ref(false);
@ -322,6 +324,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -353,7 +365,7 @@ watch(
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -381,17 +393,52 @@ watch(
{ deep: true } { deep: true }
); );
watch( // record
() => props.record, const isInitLoading = ref(false);
newRecord => { watch(() => props.record, newRecord => {
if (newRecord) { if (newRecord) {
const converted = { ...newRecord }; isInitLoading.value = true;
originalRecord.value = { ...converted }; const converted = { ...newRecord };
formData.value = { ...converted }; // "-" null date-picker Invalid Date
changeOrder.value = []; for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
} }
}, originalRecord.value = { ...converted };
{ deep: true } formData.value = { ...converted };
changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
}
}, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
); );
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
@ -426,15 +473,14 @@ const loadDropdownData = () => {
value: item.sttpCode value: item.sttpCode
})); }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData // store computed
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
}; };
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -231,6 +231,8 @@
<a-textarea <a-textarea
v-model:value="formData.introduce" v-model:value="formData.introduce"
placeholder="请输入简介" placeholder="请输入简介"
:maxlength="1000"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -240,6 +242,8 @@
<a-textarea <a-textarea
v-model:value="formData.remark" v-model:value="formData.remark"
placeholder="请输入备注" placeholder="请输入备注"
:maxlength="150"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -258,7 +262,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addAiInfo, updateAiInfo } from '@/api/DataQueryMenuModule'; import { addAiInfo, updateAiInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -286,6 +290,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -298,13 +303,10 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
label: item.wbsName,
value: item.wbsCode
}))
); );
const engLoading = ref(false); const engLoading = ref(false);
@ -368,6 +370,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -399,11 +411,7 @@ watch(
) )
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm)) : oldNorm === null ? '空' : String(oldNorm);
? resolveSelectLabel(key, oldNorm)
: oldNorm === null
? '空'
: String(oldNorm);
const newDisplay = isSelect const newDisplay = isSelect
? resolveSelectLabel(key, newNorm) ? resolveSelectLabel(key, newNorm)
: newNorm === null : newNorm === null
@ -429,17 +437,51 @@ watch(
); );
// record // record
watch( const isInitLoading = ref(false);
() => props.record, watch(() => props.record, newRecord => {
newRecord => { if (newRecord) {
if (newRecord) { isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
originalRecord.value = { ...converted }; // "-" null date-picker Invalid Date
formData.value = { ...converted }; for (const key in converted) {
changeOrder.value = []; if (converted[key] === '-') {
converted[key] = null;
}
} }
}, originalRecord.value = { ...converted };
{ deep: true } formData.value = { ...converted };
changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
}
}, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
); );
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
@ -476,16 +518,14 @@ const loadDropdownData = () => {
value: item.sttpCode value: item.sttpCode
})); }));
}); });
// store // store computed
baseNameOptions.value = jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
}; };
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -55,12 +55,12 @@
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="开工日期" name="swdt"> <a-form-item label="开工日期" name="swdt">
<a-date-picker v-model:value="formData.swdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开工日期" style="width: 100%" /> <a-date-picker v-model:value="formData.swdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" :disabled-date="disabledSwdtDate" placeholder="请选择开工日期" style="width: 100%" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="建成日期" name="jcdt"> <a-form-item label="建成日期" name="jcdt">
<a-date-picker v-model:value="formData.jcdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择建成日期" style="width: 100%" /> <a-date-picker v-model:value="formData.jcdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" :disabled-date="disabledJcdtDate" placeholder="请选择建成日期" style="width: 100%" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
@ -114,7 +114,9 @@
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="过鱼月份" name="fpssmn"> <a-form-item label="过鱼月份" name="fpssmn">
<a-input v-model:value="formData.fpssmn" placeholder="多个月份用,隔开" style="width: 100%" /> <a-select :key="visible" v-model:value="formData.fpssmn" mode="multiple" placeholder="请选择过鱼月份" allow-clear>
<a-select-option v-for="item in fpssmnOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option>
</a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
@ -138,7 +140,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import dayjs from 'dayjs';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addFpInfo, updateFpInfo } from '@/api/DataQueryMenuModule'; import { addFpInfo, updateFpInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -156,8 +159,9 @@ useDraggable(visible, { boundary: true, resetOnOpen: true });
const formRef = ref(); const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({ fpssmn: [] });
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -168,12 +172,15 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode })) jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
); );
const engLoading = ref(false); const engLoading = ref(false);
// 1-12
const fpssmnOptions = ref(Array.from({ length: 12 }, (_, i) => ({ label: `${i + 1}`, value: `${i + 1}` })));
const fieldLabelMap: Record<string, string> = { const fieldLabelMap: Record<string, string> = {
stcd: '设施编码', stnm: '设施名称', sttp: '设施类型', stlc: '站址/位置', stcd: '设施编码', stnm: '设施名称', sttp: '设施类型', stlc: '站址/位置',
baseId: '水电基地', rstcd: '所属电站', lgtd: '经度(°)', lttd: '纬度(°)', baseId: '水电基地', rstcd: '所属电站', lgtd: '经度(°)', lttd: '纬度(°)',
@ -196,7 +203,8 @@ const selectOptionsMap: Record<string, () => any[]> = {
mway: () => [ mway: () => [
{ label: '人工', value: 1 }, { label: '人工', value: 1 },
{ label: '自动', value: 2 } { label: '自动', value: 2 }
] ],
fpssmn: () => fpssmnOptions.value
}; };
const changeOrder = ref<{ field: string; label: string; oldValue: string; newValue: string }[]>([]); const changeOrder = ref<{ field: string; label: string; oldValue: string; newValue: string }[]>([]);
@ -204,6 +212,16 @@ const diffList = changeOrder;
const resolveSelectLabel = (field: string, value: any): string => { const resolveSelectLabel = (field: string, value: any): string => {
if (value === null || value === undefined || value === '') return '空'; if (value === null || value === undefined || value === '') return '空';
// fpssmn label
if (field === 'fpssmn') {
const arr = Array.isArray(value) ? value : String(value).split(',');
return arr.map((v: any) => {
const trimmed = String(v).trim();
if (!trimmed) return '';
const opt = fpssmnOptions.value.find((o) => String(o.value) === trimmed);
return opt ? opt.label : trimmed;
}).filter(Boolean).join('、');
}
const getOptions = selectOptionsMap[field]; const getOptions = selectOptionsMap[field];
if (getOptions) { if (getOptions) {
const opt = getOptions().find((o: any) => String(o.value) === String(value)); const opt = getOptions().find((o: any) => String(o.value) === String(value));
@ -212,24 +230,55 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
return label.includes(inputValue || ''); return label.includes(inputValue || '');
}; };
//
const disabledSwdtDate = (current: any) => {
if (!formData.value.jcdt) return false;
return current && current > dayjs(formData.value.jcdt).endOf('day');
};
//
const disabledJcdtDate = (current: any) => {
if (!formData.value.swdt) return false;
return current && current < dayjs(formData.value.swdt).startOf('day');
};
watch(() => formData.value, newData => { watch(() => formData.value, newData => {
const original = originalRecord.value; const original = originalRecord.value;
for (const key in newData) { for (const key in newData) {
const oldVal = original[key]; const oldVal = original[key];
const newVal = newData[key]; const newVal = newData[key];
if (oldVal !== newVal) { if (oldVal !== newVal) {
// fpssmn vs
if (key === 'fpssmn') {
const normalize = (v: any) => {
if (!v) return '';
const arr = Array.isArray(v) ? v : String(v).split(',');
return arr.map((s: string) => s.trim()).filter(Boolean).sort().join(',');
};
if (normalize(oldVal) === normalize(newVal)) continue;
}
const existingIdx = changeOrder.value.findIndex(c => c.field === key); const existingIdx = changeOrder.value.findIndex(c => c.field === key);
const oldNorm = oldVal === null || oldVal === undefined || oldVal === '-' ? null : oldVal; const oldNorm = oldVal === null || oldVal === undefined || oldVal === '-' ? null : oldVal;
const newNorm = newVal === null || newVal === undefined ? null : newVal; const newNorm = newVal === null || newVal === undefined ? null : newVal;
if (oldNorm === newNorm) continue; if (oldNorm === newNorm) continue;
if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue; if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect ? resolveSelectLabel(key, oldNorm) : oldNorm === null ? '空' : String(oldNorm); const oldDisplay = isSelect ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm)) : oldNorm === null ? '空' : String(oldNorm);
const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm); const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm);
const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay }; const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay };
if (existingIdx >= 0) changeOrder.value[existingIdx] = entry; if (existingIdx >= 0) changeOrder.value[existingIdx] = entry;
@ -240,15 +289,56 @@ watch(() => formData.value, newData => {
} }
}, { deep: true }); }, { deep: true });
// record
const isInitLoading = ref(false);
watch(() => props.record, newRecord => { watch(() => props.record, newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; // fpssmn
const fpssmnArr = converted.fpssmn ? String(converted.fpssmn).split(',').map((s: string) => s.trim()).filter(Boolean) : [];
formData.value = { ...converted, fpssmn: fpssmnArr.length > 0 ? fpssmnArr : undefined };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, { deep: true }); }, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
try { try {
@ -268,11 +358,15 @@ const loadDropdownData = () => {
}).then(res => { }).then(res => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode })); sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode })); // store computed
}; };
// //
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });
@ -280,7 +374,7 @@ watch(() => formData.value?.baseId, (newBaseId) => {
watch(() => props.open, val => { watch(() => props.open, val => {
if (val) { if (val) {
if (props.isAdd) { if (props.isAdd) {
formData.value = {}; formData.value = { fpssmn: [] };
originalRecord.value = {}; originalRecord.value = {};
changeOrder.value = []; changeOrder.value = [];
loadEngOptions(); loadEngOptions();
@ -304,10 +398,14 @@ const handleConfirmSubmit = async (source: string) => {
let res: any; let res: any;
if (props.isAdd) { if (props.isAdd) {
Object.assign(engInfo, formData.value); Object.assign(engInfo, formData.value);
// fpssmn
if (Array.isArray(engInfo.fpssmn)) engInfo.fpssmn = engInfo.fpssmn.join(',');
res = await addFpInfo({ engInfo, source: source.trim() || '新增' }); res = await addFpInfo({ engInfo, source: source.trim() || '新增' });
} else { } else {
engInfo.stcd = formData.value.stcd; engInfo.stcd = formData.value.stcd;
changeOrder.value.forEach(item => { engInfo[item.field] = formData.value[item.field]; }); changeOrder.value.forEach(item => { engInfo[item.field] = formData.value[item.field]; });
// fpssmn
if (Array.isArray(engInfo.fpssmn)) engInfo.fpssmn = engInfo.fpssmn.join(',');
res = await updateFpInfo({ engInfo, source: source.trim() || '编辑' }); res = await updateFpInfo({ engInfo, source: source.trim() || '编辑' });
} }
if (res?.code == 0 || res?.success) { if (res?.code == 0 || res?.success) {

View File

@ -125,6 +125,8 @@
<a-textarea <a-textarea
v-model:value="formData.introduce" v-model:value="formData.introduce"
placeholder="请输入简介" placeholder="请输入简介"
:maxlength="1000"
show-count
:rows="3" :rows="3"
/> />
</a-form-item> </a-form-item>
@ -134,6 +136,8 @@
<a-textarea <a-textarea
v-model:value="formData.remark" v-model:value="formData.remark"
placeholder="请输入备注" placeholder="请输入备注"
:maxlength="150"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -152,7 +156,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addTeInfo, updateTeInfo } from '@/api/DataQueryMenuModule'; import { addTeInfo, updateTeInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -180,6 +184,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -192,13 +197,10 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
label: item.wbsName,
value: item.wbsCode
}))
); );
const engLoading = ref(false); const engLoading = ref(false);
@ -242,6 +244,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -273,11 +285,7 @@ watch(
) )
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm)) : oldNorm === null ? '空' : String(oldNorm);
? resolveSelectLabel(key, oldNorm)
: oldNorm === null
? '空'
: String(oldNorm);
const newDisplay = isSelect const newDisplay = isSelect
? resolveSelectLabel(key, newNorm) ? resolveSelectLabel(key, newNorm)
: newNorm === null : newNorm === null
@ -303,17 +311,51 @@ watch(
); );
// record // record
watch( const isInitLoading = ref(false);
() => props.record, watch(() => props.record, newRecord => {
newRecord => { if (newRecord) {
if (newRecord) { isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
originalRecord.value = { ...converted }; // "-" null date-picker Invalid Date
formData.value = { ...converted }; for (const key in converted) {
changeOrder.value = []; if (converted[key] === '-') {
converted[key] = null;
}
} }
}, originalRecord.value = { ...converted };
{ deep: true } formData.value = { ...converted };
changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
}
}, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
); );
// baseId // baseId
@ -351,17 +393,15 @@ const loadDropdownData = () => {
value: item.sttpCode value: item.sttpCode
})); }));
}); });
// store // store computed
baseNameOptions.value = jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
}; };
// //
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -18,81 +18,174 @@
<a-row :gutter="16"> <a-row :gutter="16">
<a-col :span="8"> <a-col :span="8">
<a-form-item label="栖息地站码" name="stcd"> <a-form-item label="栖息地站码" name="stcd">
<a-input v-model:value="formData.stcd" placeholder="请输入栖息地站码" :disabled="!isAdd" style="width: 100%" /> <a-input
v-model:value="formData.stcd"
placeholder="请输入栖息地站码"
:disabled="!isAdd"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="栖息地名称" name="stnm"> <a-form-item label="栖息地名称" name="stnm">
<a-input v-model:value="formData.stnm" placeholder="请输入栖息地名称" style="width: 100%" /> <a-input
v-model:value="formData.stnm"
placeholder="请输入栖息地名称"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="站址" name="stlc"> <a-form-item label="站址" name="stlc">
<a-input v-model:value="formData.stlc" placeholder="请输入站址" style="width: 100%" /> <a-input
v-model:value="formData.stlc"
placeholder="请输入站址"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="经度(°)" name="lgtd"> <a-form-item label="经度(°)" name="lgtd">
<a-input-number v-model:value="formData.lgtd" placeholder="请输入" :precision="6" style="width: 100%" /> <a-input-number
v-model:value="formData.lgtd"
placeholder="请输入"
:precision="6"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="纬度(°)" name="lttd"> <a-form-item label="纬度(°)" name="lttd">
<a-input-number v-model:value="formData.lttd" placeholder="请输入" :precision="6" style="width: 100%" /> <a-input-number
v-model:value="formData.lttd"
placeholder="请输入"
:precision="6"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="水电基地" name="baseId"> <a-form-item label="水电基地" name="baseId">
<a-select v-model:value="formData.baseId" placeholder="请选择水电基地" allow-clear show-search :filter-option="filterOption"> <a-select
<a-select-option v-for="item in baseNameOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option> v-model:value="formData.baseId"
placeholder="请选择水电基地"
allow-clear
show-search
:filter-option="filterOption"
>
<a-select-option
v-for="item in baseNameOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>{{ item.label }}</a-select-option
>
</a-select> </a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="所属电站" name="rstcd"> <a-form-item label="所属电站" name="rstcd">
<a-select v-model:value="formData.rstcd" placeholder="请选择所属电站" allow-clear show-search :loading="engLoading" :filter-option="filterOption"> <a-select
<a-select-option v-for="item in engInfoOptions" :key="item.value" :label="item.label" :value="item.value">{{ item.label }}</a-select-option> v-model:value="formData.rstcd"
placeholder="请选择所属电站"
allow-clear
show-search
:loading="engLoading"
:filter-option="filterOption"
>
<a-select-option
v-for="item in engInfoOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>{{ item.label }}</a-select-option
>
</a-select> </a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="保护对象" name="bhdx"> <a-form-item label="保护对象" name="bhdx">
<a-input v-model:value="formData.bhdx" placeholder="请输入保护对象" style="width: 100%" /> <a-select
v-model:value="formData.bhdx"
mode="multiple"
placeholder="请选择保护对象"
allow-clear
show-search
:filter-option="filterOption"
>
<a-select-option
v-for="item in fishOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>{{ item.label }}</a-select-option
>
</a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="保护范围" name="bhfw"> <a-form-item label="保护范围" name="bhfw">
<a-input v-model:value="formData.bhfw" placeholder="请输入保护范围" style="width: 100%" /> <a-input
v-model:value="formData.bhfw"
placeholder="请输入保护范围"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="保护核心长度(km)" name="bhhxcd"> <a-form-item label="保护核心长度(km)" name="bhhxcd">
<a-input-number v-model:value="formData.bhhxcd" placeholder="请输入" :precision="2" style="width: 100%" /> <a-input-number
v-model:value="formData.bhhxcd"
placeholder="请输入"
:precision="2"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="保护河流" name="bhhl"> <a-form-item label="保护河流" name="bhhl">
<a-input v-model:value="formData.bhhl" placeholder="请输入保护河流" style="width: 100%" /> <a-input
v-model:value="formData.bhhl"
placeholder="请输入保护河流"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="保护河段" name="bhhd"> <a-form-item label="保护河段" name="bhhd">
<a-input v-model:value="formData.bhhd" placeholder="请输入保护河段" style="width: 100%" /> <a-input
v-model:value="formData.bhhd"
placeholder="请输入保护河段"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="保护措施" name="bhcs"> <a-form-item label="保护措施" name="bhcs">
<a-input v-model:value="formData.bhcs" placeholder="请输入保护措施" style="width: 100%" /> <a-input
v-model:value="formData.bhcs"
placeholder="请输入保护措施"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="保护方式" name="bhfs"> <a-form-item label="保护方式" name="bhfs">
<a-input v-model:value="formData.bhfs" placeholder="请输入保护方式" style="width: 100%" /> <a-input
v-model:value="formData.bhfs"
placeholder="请输入保护方式"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="投资(亿元)" name="inv"> <a-form-item label="投资(亿元)" name="inv">
<a-input-number v-model:value="formData.inv" placeholder="请输入" :precision="3" style="width: 100%" /> <a-input-number
v-model:value="formData.inv"
placeholder="请输入"
:precision="3"
style="width: 100%"
/>
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
@ -109,10 +202,10 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addFhInfo, updateFhInfo } from '@/api/DataQueryMenuModule'; import { addFhInfo, updateFhInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown, selectForDropdown } from '@/api/select';
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent'; import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
import ConfirmModal from '@/components/ConfirmModal/index.vue'; import ConfirmModal from '@/components/ConfirmModal/index.vue';
import { useDraggable } from '@/utils/drag'; import { useDraggable } from '@/utils/drag';
@ -121,13 +214,17 @@ const props = defineProps<{ open: boolean; record?: any; isAdd?: boolean }>();
const emit = defineEmits(['update:open', 'success']); const emit = defineEmits(['update:open', 'success']);
const jidiSelectEventStore = useJidiSelectEventStore(); const jidiSelectEventStore = useJidiSelectEventStore();
const visible = computed({ get: () => props.open, set: val => emit('update:open', val) }); const visible = computed({
get: () => props.open,
set: val => emit('update:open', val)
});
useDraggable(visible, { boundary: true, resetOnOpen: true }); useDraggable(visible, { boundary: true, resetOnOpen: true });
const formRef = ref(); const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -137,7 +234,7 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode })) .map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
@ -146,73 +243,221 @@ const baseNameOptions = ref<any[]>(
const engLoading = ref(false); const engLoading = ref(false);
const fieldLabelMap: Record<string, string> = { const fieldLabelMap: Record<string, string> = {
stcd: '栖息地站码', stnm: '栖息地名称', stlc: '站址', baseId: '水电基地', stcd: '栖息地站码',
rstcd: '所属电站', bhdx: '保护对象', bhfw: '保护范围', stnm: '栖息地名称',
bhhxcd: '保护核心长度(km)', stlc: '站址',
bhhl: '保护河流', bhhd: '保护河段', bhcs: '保护措施', bhfs: '保护方式', inv: '投资(亿元)', lgtd: '经度(°)', lttd: '纬度(°)' baseId: '水电基地',
rstcd: '所属电站',
bhdx: '保护对象',
bhfw: '保护范围',
bhhxcd: '保护核心长度(km)',
bhhl: '保护河流',
bhhd: '保护河段',
bhcs: '保护措施',
bhfs: '保护方式',
inv: '投资(亿元)',
lgtd: '经度(°)',
lttd: '纬度(°)'
}; };
const selectOptionsMap: Record<string, () => any[]> = { const selectOptionsMap: Record<string, () => any[]> = {
baseId: () => baseNameOptions.value, baseId: () => baseNameOptions.value,
rstcd: () => engInfoOptions.value rstcd: () => engInfoOptions.value,
bhdx: () => fishOptions.value
}; };
const changeOrder = ref<{ field: string; label: string; oldValue: string; newValue: string }[]>([]); const changeOrder = ref<
{ field: string; label: string; oldValue: string; newValue: string }[]
>([]);
const diffList = changeOrder; const diffList = changeOrder;
const resolveSelectLabel = (field: string, value: any): string => { const resolveSelectLabel = (field: string, value: any): string => {
if (value === null || value === undefined || value === '') return '空'; if (value === null || value === undefined || value === '') return '空';
// bhdx label
if (field === 'bhdx') {
const arr = Array.isArray(value) ? value : String(value).split(',');
return arr
.map((v: any) => {
const trimmed = String(v).trim();
if (!trimmed) return '';
const opt = fishOptions.value.find(
(o: any) => String(o.value) === trimmed
);
return opt ? opt.label : trimmed;
})
.filter(Boolean)
.join('、');
}
const getOptions = selectOptionsMap[field]; const getOptions = selectOptionsMap[field];
if (getOptions) { if (getOptions) {
const opt = getOptions().find((o: any) => String(o.value) === String(value)); const opt = getOptions().find(
(o: any) => String(o.value) === String(value)
);
if (opt) return opt.label; if (opt) return opt.label;
} }
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
return label.includes(inputValue || ''); return label.includes(inputValue || '');
}; };
const fishOptions = ref<any[]>([]);
const getFishzy = async () => {
try {
const res = await selectForDropdown({
"select": ["name","id"],
"filter": {"logic": "and","filters": []}});
fishOptions.value = (res.data || []).map((item: any) => ({
label: item.name ,
value: item.id
}));
} catch (error) {
console.error('获取保护对象列表失败:', error);
}
};
watch(() => formData.value, newData => { watch(
() => formData.value,
newData => {
const original = originalRecord.value;
for (const key in newData) {
const oldVal = original[key];
const newVal = newData[key];
if (oldVal !== newVal) {
// bhdx vs
if (key === 'bhdx') {
const normalize = (v: any) => {
if (!v) return '';
const arr = Array.isArray(v) ? v : String(v).split(',');
return arr
.map((s: string) => s.trim())
.filter(Boolean)
.sort()
.join(',');
};
if (normalize(oldVal) === normalize(newVal)) continue;
}
const existingIdx = changeOrder.value.findIndex(c => c.field === key);
const oldNorm =
oldVal === null || oldVal === undefined || oldVal === '-'
? null
: oldVal;
const newNorm = newVal === null || newVal === undefined ? null : newVal;
if (oldNorm === newNorm) continue;
if (
oldNorm !== null &&
newNorm !== null &&
!isNaN(Number(oldNorm)) &&
!isNaN(Number(newNorm)) &&
Number(oldNorm) === Number(newNorm)
)
continue;
const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect
? originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm)
: oldNorm === null
? '空'
: String(oldNorm);
const newDisplay = isSelect
? resolveSelectLabel(key, newNorm)
: newNorm === null
? '空'
: String(newNorm);
const entry = {
field: key,
label: fieldLabelMap[key] || key,
oldValue: oldDisplay,
newValue: newDisplay
};
if (existingIdx >= 0) changeOrder.value[existingIdx] = entry;
else changeOrder.value.push(entry);
} else {
changeOrder.value = changeOrder.value.filter(c => c.field !== key);
}
}
},
{ deep: true }
);
// record
const isInitLoading = ref(false);
watch(
() => props.record,
newRecord => {
if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted };
// bhdx
const bhdxArr = converted.bhdx
? String(converted.bhdx)
.split(',')
.map((s: string) => s.trim())
.filter(Boolean)
: [];
formData.value = {
...converted,
bhdx: bhdxArr.length > 0 ? bhdxArr : undefined
};
changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
}
},
{ deep: true }
);
// record code
watch([baseNameOptions, engInfoOptions, fishOptions], () => {
const original = originalRecord.value; const original = originalRecord.value;
for (const key in newData) { if (!original || Object.keys(original).length === 0) return;
const oldVal = original[key]; const labels: Record<string, string> = {};
const newVal = newData[key]; for (const key in original) {
if (oldVal !== newVal) { if (selectOptionsMap[key]) {
const existingIdx = changeOrder.value.findIndex(c => c.field === key); labels[key] = resolveOriginalLabel(key);
const oldNorm = oldVal === null || oldVal === undefined || oldVal === '-' ? null : oldVal;
const newNorm = newVal === null || newVal === undefined ? null : newVal;
if (oldNorm === newNorm) continue;
if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue;
const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect ? resolveSelectLabel(key, oldNorm) : oldNorm === null ? '空' : String(oldNorm);
const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm);
const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay };
if (existingIdx >= 0) changeOrder.value[existingIdx] = entry;
else changeOrder.value.push(entry);
} else {
changeOrder.value = changeOrder.value.filter(c => c.field !== key);
} }
} }
}, { deep: true }); originalLabels.value = labels;
});
watch(() => props.record, newRecord => {
if (newRecord) {
const converted = { ...newRecord };
originalRecord.value = { ...converted };
formData.value = { ...converted };
changeOrder.value = [];
}
}, { deep: true });
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
try { try {
const params = baseId ? { baseId } : {}; const params = baseId ? { baseId } : {};
const res = await getEngInfoDropdown(params); const res = await getEngInfoDropdown(params);
engInfoOptions.value = (res.data || []).map((item: any) => ({ label: item.ennm, value: item.stcd })); engInfoOptions.value = (res.data || []).map((item: any) => ({
label: item.ennm,
value: item.stcd
}));
} catch (error) { } catch (error) {
console.error('获取电站列表失败:', error); console.error('获取电站列表失败:', error);
} finally { } finally {
@ -220,30 +465,44 @@ const loadEngOptions = async (baseId?: string) => {
} }
}; };
const loadDropdownData = () => { watch(
baseNameOptions.value = jidiSelectEventStore.jidiData () => formData.value?.baseId,
.filter((item: any) => item.wbsCode !== 'all') newBaseId => {
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode })); // record record watch
}; if (isInitLoading.value) {
return;
watch(() => formData.value?.baseId, (newBaseId) => { }
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
});
watch(() => props.open, val => {
if (val) {
loadDropdownData();
if (props.isAdd) { formData.value = {}; originalRecord.value = {}; changeOrder.value = []; loadEngOptions(); }
} }
}); );
watch(
() => props.open,
val => {
if (val) {
if (props.isAdd) {
formData.value = {};
originalRecord.value = {};
changeOrder.value = [];
loadEngOptions();
}
getFishzy();
}
}
);
const handleOk = async () => { const handleOk = async () => {
try { try {
await formRef.value?.validateFields(); await formRef.value?.validateFields();
if (!props.isAdd && changeOrder.value.length === 0) { message.info('未检测到任何修改'); return; } if (!props.isAdd && changeOrder.value.length === 0) {
message.info('未检测到任何修改');
return;
}
confirmModalVisible.value = true; confirmModalVisible.value = true;
} catch (error) { console.error('验证失败:', error); } } catch (error) {
console.error('验证失败:', error);
}
}; };
const handleConfirmSubmit = async (source: string) => { const handleConfirmSubmit = async (source: string) => {
@ -253,10 +512,16 @@ const handleConfirmSubmit = async (source: string) => {
let res: any; let res: any;
if (props.isAdd) { if (props.isAdd) {
Object.assign(engInfo, formData.value); Object.assign(engInfo, formData.value);
// bhdx
if (Array.isArray(engInfo.bhdx)) engInfo.bhdx = engInfo.bhdx.join(',');
res = await addFhInfo({ engInfo, source: source.trim() || '新增' }); res = await addFhInfo({ engInfo, source: source.trim() || '新增' });
} else { } else {
engInfo.stcd = formData.value.stcd; engInfo.stcd = formData.value.stcd;
changeOrder.value.forEach(item => { engInfo[item.field] = formData.value[item.field]; }); changeOrder.value.forEach(item => {
engInfo[item.field] = formData.value[item.field];
});
// bhdx
if (Array.isArray(engInfo.bhdx)) engInfo.bhdx = engInfo.bhdx.join(',');
res = await updateFhInfo({ engInfo, source: source.trim() || '编辑' }); res = await updateFhInfo({ engInfo, source: source.trim() || '编辑' });
} }
if (res?.code == 0 || res?.success) { if (res?.code == 0 || res?.success) {
@ -264,11 +529,22 @@ const handleConfirmSubmit = async (source: string) => {
confirmModalVisible.value = false; confirmModalVisible.value = false;
visible.value = false; visible.value = false;
emit('success'); emit('success');
} else { message.error(res?.msg || (props.isAdd ? '新增失败' : '编辑失败')); } } else {
} catch (error) { message.error('提交失败,请重试'); } message.error(res?.msg || (props.isAdd ? '新增失败' : '编辑失败'));
finally { confirmLoading.value = false; } }
} catch (error) {
message.error('提交失败,请重试');
} finally {
confirmLoading.value = false;
}
}; };
const handleConfirmCancel = () => { confirmModalVisible.value = false; }; const handleConfirmCancel = () => {
const handleCancel = () => { visible.value = false; confirmModalVisible.value = false; formRef.value?.resetFields(); }; confirmModalVisible.value = false;
};
const handleCancel = () => {
visible.value = false;
confirmModalVisible.value = false;
formRef.value?.resetFields();
};
</script> </script>

View File

@ -62,7 +62,7 @@ const columns = ref<any[]>([
{ key: 'stcd', title: '栖息地站码', dataIndex: 'stcd', visible: true, width: 320, fixed: 'left', ellipsis: true }, { key: 'stcd', title: '栖息地站码', dataIndex: 'stcd', visible: true, width: 320, fixed: 'left', ellipsis: true },
{ key: 'baseName', title: '水电基地', dataIndex: 'baseName', visible: true, width: 120, ellipsis: true }, { key: 'baseName', title: '水电基地', dataIndex: 'baseName', visible: true, width: 120, ellipsis: true },
{ key: 'ennm', title: '所属电站', dataIndex: 'ennm', visible: true, width: 150, ellipsis: true }, { key: 'ennm', title: '所属电站', dataIndex: 'ennm', visible: true, width: 150, ellipsis: true },
{ key: 'bhdx', title: '保护对象', dataIndex: 'bhdx', visible: true, width: 120, ellipsis: true }, { key: 'bhdxName', title: '保护对象', dataIndex: 'bhdxName', visible: true, width: 240, ellipsis: true },
{ key: 'bhhl', title: '保护河流', dataIndex: 'bhhl', visible: true, width: 120, ellipsis: true }, { key: 'bhhl', title: '保护河流', dataIndex: 'bhhl', visible: true, width: 120, ellipsis: true },
{ key: 'bhhd', title: '保护河段', dataIndex: 'bhhd', visible: true, width: 240, ellipsis: true }, { key: 'bhhd', title: '保护河段', dataIndex: 'bhhd', visible: true, width: 240, ellipsis: true },
{ key: 'bhfw', title: '保护范围', dataIndex: 'bhfw', visible: true, width: 120, ellipsis: true }, { key: 'bhfw', title: '保护范围', dataIndex: 'bhfw', visible: true, width: 120, ellipsis: true },

View File

@ -188,6 +188,8 @@
<a-textarea <a-textarea
v-model:value="formData.introduce" v-model:value="formData.introduce"
placeholder="请输入简介" placeholder="请输入简介"
:maxlength="1000"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -197,6 +199,8 @@
<a-textarea <a-textarea
v-model:value="formData.remark" v-model:value="formData.remark"
placeholder="请输入备注" placeholder="请输入备注"
:maxlength="150"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -215,7 +219,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addVaInfo, updateVaInfo } from '@/api/DataQueryMenuModule'; import { addVaInfo, updateVaInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -243,6 +247,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -254,7 +259,7 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({
@ -270,18 +275,16 @@ const fieldLabelMap: Record<string, string> = {
stnm: '救助站名称', stnm: '救助站名称',
sttp: '测站类型', sttp: '测站类型',
stlc: '站址', stlc: '站址',
lgtd: '经度(°)',
lttd: '纬度(°)',
baseId: '水电基地', baseId: '水电基地',
rstcd: '所属电站', rstcd: '所属电站',
place: '地点', place: '地点',
area: '面积', area: '面积(km²)',
bhfs: '保护方式', bhfs: '保护方式',
bhyy: '保护原因', bhyy: '保护原因',
bhdx: '保护对象', bhdx: '保护对象',
usfl: '是否启用', usfl: '是否启用',
jcdt: '建成日期', jcdt: '建成日期',
inv: '投资', inv: '投资(亿元)',
introduce: '简介', introduce: '简介',
remark: '备注' remark: '备注'
}; };
@ -317,6 +320,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -337,8 +350,16 @@ watch(
if (oldNorm === newNorm) continue; if (oldNorm === newNorm) continue;
if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue; if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect ? resolveSelectLabel(key, oldNorm) : oldNorm === null ? '空' : String(oldNorm); const oldDisplay = isSelect
const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm); ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null
? '空'
: String(oldNorm);
const newDisplay = isSelect
? resolveSelectLabel(key, newNorm)
: newNorm === null
? '空'
: String(newNorm);
const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay }; const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay };
if (existingIdx >= 0) changeOrder.value[existingIdx] = entry; if (existingIdx >= 0) changeOrder.value[existingIdx] = entry;
else changeOrder.value.push(entry); else changeOrder.value.push(entry);
@ -350,14 +371,56 @@ watch(
{ deep: true } { deep: true }
); );
watch(() => props.record, newRecord => { const isInitLoading = ref(false);
if (newRecord) { watch(
const converted = { ...newRecord }; () => props.record,
originalRecord.value = { ...converted }; newRecord => {
formData.value = { ...converted }; if (newRecord) {
changeOrder.value = []; isInitLoading.value = true;
const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted };
formData.value = { ...converted };
changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
}
},
{ deep: true }
);
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
} }
}, { deep: true }); );
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
@ -381,23 +444,27 @@ const loadDropdownData = () => {
}).then(res => { }).then(res => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode })); sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode })); // baseNameOptions computed
}; };
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });
watch(() => props.open, val => { watch(() => props.open, val => {
if (val) { if (val) {
loadDropdownData();
if (props.isAdd) { if (props.isAdd) {
formData.value = {}; formData.value = {};
originalRecord.value = {}; originalRecord.value = {};
changeOrder.value = []; changeOrder.value = [];
loadEngOptions(); loadEngOptions();
} }
loadDropdownData();
} }
}); });

View File

@ -55,12 +55,12 @@
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="开工日期" name="swdt"> <a-form-item label="开工日期" name="swdt">
<a-date-picker v-model:value="formData.swdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开工日期" style="width: 100%" /> <a-date-picker v-model:value="formData.swdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" :disabled-date="disabledSwdtDate" placeholder="请选择开工日期" style="width: 100%" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="建成日期" name="jcdt"> <a-form-item label="建成日期" name="jcdt">
<a-date-picker v-model:value="formData.jcdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择建成日期" style="width: 100%" /> <a-date-picker v-model:value="formData.jcdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" :disabled-date="disabledJcdtDate" placeholder="请选择建成日期" style="width: 100%" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
@ -110,7 +110,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import dayjs from 'dayjs';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addEqInfo, updateEqInfo } from '@/api/DataQueryMenuModule'; import { addEqInfo, updateEqInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -130,6 +131,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -142,7 +144,7 @@ const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const engLoading = ref(false); const engLoading = ref(false);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode })) jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
); );
@ -178,11 +180,33 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
return label.includes(inputValue || ''); return label.includes(inputValue || '');
}; };
//
const disabledSwdtDate = (current: any) => {
if (!formData.value.jcdt) return false;
return current && current > dayjs(formData.value.jcdt).endOf('day');
};
//
const disabledJcdtDate = (current: any) => {
if (!formData.value.swdt) return false;
return current && current < dayjs(formData.value.swdt).startOf('day');
};
watch(() => formData.value, newData => { watch(() => formData.value, newData => {
const original = originalRecord.value; const original = originalRecord.value;
for (const key in newData) { for (const key in newData) {
@ -195,7 +219,7 @@ watch(() => formData.value, newData => {
if (oldNorm === newNorm) continue; if (oldNorm === newNorm) continue;
if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue; if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect ? resolveSelectLabel(key, oldNorm) : oldNorm === null ? '空' : String(oldNorm); const oldDisplay = isSelect ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm)) : oldNorm === null ? '空' : String(oldNorm);
const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm); const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm);
const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay }; const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay };
if (existingIdx >= 0) changeOrder.value[existingIdx] = entry; if (existingIdx >= 0) changeOrder.value[existingIdx] = entry;
@ -206,15 +230,54 @@ watch(() => formData.value, newData => {
} }
}, { deep: true }); }, { deep: true });
// record
const isInitLoading = ref(false);
watch(() => props.record, newRecord => { watch(() => props.record, newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, { deep: true }); }, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
// baseId // baseId
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
@ -235,11 +298,15 @@ const loadDropdownData = () => {
}).then(res => { }).then(res => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode })); sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode })); // store computed
}; };
// //
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -51,7 +51,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addVdInfo, updateVdInfo } from '@/api/DataQueryMenuModule'; import { addVdInfo, updateVdInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -71,6 +71,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -82,8 +83,10 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode })) jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
); );
const engLoading = ref(false); const engLoading = ref(false);
@ -113,6 +116,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
return label.includes(inputValue || ''); return label.includes(inputValue || '');
@ -130,7 +143,7 @@ watch(() => formData.value, newData => {
if (oldNorm === newNorm) continue; if (oldNorm === newNorm) continue;
if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue; if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect ? resolveSelectLabel(key, oldNorm) : oldNorm === null ? '空' : String(oldNorm); const oldDisplay = isSelect ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm)) : oldNorm === null ? '空' : String(oldNorm);
const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm); const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm);
const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay }; const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay };
if (existingIdx >= 0) changeOrder.value[existingIdx] = entry; if (existingIdx >= 0) changeOrder.value[existingIdx] = entry;
@ -141,15 +154,54 @@ watch(() => formData.value, newData => {
} }
}, { deep: true }); }, { deep: true });
// record
const isInitLoading = ref(false);
watch(() => props.record, newRecord => { watch(() => props.record, newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, { deep: true }); }, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
// baseId // baseId
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
@ -170,11 +222,15 @@ const loadDropdownData = () => {
}).then(res => { }).then(res => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode })); sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode })); // store computed
}; };
// //
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -125,6 +125,8 @@
<a-textarea <a-textarea
v-model:value="formData.introduce" v-model:value="formData.introduce"
placeholder="请输入简介" placeholder="请输入简介"
:maxlength="1000"
show-count
:rows="3" :rows="3"
/> />
</a-form-item> </a-form-item>
@ -134,6 +136,8 @@
<a-textarea <a-textarea
v-model:value="formData.remark" v-model:value="formData.remark"
placeholder="请输入备注" placeholder="请输入备注"
:maxlength="150"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -152,7 +156,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addWeInfo, updateWeInfo } from '@/api/DataQueryMenuModule'; import { addWeInfo, updateWeInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -180,6 +184,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -192,7 +197,7 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({
@ -242,6 +247,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -274,7 +289,7 @@ watch(
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -303,19 +318,57 @@ watch(
); );
// record // record
const isInitLoading = ref(false);
watch( watch(
() => props.record, () => props.record,
newRecord => { newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, },
{ deep: true } { deep: true }
); );
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
// baseId // baseId
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
@ -351,17 +404,15 @@ const loadDropdownData = () => {
value: item.sttpCode value: item.sttpCode
})); }));
}); });
// store // store computed
baseNameOptions.value = jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
}; };
// //
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -147,7 +147,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addWtInfo, updateWtInfo } from '@/api/DataQueryMenuModule'; import { addWtInfo, updateWtInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -175,6 +175,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -187,7 +188,7 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({
@ -241,6 +242,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -273,7 +284,7 @@ watch(
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -302,19 +313,57 @@ watch(
); );
// record // record
const isInitLoading = ref(false);
watch( watch(
() => props.record, () => props.record,
newRecord => { newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, },
{ deep: true } { deep: true }
); );
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
try { try {
@ -349,16 +398,14 @@ const loadDropdownData = () => {
value: item.sttpCode value: item.sttpCode
})); }));
}); });
// store // store computed
baseNameOptions.value = jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
}; };
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -177,7 +177,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addWqInfo, updateWqInfo } from '@/api/DataQueryMenuModule'; import { addWqInfo, updateWqInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -206,6 +206,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -219,7 +220,7 @@ const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const wwqtgOptions = ref<any[]>([]); const wwqtgOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({
@ -282,6 +283,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -314,7 +325,7 @@ watch(
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -343,19 +354,57 @@ watch(
); );
// record // record
const isInitLoading = ref(false);
watch( watch(
() => props.record, () => props.record,
newRecord => { newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, },
{ deep: true } { deep: true }
); );
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions, wwqtgOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
try { try {
@ -399,15 +448,14 @@ const loadDropdownData = () => {
})); }));
} }
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData // store computed
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
}; };
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -176,6 +176,8 @@
<a-textarea <a-textarea
v-model:value="formData.introduce" v-model:value="formData.introduce"
placeholder="请输入简介" placeholder="请输入简介"
:maxlength="1000"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -185,6 +187,8 @@
<a-textarea <a-textarea
v-model:value="formData.remark" v-model:value="formData.remark"
placeholder="请输入备注" placeholder="请输入备注"
:maxlength="150"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -203,7 +207,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addSonarInfo, updateSonarInfo } from '@/api/DataQueryMenuModule'; import { addSonarInfo, updateSonarInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -231,18 +235,20 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
stcd: [{ required: true, message: '请输入站码', trigger: 'blur' }], stcd: [{ required: true, message: '请输入站码', trigger: 'blur' }],
stnm: [{ required: true, message: '请输入站名', trigger: 'blur' }], stnm: [{ required: true, message: '请输入站名', trigger: 'blur' }],
sttp: [{ required: true, message: '请选择监控类别', trigger: 'change' }] sttp: [{ required: true, message: '请选择监控类别', trigger: 'change' }],
mntp: [{ required: true, message: '请输入监控类型', trigger: 'blur' }],
}); });
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({
@ -304,6 +310,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -335,7 +351,7 @@ watch(
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -363,17 +379,52 @@ watch(
{ deep: true } { deep: true }
); );
watch( // record
() => props.record, const isInitLoading = ref(false);
newRecord => { watch(() => props.record, newRecord => {
if (newRecord) { if (newRecord) {
const converted = { ...newRecord }; isInitLoading.value = true;
originalRecord.value = { ...converted }; const converted = { ...newRecord };
formData.value = { ...converted }; // "-" null date-picker Invalid Date
changeOrder.value = []; for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
} }
}, originalRecord.value = { ...converted };
{ deep: true } formData.value = { ...converted };
changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
}
}, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
); );
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
@ -408,15 +459,14 @@ const loadDropdownData = () => {
value: item.sttpCode value: item.sttpCode
})); }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData // baseNameOptions computed
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
}; };
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -179,6 +179,8 @@
<a-textarea <a-textarea
v-model:value="formData.introduce" v-model:value="formData.introduce"
placeholder="请输入简介" placeholder="请输入简介"
:maxlength="1000"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -188,6 +190,8 @@
<a-textarea <a-textarea
v-model:value="formData.remark" v-model:value="formData.remark"
placeholder="请输入备注" placeholder="请输入备注"
:maxlength="150"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -206,7 +210,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addDwInfo, updateDwInfo } from '@/api/DataQueryMenuModule'; import { addDwInfo, updateDwInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -234,6 +238,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -246,7 +251,7 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({
@ -310,6 +315,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -342,7 +357,7 @@ watch(
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -371,19 +386,57 @@ watch(
); );
// record // record
const isInitLoading = ref(false);
watch( watch(
() => props.record, () => props.record,
newRecord => { newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, },
{ deep: true } { deep: true }
); );
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
try { try {
@ -418,15 +471,14 @@ const loadDropdownData = () => {
value: item.sttpCode value: item.sttpCode
})); }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData // store computed
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
}; };
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -187,6 +187,8 @@
<a-textarea <a-textarea
v-model:value="formData.introduce" v-model:value="formData.introduce"
placeholder="请输入简介" placeholder="请输入简介"
:maxlength="1000"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -196,6 +198,8 @@
<a-textarea <a-textarea
v-model:value="formData.remark" v-model:value="formData.remark"
placeholder="请输入备注" placeholder="请输入备注"
:maxlength="150"
show-count
:rows="2" :rows="2"
/> />
</a-form-item> </a-form-item>
@ -214,7 +218,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addOtteInfo, updateOtteInfo } from '@/api/DataQueryMenuModule'; import { addOtteInfo, updateOtteInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -242,6 +246,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -254,13 +259,10 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ .map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
label: item.wbsName,
value: item.wbsCode
}))
); );
const engLoading = ref(false); const engLoading = ref(false);
@ -325,6 +327,16 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
const keyword = inputValue || ''; const keyword = inputValue || '';
@ -356,7 +368,7 @@ watch(
continue; continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect const oldDisplay = isSelect
? resolveSelectLabel(key, oldNorm) ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm))
: oldNorm === null : oldNorm === null
? '空' ? '空'
: String(oldNorm); : String(oldNorm);
@ -384,19 +396,58 @@ watch(
{ deep: true } { deep: true }
); );
// record
const isInitLoading = ref(false);
watch( watch(
() => props.record, () => props.record,
newRecord => { newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, },
{ deep: true } { deep: true }
); );
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
try { try {
@ -429,15 +480,14 @@ const loadDropdownData = () => {
value: item.sttpCode value: item.sttpCode
})); }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData // store computed
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({
label: item.wbsName,
value: item.wbsCode
}));
}; };
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -57,12 +57,12 @@
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="开工日期" name="swdt"> <a-form-item label="开工日期" name="swdt">
<a-date-picker v-model:value="formData.swdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开工日期" style="width: 100%" /> <a-date-picker v-model:value="formData.swdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开工日期" :disabled-date="disabledSwdtDate" style="width: 100%" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="建成日期" name="jcdt"> <a-form-item label="建成日期" name="jcdt">
<a-date-picker v-model:value="formData.jcdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择建成日期" style="width: 100%" /> <a-date-picker v-model:value="formData.jcdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择建成日期" :disabled-date="disabledJcdtDate" style="width: 100%" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
@ -123,7 +123,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import dayjs from 'dayjs';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addFbInfo, updateFbInfo } from '@/api/DataQueryMenuModule'; import { addFbInfo, updateFbInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -143,6 +144,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -154,7 +156,7 @@ const formRules = ref<any>({
const engInfoOptions = ref<any[]>([]); const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData jidiSelectEventStore.jidiData
.filter((item: any) => item.wbsCode !== 'all') .filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode })) .map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
@ -189,11 +191,32 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
return label.includes(inputValue || ''); return label.includes(inputValue || '');
}; };
//
const disabledSwdtDate = (current: any) => {
if (!formData.value.jcdt) return false;
return current && current > dayjs(formData.value.jcdt).endOf('day');
};
//
const disabledJcdtDate = (current: any) => {
if (!formData.value.swdt) return false;
return current && current < dayjs(formData.value.swdt).startOf('day');
};
watch(() => formData.value, newData => { watch(() => formData.value, newData => {
const original = originalRecord.value; const original = originalRecord.value;
for (const key in newData) { for (const key in newData) {
@ -206,7 +229,7 @@ watch(() => formData.value, newData => {
if (oldNorm === newNorm) continue; if (oldNorm === newNorm) continue;
if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue; if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect ? resolveSelectLabel(key, oldNorm) : oldNorm === null ? '空' : String(oldNorm); const oldDisplay = isSelect ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm)) : oldNorm === null ? '空' : String(oldNorm);
const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm); const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm);
const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay }; const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay };
if (existingIdx >= 0) changeOrder.value[existingIdx] = entry; if (existingIdx >= 0) changeOrder.value[existingIdx] = entry;
@ -217,15 +240,54 @@ watch(() => formData.value, newData => {
} }
}, { deep: true }); }, { deep: true });
// record
const isInitLoading = ref(false);
watch(() => props.record, newRecord => { watch(() => props.record, newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, { deep: true }); }, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
try { try {
@ -245,13 +307,15 @@ const loadDropdownData = () => {
}).then(res => { }).then(res => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode })); sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData // store computed
.filter((item: any) => item.wbsCode !== 'all')
.map((item: any) => ({ label: item.wbsName, value: item.wbsCode }));
}; };
// //
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -50,12 +50,12 @@
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
<a-form-item label="开工日期" name="swdt"> <a-form-item label="开工日期" name="swdt">
<a-date-picker v-model:value="formData.swdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开工日期" style="width: 100%" /> <a-date-picker v-model:value="formData.swdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" :disabled-date="disabledSwdtDate" placeholder="请选择开工日期" style="width: 100%" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
<a-form-item label="建成日期" name="jcdt"> <a-form-item label="建成日期" name="jcdt">
<a-date-picker v-model:value="formData.jcdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择建成日期" style="width: 100%" /> <a-date-picker v-model:value="formData.jcdt" format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择建成日期" style="width: 100%" :disabled-date="disabledJcdtDate" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
@ -81,7 +81,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue'; import { ref, computed, watch, nextTick } from 'vue';
import dayjs from 'dayjs';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addVpInfo, updateVpInfo } from '@/api/DataQueryMenuModule'; import { addVpInfo, updateVpInfo } from '@/api/DataQueryMenuModule';
import { getEngInfoDropdown } from '@/api/select'; import { getEngInfoDropdown } from '@/api/select';
@ -101,6 +102,7 @@ const formRef = ref();
const confirmLoading = ref(false); const confirmLoading = ref(false);
const formData = ref<any>({}); const formData = ref<any>({});
const originalRecord = ref<any>({}); const originalRecord = ref<any>({});
const originalLabels = ref<Record<string, string>>({});
const confirmModalVisible = ref(false); const confirmModalVisible = ref(false);
const formRules = ref<any>({ const formRules = ref<any>({
@ -113,14 +115,14 @@ const engInfoOptions = ref<any[]>([]);
const sttpOptions = ref<any[]>([]); const sttpOptions = ref<any[]>([]);
const engLoading = ref(false); const engLoading = ref(false);
const baseNameOptions = ref<any[]>( const baseNameOptions = computed(() =>
jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode })) jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode }))
); );
const fieldLabelMap: Record<string, string> = { const fieldLabelMap: Record<string, string> = {
stcd: '植物园编码', stnm: '植物园名称', stlc: '站址', sttp: '测站类型', stcd: '植物园编码', stnm: '植物园名称', stlc: '站址', sttp: '测站类型',
baseId: '水电基地', rstcd: '所属电站', swdt: '开工日期', jcdt: '建成日期', baseId: '水电基地', rstcd: '所属电站', swdt: '开工日期', jcdt: '建成日期',
bhfs: '保护方式', area: '面积(km²)', inv: '投资(亿元)', bhfs: '保护方式', area: '面积(km²)', inv: '投资(亿元)',
lgtd: '经度(°)', lttd: '纬度(°)' lgtd: '经度(°)', lttd: '纬度(°)'
}; };
@ -143,11 +145,33 @@ const resolveSelectLabel = (field: string, value: any): string => {
return String(value); return String(value);
}; };
// rstcd record ennm
const resolveOriginalLabel = (field: string): string => {
const original = originalRecord.value;
if (field === 'rstcd') {
const ennm = original.ennm || original.rstcdName;
if (ennm) return String(ennm);
}
return resolveSelectLabel(field, original[field]);
};
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
const label = option.label || option.value; const label = option.label || option.value;
return label.includes(inputValue || ''); return label.includes(inputValue || '');
}; };
//
const disabledSwdtDate = (current: any) => {
if (!formData.value.jcdt) return false;
return current && current > dayjs(formData.value.jcdt).endOf('day');
};
//
const disabledJcdtDate = (current: any) => {
if (!formData.value.swdt) return false;
return current && current < dayjs(formData.value.swdt).startOf('day');
};
watch(() => formData.value, newData => { watch(() => formData.value, newData => {
const original = originalRecord.value; const original = originalRecord.value;
for (const key in newData) { for (const key in newData) {
@ -160,7 +184,7 @@ watch(() => formData.value, newData => {
if (oldNorm === newNorm) continue; if (oldNorm === newNorm) continue;
if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue; if (oldNorm !== null && newNorm !== null && !isNaN(Number(oldNorm)) && !isNaN(Number(newNorm)) && Number(oldNorm) === Number(newNorm)) continue;
const isSelect = !!selectOptionsMap[key]; const isSelect = !!selectOptionsMap[key];
const oldDisplay = isSelect ? resolveSelectLabel(key, oldNorm) : oldNorm === null ? '空' : String(oldNorm); const oldDisplay = isSelect ? (originalLabels.value[key] ?? resolveSelectLabel(key, oldNorm)) : oldNorm === null ? '空' : String(oldNorm);
const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm); const newDisplay = isSelect ? resolveSelectLabel(key, newNorm) : newNorm === null ? '空' : String(newNorm);
const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay }; const entry = { field: key, label: fieldLabelMap[key] || key, oldValue: oldDisplay, newValue: newDisplay };
if (existingIdx >= 0) changeOrder.value[existingIdx] = entry; if (existingIdx >= 0) changeOrder.value[existingIdx] = entry;
@ -171,15 +195,54 @@ watch(() => formData.value, newData => {
} }
}, { deep: true }); }, { deep: true });
// record
const isInitLoading = ref(false);
watch(() => props.record, newRecord => { watch(() => props.record, newRecord => {
if (newRecord) { if (newRecord) {
isInitLoading.value = true;
const converted = { ...newRecord }; const converted = { ...newRecord };
// "-" null date-picker Invalid Date
for (const key in converted) {
if (converted[key] === '-') {
converted[key] = null;
}
}
originalRecord.value = { ...converted }; originalRecord.value = { ...converted };
formData.value = { ...converted }; formData.value = { ...converted };
changeOrder.value = []; changeOrder.value = [];
// rstcd diff
loadEngOptions(converted.baseId || undefined);
// select label
const labels: Record<string, string> = {};
for (const key in converted) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
// true
nextTick(() => {
isInitLoading.value = false;
});
} }
}, { deep: true }); }, { deep: true });
// record code
watch(
[baseNameOptions, engInfoOptions, sttpOptions],
() => {
const original = originalRecord.value;
if (!original || Object.keys(original).length === 0) return;
const labels: Record<string, string> = {};
for (const key in original) {
if (selectOptionsMap[key]) {
labels[key] = resolveOriginalLabel(key);
}
}
originalLabels.value = labels;
}
);
const loadEngOptions = async (baseId?: string) => { const loadEngOptions = async (baseId?: string) => {
engLoading.value = true; engLoading.value = true;
try { try {
@ -199,11 +262,15 @@ const loadDropdownData = () => {
}).then(res => { }).then(res => {
sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode })); sttpOptions.value = (res.data?.data || []).map((item: any) => ({ label: item.sttpName, value: item.sttpCode }));
}); });
baseNameOptions.value = jidiSelectEventStore.jidiData.filter((item: any) => item.wbsCode !== 'all').map((item: any) => ({ label: item.wbsName, value: item.wbsCode })); // store computed
}; };
// //
watch(() => formData.value?.baseId, (newBaseId) => { watch(() => formData.value?.baseId, (newBaseId) => {
// record record watch
if (isInitLoading.value) {
return;
}
formData.value.rstcd = undefined; formData.value.rstcd = undefined;
loadEngOptions(newBaseId || undefined); loadEngOptions(newBaseId || undefined);
}); });

View File

@ -15,6 +15,7 @@
format="YYYY-MM-DD" format="YYYY-MM-DD"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
placeholder="起始时间" placeholder="起始时间"
:allow-clear="false"
:showToday="false" :showToday="false"
> >
<template #renderExtraFooter> <template #renderExtraFooter>
@ -33,6 +34,7 @@
<a-form-item-rest> <a-form-item-rest>
<a-date-picker <a-date-picker
class="w-[120px]" class="w-[120px]"
:allow-clear="false"
v-model:value="jcdt.max" v-model:value="jcdt.max"
format="YYYY-MM-DD" format="YYYY-MM-DD"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"

View File

@ -119,7 +119,7 @@ const tableScrollX = computed(() =>
// //
const columnsManual: any[] = [ const columnsManual: any[] = [
{ {
key: 'stnm', key: 'ennm',
title: '电站名称', title: '电站名称',
dataIndex: 'stnm', dataIndex: 'stnm',
visible: true, visible: true,
@ -261,9 +261,9 @@ const columnsManual: any[] = [
// //
const columnsAuto: any[] = [ const columnsAuto: any[] = [
{ {
key: 'stnm', key: 'ennm',
title: '电站名称', title: '电站名称',
dataIndex: 'stnm', dataIndex: 'ennm',
visible: true, visible: true,
width: 200, width: 200,
sort: true, sort: true,

View File

@ -14,6 +14,7 @@
v-model:value="jcdt.min" v-model:value="jcdt.min"
:format="timeFormat" :format="timeFormat"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
:allow-clear="false"
:picker="timePicker" :picker="timePicker"
:showTime="timeShowTime" :showTime="timeShowTime"
placeholder="起始时间" placeholder="起始时间"
@ -40,6 +41,7 @@
:format="timeFormat" :format="timeFormat"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
:picker="timePicker" :picker="timePicker"
:allow-clear="false"
:showTime="timeShowTime" :showTime="timeShowTime"
:disabledDate="disabledEndDate" :disabledDate="disabledEndDate"
placeholder="结束时间" placeholder="结束时间"

View File

@ -363,6 +363,7 @@ const displayColumns = computed(() => {
}); });
const onSearchFinish = async (values: any) => { const onSearchFinish = async (values: any) => {
// debugger
currentSearchParams.value = values; currentSearchParams.value = values;
await nextTick(); await nextTick();
initTable(values); initTable(values);
@ -438,7 +439,7 @@ const initTable = (values: any) => {
: null, : null,
values.rstcd values.rstcd
? { ? {
field: 'rstcd', field: 'stcd',
operator: 'eq', operator: 'eq',
dataType: 'string', dataType: 'string',
value: values.rstcd value: values.rstcd

View File

@ -16,6 +16,7 @@
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
:picker="timePicker" :picker="timePicker"
:showTime="timeShowTime" :showTime="timeShowTime"
:allow-clear="false"
placeholder="起始时间" placeholder="起始时间"
:showToday="false" :showToday="false"
:showNow="false" :showNow="false"
@ -42,6 +43,7 @@
:picker="timePicker" :picker="timePicker"
:showTime="timeShowTime" :showTime="timeShowTime"
:disabledDate="disabledEndDate" :disabledDate="disabledEndDate"
:allow-clear="false"
placeholder="结束时间" placeholder="结束时间"
:showToday="false" :showToday="false"
:showNow="false" :showNow="false"

View File

@ -593,8 +593,7 @@ const transformData = (data: any) => {
}) })
.reverse(); .reverse();
const total = data?.data?.data?.[0]?.total || 0; const total = data?.data?.total || 0;
tableData.value = formattedData; tableData.value = formattedData;
// //

View File

@ -17,6 +17,7 @@
:picker="timePicker" :picker="timePicker"
:showTime="timeShowTime" :showTime="timeShowTime"
placeholder="起始时间" placeholder="起始时间"
:allow-clear="false"
:showToday="false" :showToday="false"
:showNow="false" :showNow="false"
> >
@ -43,6 +44,7 @@
:showTime="timeShowTime" :showTime="timeShowTime"
:disabledDate="disabledEndDate" :disabledDate="disabledEndDate"
placeholder="结束时间" placeholder="结束时间"
:allow-clear="false"
:showToday="false" :showToday="false"
:showNow="false" :showNow="false"
> >

View File

@ -5,7 +5,7 @@ export default {
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, reactive, ref, nextTick } from 'vue'; import { onMounted, reactive, ref, nextTick, watch } from 'vue';
import { ElMessage, ElMessageBox, FormRules } from 'element-plus'; import { ElMessage, ElMessageBox, FormRules } from 'element-plus';
import Sortable from 'sortablejs'; import Sortable from 'sortablejs';
import { useAppStore } from '@/store/modules/app'; import { useAppStore } from '@/store/modules/app';
@ -31,6 +31,17 @@ const treedata: any = ref([]);
const treeRef = ref(); const treeRef = ref();
const treeId = ref(''); const treeId = ref('');
const defaultProps = { label: 'dictName' }; const defaultProps = { label: 'dictName' };
//
const treeFilterText = ref('');
function filterNode(value: string, data: any) {
if (!value) return true;
return data.dictName?.includes(value);
}
watch(treeFilterText, (val) => {
treeRef.value?.filter(val);
});
// //
const title = ref(''); const title = ref('');
const dialogdict = ref(false); const dialogdict = ref(false);
@ -432,6 +443,12 @@ const total = ref();
/> />
新增字典</el-button 新增字典</el-button
> >
<el-input
v-model="treeFilterText"
placeholder="请输入关键字过滤"
clearable
style="margin-bottom: 10px"
/>
<el-tree <el-tree
v-loading="treeloading" v-loading="treeloading"
ref="treeRef" ref="treeRef"
@ -446,9 +463,10 @@ const total = ref();
draggable draggable
:highlight-current="true" :highlight-current="true"
:props="defaultProps" :props="defaultProps"
:filter-node-method="filterNode"
@node-click="handleNodeClick" @node-click="handleNodeClick"
@node-drop="treenodeDrop" @node-drop="treenodeDrop"
style="height: calc(100vh - 254px); overflow: auto" style="height: calc(100vh - 304px); overflow: auto"
> >
<template #default="{ node, data }"> <template #default="{ node, data }">
<span class="custom-tree-node"> <span class="custom-tree-node">

View File

@ -34,8 +34,8 @@ const menuInfoRef = ref();
const btnInfoRef = ref(); const btnInfoRef = ref();
const loading = ref(false); const loading = ref(false);
//tabbar //tabbar
const systemcode = ref('2'); const systemcode = ref('1');
const activeIndex = ref('2'); const activeIndex = ref('1');
function handleSelect(key: string) { function handleSelect(key: string) {
if (key == '1') { if (key == '1') {
systemcode.value = '1'; systemcode.value = '1';
@ -585,9 +585,9 @@ onMounted(() => {
mode="horizontal" mode="horizontal"
@select="handleSelect" @select="handleSelect"
> >
<!-- <el-menu-item index="1">全过程数据管理子系统</el-menu-item> --> <el-menu-item index="1">水电水利建设项目全过程环境管理信息平台</el-menu-item>
<el-menu-item index="2">全过程数据管理子系统</el-menu-item> <el-menu-item index="2">全过程数据管理子系统</el-menu-item>
<!-- <el-menu-item index="4">填报管理子系统</el-menu-item> --> <el-menu-item index="4">填报管理子系统</el-menu-item>
</el-menu> </el-menu>
<div <div
style=" style="
@ -679,7 +679,7 @@ onMounted(() => {
align="center" align="center"
> >
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.systemcode == '1'">全过程数据管理子系统</span> <span v-if="scope.row.systemcode == '1'">水电水利建设项目全过程环境管理信息平台</span>
<span v-else-if="scope.row.systemcode == '2'">全过程数据管理子系统</span> <span v-else-if="scope.row.systemcode == '2'">全过程数据管理子系统</span>
<span v-else>填报管理子系统</span> <span v-else>填报管理子系统</span>
</template> </template>

View File

@ -247,6 +247,7 @@ function handleClose() {
:before-close="handleClose" :before-close="handleClose"
top="30px" top="30px"
draggable draggable
style="pointer-events: all;"
:destroy-on-close="false" :destroy-on-close="false"
> >
<el-table <el-table

View File

@ -1,15 +1,15 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: "review", name: 'review'
}; };
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, nextTick, watch } from "vue"; import { ref, onMounted, nextTick, watch } from 'vue';
import { import {
queryPendingAuditUsers, queryPendingAuditUsers,
deltableData, deltableData,
getRole, listGroupedByTenant,
addUsers, addUsers,
updataUser, updataUser,
setpass, setpass,
@ -17,20 +17,20 @@ import {
getFishtree, getFishtree,
saveFishqvan, saveFishqvan,
getuserdata, getuserdata,
auditUser, auditUser
} from "@/api/user"; } from '@/api/user';
import { getDictItemsByCode } from "@/api/dict"; import { getDictItemsByCode } from '@/api/dict';
import { ElMessageBox, ElMessage } from "element-plus"; import { ElMessageBox, ElMessage } from 'element-plus';
import Page from "@/components/Pagination/page.vue"; import Page from '@/components/Pagination/page.vue';
import { Search } from "@element-plus/icons-vue"; import { Search } from '@element-plus/icons-vue';
// //
const loading = ref(false); const loading = ref(false);
// //
const queryParams = ref({ const queryParams = ref({
current: 1, current: 1,
size: 10, size: 10,
querystr: "", querystr: '',
regStatus: "", regStatus: ''
}); });
// //
const total = ref(); const total = ref();
@ -39,25 +39,25 @@ const infoForm = ref();
// //
const dialogVisible = ref(false); const dialogVisible = ref(false);
const title = ref(""); const title = ref('');
function addClick() { function addClick() {
title.value = "新增用户"; title.value = '新增用户';
dialogVisible.value = true; dialogVisible.value = true;
info.value = { info.value = {
id: "", id: '',
username: "", username: '',
nickname: "", nickname: '',
email: "", email: '',
phone: "", phone: '',
belongingUnit: "", belongingUnit: '',
roleinfo: [], roleinfo: []
}; };
getrole(); getrole();
} }
// //
const multipleSelection = ref([]); const multipleSelection = ref([]);
const tableData = ref([]); const tableData = ref([]);
const orgId = ref(""); const orgId = ref('');
// //
function getdata() { function getdata() {
const params = { const params = {
@ -65,11 +65,11 @@ function getdata() {
size: queryParams.value.size, size: queryParams.value.size,
// orgid: orgId.value, // orgid: orgId.value,
name: queryParams.value.querystr, name: queryParams.value.querystr,
regStatus: queryParams.value.regStatus, regStatus: queryParams.value.regStatus
}; };
loading.value = true; loading.value = true;
queryPendingAuditUsers(params) queryPendingAuditUsers(params)
.then((res) => { .then(res => {
total.value = res.data.total; total.value = res.data.total;
tableData.value = res.data.records; tableData.value = res.data.records;
queryParams.value.size = res.data.size; queryParams.value.size = res.data.size;
@ -83,13 +83,13 @@ function getdata() {
// //
const info = ref({ const info = ref({
id: "", id: '',
username: "", username: '',
nickname: "", nickname: '',
email: "", email: '',
phone: "", phone: '',
belongingUnit: "", belongingUnit: '',
roleinfo: [] as any[], roleinfo: [] as any[]
}); });
//- //-
function editdepartment(row: any) { function editdepartment(row: any) {
@ -103,7 +103,7 @@ function editdepartment(row: any) {
info.value = JSON.parse(JSON.stringify(row)); info.value = JSON.parse(JSON.stringify(row));
info.value.roleinfo = selectID; info.value.roleinfo = selectID;
rolesdata.value = row.roles; rolesdata.value = row.roles;
title.value = "修改用户"; title.value = '修改用户';
dialogVisible.value = true; dialogVisible.value = true;
getrole(); getrole();
} }
@ -120,15 +120,15 @@ function confirmClick(formEl: any) {
nickname: info.value.nickname, nickname: info.value.nickname,
email: info.value.email, email: info.value.email,
phone: info.value.phone, phone: info.value.phone,
belongingUnit: info.value.belongingUnit, belongingUnit: info.value.belongingUnit
}; };
const roleids = String(info.value.roleinfo); const roleids = String(info.value.roleinfo);
updataUser(params, roleids).then(() => { updataUser(params, roleids).then(() => {
getdata(); getdata();
dialogVisible.value = false; dialogVisible.value = false;
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "修改成功", message: '修改成功'
}); });
}); });
} else { } else {
@ -138,15 +138,15 @@ function confirmClick(formEl: any) {
email: info.value.email, email: info.value.email,
phone: info.value.phone, phone: info.value.phone,
belongingUnit: info.value.belongingUnit, belongingUnit: info.value.belongingUnit,
orgid: orgId.value, orgid: orgId.value
}; };
const roleids = info.value.roleinfo; const roleids = info.value.roleinfo;
addUsers(params, roleids).then((res) => { addUsers(params, roleids).then(res => {
getdata(); getdata();
dialogVisible.value = false; dialogVisible.value = false;
ElMessage({ ElMessage({
type: "success", type: 'success',
message: res.data.msg, message: res.data.msg
}); });
}); });
} }
@ -155,8 +155,8 @@ function confirmClick(formEl: any) {
} }
// //
const moderules = ref({ const moderules = ref({
username: [{ required: true, message: "请输入用户账号", trigger: "blur" }], username: [{ required: true, message: '请输入用户账号', trigger: 'blur' }],
nickname: [{ required: true, message: "请输入用户名称", trigger: "blur" }], nickname: [{ required: true, message: '请输入用户名称', trigger: 'blur' }]
}); });
// //
@ -166,17 +166,17 @@ function handleClose() {
} }
// //
const userid = ref(""); const userid = ref('');
const resultPawss = ref(false); const resultPawss = ref(false);
const msgText = ref(""); const msgText = ref('');
function setpassword(row: any) { function setpassword(row: any) {
ElMessageBox.confirm("确定要重置此账号密码吗?", "重置密码", { ElMessageBox.confirm('确定要重置此账号密码吗?', '重置密码', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning'
}).then(() => { }).then(() => {
const params = { const params = {
id: userid.value, id: userid.value
}; };
setpass(params).then((res: any) => { setpass(params).then((res: any) => {
if (res.code == 0) { if (res.code == 0) {
@ -196,7 +196,7 @@ function closeResult() {
} }
// //
const fishway = ref(false); const fishway = ref(false);
const userId = ref(""); const userId = ref('');
// ID // ID
const fishhui = ref<any[]>([]); const fishhui = ref<any[]>([]);
const fishTreeDialog = ref(false); const fishTreeDialog = ref(false);
@ -207,7 +207,7 @@ const isFishDataLoaded = ref(false);
async function openFishway(row: any) { async function openFishway(row: any) {
fishway.value = true; fishway.value = true;
userId.value = row.id; userId.value = row.id;
treeInput.value = ""; treeInput.value = '';
// //
fishhui.value = []; fishhui.value = [];
tableDatafish.value = []; tableDatafish.value = [];
@ -218,7 +218,7 @@ async function openFishway(row: any) {
await Promise.all([ await Promise.all([
getFishTree(), // getFishTree(), //
getuserdata({ userId: userId.value }).then((res: any) => { getuserdata({ userId: userId.value }).then((res: any) => {
console.log("用户权限数据:", res); console.log('用户权限数据:', res);
if (res.code == 0) { if (res.code == 0) {
res.data.forEach((item: any) => { res.data.forEach((item: any) => {
fishhui.value.push(item.orgId); fishhui.value.push(item.orgId);
@ -231,19 +231,19 @@ async function openFishway(row: any) {
userId: item.userId, userId: item.userId,
parentId: item.parentId, parentId: item.parentId,
orgLevel: item.orgLevel, orgLevel: item.orgLevel,
permissionType: item.permissionType, permissionType: item.permissionType
}); });
}); });
} }
}), })
]); ]);
// //
isFishDataLoaded.value = true; isFishDataLoaded.value = true;
console.log("所有数据加载完成,准备回显"); console.log('所有数据加载完成,准备回显');
} catch (error) { } catch (error) {
console.error("加载数据失败:", error); console.error('加载数据失败:', error);
ElMessage.error("加载数据失败,请重试"); ElMessage.error('加载数据失败,请重试');
} }
} }
@ -251,9 +251,9 @@ async function openFishway(row: any) {
watch([fishway, isFishDataLoaded], ([newFishway, newDataLoaded]) => { watch([fishway, isFishDataLoaded], ([newFishway, newDataLoaded]) => {
if (newFishway && newDataLoaded) { if (newFishway && newDataLoaded) {
// //
console.log("开始回显, fishTreeRef:", fishTreeRef.value); console.log('开始回显, fishTreeRef:', fishTreeRef.value);
console.log("回显ID:", fishhui.value); console.log('回显ID:', fishhui.value);
console.log("树数据:", fishData.value); console.log('树数据:', fishData.value);
// 使 nextTick DOM // 使 nextTick DOM
nextTick(() => { nextTick(() => {
@ -270,7 +270,7 @@ watch([fishway, isFishDataLoaded], ([newFishway, newDataLoaded]) => {
fishhui.value, fishhui.value,
fishData.value fishData.value
); );
console.log("需要展开的父节点codes:", parentCodesToExpand); console.log('需要展开的父节点codes:', parentCodesToExpand);
// / // /
setTreeExpandState(parentCodesToExpand); setTreeExpandState(parentCodesToExpand);
@ -278,8 +278,8 @@ watch([fishway, isFishDataLoaded], ([newFishway, newDataLoaded]) => {
// //
const checkedKeys = fishTreeRef.value.getCheckedKeys(); const checkedKeys = fishTreeRef.value.getCheckedKeys();
const halfCheckedKeys = fishTreeRef.value.getHalfCheckedKeys(); const halfCheckedKeys = fishTreeRef.value.getHalfCheckedKeys();
console.log("回显完成 - 全选节点:", checkedKeys); console.log('回显完成 - 全选节点:', checkedKeys);
console.log("回显完成 - 半选节点:", halfCheckedKeys); console.log('回显完成 - 半选节点:', halfCheckedKeys);
// //
fishTableData.value = tableDatafish.value; fishTableData.value = tableDatafish.value;
@ -294,7 +294,7 @@ watch([fishway, isFishDataLoaded], ([newFishway, newDataLoaded]) => {
}); });
} else if (!newFishway) { } else if (!newFishway) {
// //
console.log("关闭对话框,清理数据"); console.log('关闭对话框,清理数据');
fishhui.value = []; fishhui.value = [];
isFishDataLoaded.value = false; isFishDataLoaded.value = false;
// tree // tree
@ -314,12 +314,12 @@ function fishHandleClose() {
fishData.value = []; fishData.value = [];
} }
// //
const treeInput = ref(""); const treeInput = ref('');
const fishProps = { const fishProps = {
children: "children", children: 'children',
label: "name", label: 'name'
}; };
watch(treeInput, (val) => { watch(treeInput, val => {
fishTreeRef.value!.filter(val); fishTreeRef.value!.filter(val);
}); });
function filterNode(value: string, data: any) { function filterNode(value: string, data: any) {
@ -364,13 +364,16 @@ function getAllChildrenIds(node: any): number[] {
} }
// - // -
function areAllChildrenChecked(parentNode: any, checkedKeysArray: any[]): boolean { function areAllChildrenChecked(
parentNode: any,
checkedKeysArray: any[]
): boolean {
const allChildrenIds = getAllChildrenIds(parentNode); const allChildrenIds = getAllChildrenIds(parentNode);
if (allChildrenIds.length === 0) { if (allChildrenIds.length === 0) {
return false; return false;
} }
// IDkeys // IDkeys
return allChildrenIds.every((code) => checkedKeysArray.includes(code)); return allChildrenIds.every(code => checkedKeysArray.includes(code));
} }
// - // -
@ -394,7 +397,10 @@ function isNodeContainedByOtherParent(
} }
// IDs:,ID // IDs:,ID
function filterSelectedIds(checkedKeysArray: number[], allCheckedNodes: any[]): number[] { function filterSelectedIds(
checkedKeysArray: number[],
allCheckedNodes: any[]
): number[] {
const resultIds: number[] = []; const resultIds: number[] = [];
const fullySelectedParentIds: number[] = []; const fullySelectedParentIds: number[] = [];
const filteredNodeIds = new Set<number>(); const filteredNodeIds = new Set<number>();
@ -405,7 +411,7 @@ function filterSelectedIds(checkedKeysArray: number[], allCheckedNodes: any[]):
if (areAllChildrenChecked(node, checkedKeysArray)) { if (areAllChildrenChecked(node, checkedKeysArray)) {
fullySelectedParentIds.push(node.code); fullySelectedParentIds.push(node.code);
const childrenIds = getAllChildrenIds(node); const childrenIds = getAllChildrenIds(node);
childrenIds.forEach((childId) => { childrenIds.forEach(childId => {
filteredNodeIds.add(childId); filteredNodeIds.add(childId);
}); });
} }
@ -414,9 +420,13 @@ function filterSelectedIds(checkedKeysArray: number[], allCheckedNodes: any[]):
// : // :
// 1. ""() // 1. ""()
fullySelectedParentIds.forEach((parentId) => { fullySelectedParentIds.forEach(parentId => {
if ( if (
!isNodeContainedByOtherParent(parentId, fullySelectedParentIds, allCheckedNodes) !isNodeContainedByOtherParent(
parentId,
fullySelectedParentIds,
allCheckedNodes
)
) { ) {
resultIds.push(parentId); resultIds.push(parentId);
} }
@ -426,14 +436,18 @@ function filterSelectedIds(checkedKeysArray: number[], allCheckedNodes: any[]):
allCheckedNodes.forEach((node: any) => { allCheckedNodes.forEach((node: any) => {
if (!filteredNodeIds.has(node.code) && !resultIds.includes(node.code)) { if (!filteredNodeIds.has(node.code) && !resultIds.includes(node.code)) {
if ( if (
!isNodeContainedByOtherParent(node.code, fullySelectedParentIds, allCheckedNodes) !isNodeContainedByOtherParent(
node.code,
fullySelectedParentIds,
allCheckedNodes
)
) { ) {
resultIds.push(node.code); resultIds.push(node.code);
} }
} }
}); });
console.log("过滤后的IDs:", resultIds); console.log('过滤后的IDs:', resultIds);
return resultIds; return resultIds;
} }
@ -491,7 +505,7 @@ function handleFishCheckChange(checkedNode: any, checkedInfo: any) {
// 使IDs // 使IDs
const resultIds = filterSelectedIds(checkedKeysArray, allCheckedNodes); const resultIds = filterSelectedIds(checkedKeysArray, allCheckedNodes);
console.log("最终获取的IDs:", resultIds); console.log('最终获取的IDs:', resultIds);
// //
getFishTableData(resultIds); getFishTableData(resultIds);
@ -519,7 +533,7 @@ function getFishTableData(ids: any[]) {
userId: userId.value, userId: userId.value,
parentId: node.parentId, parentId: node.parentId,
orgLevel: node.orgLevel, orgLevel: node.orgLevel,
permissionType: "READ", // permissionType: 'READ' //
}); });
} }
@ -537,16 +551,16 @@ function getFishTableData(ids: any[]) {
const tableids: any = ref([]); const tableids: any = ref([]);
// //
function fishDataHandleSelectionChange(val: any) { function fishDataHandleSelectionChange(val: any) {
console.log("选中的行数据:", val); console.log('选中的行数据:', val);
fishTableSelection.value = val; fishTableSelection.value = val;
} }
// //
function delFishTable() { function delFishTable() {
ElMessageBox.confirm("确定移除选中权限吗?", "删除提示", { ElMessageBox.confirm('确定移除选中权限吗?', '删除提示', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning'
}) })
.then(() => { .then(() => {
// ID // ID
@ -579,8 +593,8 @@ function delFishTable() {
} }
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "删除成功", message: '删除成功'
}); });
// //
@ -622,34 +636,36 @@ function fishSure() {
parentId: item.parentId, parentId: item.parentId,
orgLevel: item.orgLevel, orgLevel: item.orgLevel,
path: item.path, path: item.path,
permissionType: item.permissionType, permissionType: item.permissionType
}); });
}); });
saveFishqvan({ userId: userId.value, dataScopeList: params }).then((res: any) => { saveFishqvan({ userId: userId.value, dataScopeList: params }).then(
console.log(res); (res: any) => {
if (res.code == 0) { console.log(res);
ElMessage({ if (res.code == 0) {
message: "保存成功", ElMessage({
type: "success", message: '保存成功',
}); type: 'success'
fishHandleClose(); });
fishHandleClose();
}
} }
}); );
} }
// //
function delclick(row: any) { function delclick(row: any) {
ElMessageBox.confirm("确定删除此用户吗?", "删除提示", { ElMessageBox.confirm('确定删除此用户吗?', '删除提示', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning'
}).then(() => { }).then(() => {
const params = { const params = {
id: row.id, id: row.id
}; };
deltableData(params).then(() => { deltableData(params).then(() => {
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "删除成功", message: '删除成功'
}); });
getdata(); getdata();
}); });
@ -658,9 +674,9 @@ function delclick(row: any) {
// //
function getrole() { function getrole() {
const params = { const params = {
rolename: "", rolename: ''
}; };
getRole(params).then((res) => { listGroupedByTenant(params).then(res => {
rolesdata.value = res; rolesdata.value = res;
}); });
} }
@ -676,18 +692,18 @@ function delchoice() {
ids.value.forEach((item: any) => { ids.value.forEach((item: any) => {
choice.push(item.id); choice.push(item.id);
}); });
ElMessageBox.confirm("确定删除此用户吗?", "删除提示", { ElMessageBox.confirm('确定删除此用户吗?', '删除提示', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning'
}).then(() => { }).then(() => {
const params = { const params = {
id: String(choice), id: String(choice)
}; };
delChoise(params).then(() => { delChoise(params).then(() => {
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "删除成功", message: '删除成功'
}); });
getdata(); getdata();
}); });
@ -700,14 +716,32 @@ function dateFormat(row: any) {
var date = new Date(daterc); var date = new Date(daterc);
var year = date.getFullYear(); var year = date.getFullYear();
var month = var month =
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; date.getMonth() + 1 < 10
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; ? '0' + (date.getMonth() + 1)
var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); : date.getMonth() + 1;
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours(); date.getMonth() + 1 < 10
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes(); ? '0' + (date.getMonth() + 1)
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds(); : date.getMonth() + 1;
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
var minutes =
date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
var seconds =
date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
// //
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; return (
year +
'-' +
month +
'-' +
day +
' ' +
hours +
':' +
minutes +
':' +
seconds
);
} }
} }
@ -715,11 +749,11 @@ function dateFormat(row: any) {
// //
function getName(arr: any[], type: any): string { function getName(arr: any[], type: any): string {
if (!arr || !Array.isArray(arr) || type === undefined || type === null) { if (!arr || !Array.isArray(arr) || type === undefined || type === null) {
return ""; return '';
} }
const items = arr.find((item: any) => item?.itemCode == type); const items = arr.find((item: any) => item?.itemCode == type);
console.log(items); console.log(items);
return items?.dictName || ""; return items?.dictName || '';
} }
// Tag // Tag
@ -730,60 +764,60 @@ function getRegStatusColor(type: any): string {
type === undefined || type === undefined ||
type === null type === null
) { ) {
return "info"; return 'info';
} }
const items = regStatusArr.value.find((item: any) => item?.itemCode == type); const items = regStatusArr.value.find((item: any) => item?.itemCode == type);
const color = items?.custom1 || "info"; const color = items?.custom1 || 'info';
// custom1Element Plus Tag // custom1Element Plus Tag
const colorMap: Record<string, string> = { const colorMap: Record<string, string> = {
blue: "primary", // - blue: 'primary', // -
green: "success", // - 绿 green: 'success', // - 绿
red: "danger", // - red: 'danger' // -
}; };
return colorMap[color] || "info"; return colorMap[color] || 'info';
} }
// ==================== ==================== // ==================== ====================
// //
const auditDialogVisible = ref(false); const auditDialogVisible = ref(false);
// 1-2- // 1-2-
const auditType = ref(""); const auditType = ref('');
// ID // ID
const currentAuditUserId = ref(""); const currentAuditUserId = ref('');
// //
const auditForm = ref({ const auditForm = ref({
commentInfo: "", commentInfo: ''
}); });
// //
const auditFormRef = ref(); const auditFormRef = ref();
// //
const auditRules = ref({ const auditRules = ref({
commentInfo: [{ required: true, message: "请输入审批意见", trigger: "blur" }], commentInfo: [{ required: true, message: '请输入审批意见', trigger: 'blur' }]
}); });
// //
function handleAuditPass(row: any) { function handleAuditPass(row: any) {
currentAuditUserId.value = row.id; currentAuditUserId.value = row.id;
auditType.value = "APPROVED"; auditType.value = 'APPROVED';
auditForm.value.commentInfo = ""; auditForm.value.commentInfo = '';
auditDialogVisible.value = true; auditDialogVisible.value = true;
} }
// //
function handleAuditReject(row: any) { function handleAuditReject(row: any) {
currentAuditUserId.value = row.id; currentAuditUserId.value = row.id;
auditType.value = "REJECTED"; auditType.value = 'REJECTED';
auditForm.value.commentInfo = ""; auditForm.value.commentInfo = '';
auditDialogVisible.value = true; auditDialogVisible.value = true;
} }
// //
function handleAuditClose() { function handleAuditClose() {
auditDialogVisible.value = false; auditDialogVisible.value = false;
auditForm.value.commentInfo = ""; auditForm.value.commentInfo = '';
if (auditFormRef.value) { if (auditFormRef.value) {
auditFormRef.value.resetFields(); auditFormRef.value.resetFields();
} }
@ -796,22 +830,23 @@ function submitAudit(formEl: any) {
const params = { const params = {
userId: currentAuditUserId.value, userId: currentAuditUserId.value,
regStatus: auditType.value, regStatus: auditType.value,
commentInfo: auditForm.value.commentInfo, commentInfo: auditForm.value.commentInfo
}; };
auditUser(params) auditUser(params)
.then(() => { .then(() => {
ElMessage({ ElMessage({
type: "success", type: 'success',
message: auditType.value === "APPROVED" ? "审批通过成功" : "审批驳回成功", message:
auditType.value === 'APPROVED' ? '审批通过成功' : '审批驳回成功'
}); });
handleAuditClose(); handleAuditClose();
getdata(); // getdata(); //
}) })
.catch(() => { .catch(() => {
ElMessage({ ElMessage({
type: "error", type: 'error',
message: "审批操作失败,请重试", message: '审批操作失败,请重试'
}); });
}); });
} }
@ -825,10 +860,10 @@ onMounted(() => {
const dictData = ref([]); const dictData = ref([]);
const regStatusArr = ref([]); const regStatusArr = ref([]);
function getdictdata() { function getdictdata() {
getDictItemsByCode({ dictCode: "resourceType" }).then((res) => { getDictItemsByCode({ dictCode: 'resourceType' }).then(res => {
dictData.value = res.data; dictData.value = res.data;
}); });
getDictItemsByCode({ dictCode: "approvalStatus" }).then((res) => { getDictItemsByCode({ dictCode: 'approvalStatus' }).then(res => {
regStatusArr.value = res.data; regStatusArr.value = res.data;
}); });
} }
@ -836,18 +871,18 @@ const vMove = {
mounted(el: any) { mounted(el: any) {
el.onmousedown = function (e: any) { el.onmousedown = function (e: any) {
var init = e.clientX; var init = e.clientX;
var parent: any = document.getElementById("silderLeft"); var parent: any = document.getElementById('silderLeft');
const initWidth: any = parent.offsetWidth; const initWidth: any = parent.offsetWidth;
document.onmousemove = function (e) { document.onmousemove = function (e) {
var end = e.clientX; var end = e.clientX;
var newWidth = end - init + initWidth; var newWidth = end - init + initWidth;
parent.style.width = newWidth + "px"; parent.style.width = newWidth + 'px';
}; };
document.onmouseup = function () { document.onmouseup = function () {
document.onmousemove = document.onmouseup = null; document.onmousemove = document.onmouseup = null;
}; };
}; };
}, }
}; };
// code // code
function getAllNodeCodes(nodes: any[]): number[] { function getAllNodeCodes(nodes: any[]): number[] {
@ -864,11 +899,11 @@ function getAllNodeCodes(nodes: any[]): number[] {
// //
function handleSelectAll() { function handleSelectAll() {
if (!fishTreeRef.value || !fishData.value || fishData.value.length === 0) { if (!fishTreeRef.value || !fishData.value || fishData.value.length === 0) {
ElMessage.warning("暂无数据可全选"); ElMessage.warning('暂无数据可全选');
return; return;
} }
const allCodes = getAllNodeCodes(fishData.value); const allCodes = getAllNodeCodes(fishData.value);
console.log("全选 - 所有节点codes:", allCodes); console.log('全选 - 所有节点codes:', allCodes);
fishTreeRef.value.setCheckedKeys(allCodes, true); fishTreeRef.value.setCheckedKeys(allCodes, true);
// 使 // 使
@ -882,16 +917,16 @@ function handleSelectAll() {
getFishTableData(filteredIds); getFishTableData(filteredIds);
tableids.value = filteredIds; tableids.value = filteredIds;
console.log("全选 - 表格数据已更新过滤后IDs:", filteredIds); console.log('全选 - 表格数据已更新过滤后IDs:', filteredIds);
}, 100); }, 100);
ElMessage.success("已全选所有节点"); ElMessage.success('已全选所有节点');
} }
// //
function handleInvertSelection() { function handleInvertSelection() {
if (!fishTreeRef.value || !fishData.value || fishData.value.length === 0) { if (!fishTreeRef.value || !fishData.value || fishData.value.length === 0) {
ElMessage.warning("暂无数据可操作"); ElMessage.warning('暂无数据可操作');
return; return;
} }
@ -900,19 +935,23 @@ function handleInvertSelection() {
// keys // keys
const halfCheckedKeys = fishTreeRef.value.getHalfCheckedKeys(); const halfCheckedKeys = fishTreeRef.value.getHalfCheckedKeys();
console.log("反选前 - 已选中codes:", checkedKeys); console.log('反选前 - 已选中codes:', checkedKeys);
console.log("反选前 - 半选codes:", halfCheckedKeys); console.log('反选前 - 半选codes:', halfCheckedKeys);
// //
const currentSelectedKeys = [...new Set([...checkedKeys, ...halfCheckedKeys])]; const currentSelectedKeys = [
console.log("反选前 - 当前有效选中状态:", currentSelectedKeys); ...new Set([...checkedKeys, ...halfCheckedKeys])
];
console.log('反选前 - 当前有效选中状态:', currentSelectedKeys);
// codes // codes
const allCodes = getAllNodeCodes(fishData.value); const allCodes = getAllNodeCodes(fishData.value);
// - // -
const invertedCodes = allCodes.filter((code) => !currentSelectedKeys.includes(code)); const invertedCodes = allCodes.filter(
console.log("反选后 - 新的选中codes:", invertedCodes); code => !currentSelectedKeys.includes(code)
);
console.log('反选后 - 新的选中codes:', invertedCodes);
// //
fishTreeRef.value.setCheckedKeys([], false); fishTreeRef.value.setCheckedKeys([], false);
@ -932,11 +971,11 @@ function handleInvertSelection() {
getFishTableData(filteredIds); getFishTableData(filteredIds);
tableids.value = filteredIds; tableids.value = filteredIds;
console.log("反选 - 表格数据已更新过滤后IDs:", filteredIds); console.log('反选 - 表格数据已更新过滤后IDs:', filteredIds);
}, 100); }, 100);
}, 50); }, 50);
ElMessage.success("已反选操作"); ElMessage.success('已反选操作');
} }
// //
@ -944,17 +983,17 @@ function handleClearSelection() {
if (!fishTreeRef.value) { if (!fishTreeRef.value) {
return; return;
} }
console.log("取消选中 - 清空所有选中"); console.log('取消选中 - 清空所有选中');
fishTreeRef.value.setCheckedKeys([], true); fishTreeRef.value.setCheckedKeys([], true);
// //
setTimeout(() => { setTimeout(() => {
getFishTableData([]); getFishTableData([]);
tableids.value = []; tableids.value = [];
console.log("取消选中 - 表格数据已清空"); console.log('取消选中 - 表格数据已清空');
}, 100); }, 100);
ElMessage.success("已取消所有选中"); ElMessage.success('已取消所有选中');
} }
</script> </script>
@ -994,7 +1033,10 @@ function handleClearSelection() {
:value="item.itemCode" :value="item.itemCode"
/> />
</el-select> </el-select>
<el-button type="primary" style="margin-left: 10px" @click="getdata" <el-button
type="primary"
style="margin-left: 10px"
@click="getdata"
>搜索</el-button >搜索</el-button
> >
</div> </div>
@ -1022,7 +1064,7 @@ function handleClearSelection() {
:header-cell-style="{ :header-cell-style="{
background: 'rgb(250 250 250)', background: 'rgb(250 250 250)',
color: ' #383838', color: ' #383838',
height: '50px', height: '50px'
}" }"
> >
<!-- <el-table-column type="selection" width="50" align="center" /> --> <!-- <el-table-column type="selection" width="50" align="center" /> -->
@ -1040,8 +1082,8 @@ function handleClearSelection() {
> >
<span> <span>
{{ {{
scope.row.basinNames.split(",").slice(0, 6).join(",") + scope.row.basinNames.split(',').slice(0, 6).join(',') +
(scope.row.basinNames.split(",").length > 6 ? "..." : "") (scope.row.basinNames.split(',').length > 6 ? '...' : '')
}} }}
</span> </span>
</el-tooltip> </el-tooltip>
@ -1060,17 +1102,25 @@ function handleClearSelection() {
> >
<span> <span>
{{ {{
scope.row.stationNames.split(",").slice(0, 6).join(",") + scope.row.stationNames.split(',').slice(0, 6).join(',') +
(scope.row.stationNames.split(",").length > 6 ? "..." : "") (scope.row.stationNames.split(',').length > 6 ? '...' : '')
}} }}
</span> </span>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="nickname" label="用户姓名" width="140"></el-table-column> <el-table-column
prop="nickname"
label="用户姓名"
width="140"
></el-table-column>
<!-- <el-table-column prop="avatar" label="头像"></el-table-column> --> <!-- <el-table-column prop="avatar" label="头像"></el-table-column> -->
<!-- <el-table-column prop="email" label="邮箱"></el-table-column> --> <!-- <el-table-column prop="email" label="邮箱"></el-table-column> -->
<el-table-column prop="phone" label="手机号" width="160"></el-table-column> <el-table-column
prop="phone"
label="手机号"
width="160"
></el-table-column>
<el-table-column prop="username" label="登录账号"></el-table-column> <el-table-column prop="username" label="登录账号"></el-table-column>
<!-- <el-table-column prop="custom1" label="登录账号"></el-table-column> --> <!-- <el-table-column prop="custom1" label="登录账号"></el-table-column> -->
<!-- <el-table-column prop="rolename" label="所属角色" > <!-- <el-table-column prop="rolename" label="所属角色" >
@ -1079,7 +1129,12 @@ function handleClearSelection() {
</span> </span>
</template> </template>
</el-table-column> --> </el-table-column> -->
<el-table-column prop="regStatus" label="审核状态" width="90" align="center"> <el-table-column
prop="regStatus"
label="审核状态"
width="90"
align="center"
>
<template #default="scope"> <template #default="scope">
<el-tag :type="getRegStatusColor(scope.row.regStatus)" size="small"> <el-tag :type="getRegStatusColor(scope.row.regStatus)" size="small">
{{ getName(regStatusArr, scope.row.regStatus) }} {{ getName(regStatusArr, scope.row.regStatus) }}
@ -1166,7 +1221,12 @@ function handleClearSelection() {
width="620px" width="620px"
draggable draggable
> >
<el-form ref="infoForm" :model="info" :rules="moderules" label-width="90px"> <el-form
ref="infoForm"
:model="info"
:rules="moderules"
label-width="90px"
>
<el-form-item label="用户姓名" prop="nickname"> <el-form-item label="用户姓名" prop="nickname">
<el-input <el-input
v-model="info.nickname" v-model="info.nickname"
@ -1203,13 +1263,25 @@ function handleClearSelection() {
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item label="所属角色"> <el-form-item label="所属角色">
<el-select v-model="info.roleinfo" placeholder=" " style="width: 100%" multiple> <el-select
<el-option v-model="info.roleinfo"
v-for="item in rolesdata" placeholder=" "
:key="item.id" style="width: 100%"
:label="item.rolename" multiple
:value="item.id" filterable
/> >
<el-option-group
v-for="group in rolesdata"
:key="group.tenantName"
:label="group.tenantName"
>
<el-option
v-for="item in group.roles"
:key="item.id"
:label="item.rolename"
:value="item.id"
/>
</el-option-group>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -1223,7 +1295,9 @@ function handleClearSelection() {
" "
> >
<el-button @click="handleClose"> </el-button> <el-button @click="handleClose"> </el-button>
<el-button type="primary" @click="confirmClick(infoForm)">保存</el-button> <el-button type="primary" @click="confirmClick(infoForm)"
>保存</el-button
>
</span> </span>
</el-dialog> </el-dialog>
<!-- 过鱼设施权限维护 --> <!-- 过鱼设施权限维护 -->
@ -1256,9 +1330,15 @@ function handleClearSelection() {
</template> </template>
</el-input> </el-input>
<div class="button_div"> <div class="button_div">
<el-button type="primary" @click="handleSelectAll">全选</el-button> <el-button type="primary" @click="handleSelectAll"
<el-button type="primary" @click="handleInvertSelection">反选</el-button> >全选</el-button
<el-button type="primary" @click="handleClearSelection">取消选中</el-button> >
<el-button type="primary" @click="handleInvertSelection"
>反选</el-button
>
<el-button type="primary" @click="handleClearSelection"
>取消选中</el-button
>
</div> </div>
</div> </div>
@ -1298,13 +1378,23 @@ function handleClearSelection() {
:header-cell-style="{ :header-cell-style="{
background: 'rgb(250 250 250)', background: 'rgb(250 250 250)',
color: ' #383838', color: ' #383838',
height: '50px', height: '50px'
}" }"
> >
<el-table-column type="selection" width="50" align="center" /> <el-table-column type="selection" width="50" align="center" />
<el-table-column type="index" label="序号" width="70" align="center" /> <el-table-column
type="index"
label="序号"
width="70"
align="center"
/>
<el-table-column prop="name" label="名称"></el-table-column> <el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="type" label="类型" width="200" align="center"> <el-table-column
prop="type"
label="类型"
width="200"
align="center"
>
<template #default="scope"> <template #default="scope">
<span>{{ getName(dictData, scope.row.type) }}</span> <span>{{ getName(dictData, scope.row.type) }}</span>
</template> </template>
@ -1365,7 +1455,9 @@ function handleClearSelection() {
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="handleAuditClose">取消</el-button> <el-button @click="handleAuditClose">取消</el-button>
<el-button type="primary" @click="submitAudit(auditFormRef)">确定</el-button> <el-button type="primary" @click="submitAudit(auditFormRef)"
>确定</el-button
>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@ -1378,7 +1470,9 @@ function handleClearSelection() {
append-to-body append-to-body
:before-close="closeResult" :before-close="closeResult"
> >
已将密码重置为<span style="color: #409eff; font-size: 16px">{{ msgText }}</span> 已将密码重置为<span style="color: #409eff; font-size: 16px">{{
msgText
}}</span>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="closeResult">取消</el-button> <el-button @click="closeResult">取消</el-button>
@ -1526,4 +1620,7 @@ function handleClearSelection() {
.el-message-box { .el-message-box {
width: 300px !important; width: 300px !important;
} }
:deep(.el-select-group__title){
font-size: 16px !important;
}
</style> </style>

View File

@ -13,11 +13,12 @@ import {
addDept, addDept,
renewDept, renewDept,
deleDept, deleDept,
assignmentPer, permissionAssignmentGrouped,
setMenuById, setMenuById,
setOrgscope, setOrgscope,
postOrgscope postOrgscope
} from '@/api/role'; } from '@/api/role';
import { getDictItemsByCode } from '@/api/dict';
// //
const tableData: any = ref([]); const tableData: any = ref([]);
const multipleSelection = ref([]); const multipleSelection = ref([]);
@ -28,7 +29,8 @@ const tree = ref();
const loading = ref(false); const loading = ref(false);
function gettableData() { function gettableData() {
let params = { let params = {
rolename: input.value rolename: input.value,
tenantId:tenValue.value,
}; };
loading.value = true; loading.value = true;
listRolePages(params) listRolePages(params)
@ -115,7 +117,8 @@ function confirmClick(formEl: any) {
const params = { const params = {
rolename: info.value.rolename, rolename: info.value.rolename,
level: info.value.level, level: info.value.level,
description: info.value.description description: info.value.description,
tenantId:tenValue.value
}; };
addDept(params).then(() => { addDept(params).then(() => {
gettableData(); gettableData();
@ -126,7 +129,8 @@ function confirmClick(formEl: any) {
rolename: info.value.rolename, rolename: info.value.rolename,
level: info.value.level, level: info.value.level,
description: info.value.description, description: info.value.description,
id: info.value.id id: info.value.id,
tenantId:tenValue.value
}; };
renewDept(params).then(() => { renewDept(params).then(() => {
gettableData(); gettableData();
@ -274,12 +278,13 @@ function assignment(row: any) {
rowid.value = row.id; rowid.value = row.id;
accessVisible.value = true; accessVisible.value = true;
const params = { const params = {
roleId: rowid.value roleId: rowid.value,
tenantId:tenValue.value
}; };
assignmentPer(params).then((res: any) => { permissionAssignmentGrouped(params).then((res: any) => {
accessdata.value = res; accessdata.value = res[0]?.menus || [];
let ids: any = []; let ids: any = [];
menuChange(res, ids); menuChange(res[0]?.menus, ids);
nextTick(() => { nextTick(() => {
tree.value.setCheckedKeys(ids); tree.value.setCheckedKeys(ids);
}); });
@ -364,9 +369,13 @@ function dateFormat(row: any) {
); );
} }
} }
let tenValue = ref('1')
let tenOption = ref([])
onMounted(() => { onMounted(() => {
gettableData(); gettableData();
getDictItemsByCode({ dictCode: 'PLATFORM_TENANT' }).then(res => {
tenOption.value = res.data;
});
}); });
</script> </script>
@ -390,6 +399,15 @@ onMounted(() => {
style="width: 200px" style="width: 200px"
clearable clearable
/> />
<el-select v-model="tenValue" placeholder=" " style="width: 320px;margin-left: 10px">
<el-option
v-for="item in tenOption"
:key="item.itemCode"
:label="item.dictName"
:value="item.itemCode"
/>
<!-- PLATFORM_TENANT -->
</el-select>
<el-button <el-button
type="primary" type="primary"
style="margin-left: 10px" style="margin-left: 10px"

View File

@ -11,7 +11,7 @@ import {
gettableData, gettableData,
DataStatus, DataStatus,
deltableData, deltableData,
getRole, listGroupedByTenant,
addUsers, addUsers,
updataUser, updataUser,
setpass, setpass,
@ -786,7 +786,7 @@ function getrole() {
const params = { const params = {
rolename: '' rolename: ''
}; };
getRole(params).then(res => { listGroupedByTenant(params).then(res => {
rolesdata.value = res; rolesdata.value = res;
}); });
} }
@ -1250,19 +1250,27 @@ function handleClearSelection() {
placeholder="请输入登录账号" placeholder="请输入登录账号"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item label="所属角色"> <el-form-item label="所属角色">
<el-select <el-select
v-model="info.roleinfo" v-model="info.roleinfo"
placeholder=" " placeholder=" "
style="width: 100%" style="width: 100%"
multiple multiple
filterable
> >
<el-option <el-option-group
v-for="item in rolesdata" v-for="group in rolesdata"
:key="item.id" :key="group.tenantName"
:label="item.rolename" :label="group.tenantName"
:value="item.id" >
/> <el-option
v-for="item in group.roles"
:key="item.id"
:label="item.rolename"
:value="item.id"
/>
</el-option-group>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -1565,4 +1573,7 @@ function handleClearSelection() {
.el-message-box { .el-message-box {
width: 300px !important; width: 300px !important;
} }
:deep(.el-select-group__title){
font-size: 16px !important;
}
</style> </style>

View File

@ -51,6 +51,14 @@ export function assignmentPer (queryParams:any){
params: queryParams params: queryParams
}); });
} }
//获取分配权限(改动之后)
export function permissionAssignmentGrouped (queryParams:any){
return request({
url:'/system/menu/permissionAssignmentGrouped' ,
method: 'post',
params: queryParams
});
}
//发出分配权限 //发出分配权限
export function setMenuById (queryParams:any){ export function setMenuById (queryParams:any){
return request({ return request({

View File

@ -57,6 +57,14 @@ export function getRole (queryParams:any) {
params: queryParams params: queryParams
}); });
} }
//获取角色
export function listGroupedByTenant (queryParams:any) {
return request({
url: '/system/role/listGroupedByTenant',
method: 'POST',
data: queryParams
});
}
//新建用户 //新建用户
export function addUsers (queryParams:any,roleids:any) { export function addUsers (queryParams:any,roleids:any) {
return request({ return request({

View File

@ -96,7 +96,7 @@
</a-select> --> </a-select> -->
<!-- 流域下拉框 --> <!-- 流域下拉框 -->
<a-select <a-select
:value="formData.rvcd" :value="formData.reachcd"
placeholder="请选择" placeholder="请选择"
@change="lyChange" @change="lyChange"
show-search show-search
@ -330,7 +330,7 @@ const initForm = () => {
// //
// shuJuTianBaoStore.getBaseOption(); // shuJuTianBaoStore.getBaseOption();
shuJuTianBaoStore.getSelectForOption(); shuJuTianBaoStore.getSelectForOption();
shuJuTianBaoStore.getEngOption(formData.rvcd); shuJuTianBaoStore.getEngOption(formData.reachcd);
} }
if (item.fieldProps?.required) { if (item.fieldProps?.required) {
rules[item.name] = [ rules[item.name] = [
@ -363,23 +363,23 @@ const triggerManualValuesChange = (changedKey: string, newValue: any) => {
// }; // };
const lyChange = (value: any) => { const lyChange = (value: any) => {
formData.rvcd = value; formData.reachcd = value;
formData.rstcd = ""; formData.rstcd = "";
shuJuTianBaoStore.getEngOption(formData.rvcd); shuJuTianBaoStore.getEngOption(formData.reachcd);
// debugger
// valuesChange a-form-item-rest // valuesChange a-form-item-rest
triggerManualValuesChange("rvcd", formData.rvcd); triggerManualValuesChange("reachcd", formData.reachcd);
}; };
const stcdIdChange = (value: any) => { const stcdIdChange = (value: any) => {
if (props.zhujianfujian == "fu") { if (props.zhujianfujian == "fu") {
formData.rstcd = value; formData.rstcd = value;
shuJuTianBaoStore.getFpssOption(formData.rvcd, value); shuJuTianBaoStore.getFpssOption(formData.reachcd, value);
// valuesChange // valuesChange
triggerManualValuesChange("rstcd", formData.rstcd); triggerManualValuesChange("rstcd", formData.rstcd);
} else { } else {
formData.stcd = value; formData.stcd = value;
shuJuTianBaoStore.getFpssOption(formData.rvcd, value); shuJuTianBaoStore.getFpssOption(formData.reachcd, value);
// valuesChange // valuesChange
triggerManualValuesChange("stcd", formData.stcd); triggerManualValuesChange("stcd", formData.stcd);
} }

View File

@ -61,7 +61,7 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
const getEngOption = async (rvcd: string) => { const getEngOption = async (rvcd: string) => {
try { try {
engLoading.value = true; engLoading.value = true;
const param = rvcd === 'all' ? {} : { rvcd }; const param = rvcd === 'all' ? {} : { reachcd: rvcd };
const res = await getEngInfoDropdown(param); const res = await getEngInfoDropdown(param);
if (res.data && Array.isArray(res.data)) { if (res.data && Array.isArray(res.data)) {
// 直接赋值给 ref // 直接赋值给 ref
@ -78,7 +78,7 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
const getFpssOption = async (rvcd: string, rstcd: string) => { const getFpssOption = async (rvcd: string, rstcd: string) => {
try { try {
fpssLoading.value = true; fpssLoading.value = true;
const param = rvcd === 'all' ? {} : { rvcd }; const param = rvcd === 'all' ? {} : { reachcd:rvcd };
const res = await getFpssDropdown({...param, rstcd: rstcd}); const res = await getFpssDropdown({...param, rstcd: rstcd});
fpssOption.value = res.data; fpssOption.value = res.data;
} catch (error) { } catch (error) {

View File

@ -19,7 +19,18 @@ service.interceptors.request.use(
`Expected 'config' and 'config.headers' not to be undefined` `Expected 'config' and 'config.headers' not to be undefined`
); );
} }
config.headers.tenant_id = '4'; const menuPaths = [
'/system/menu/getMenuButtonTree',
'/system/menu/addMenu',
'/system/menu/updateById',
'/system/menu/deleteById',
'/system/menu/changeMenuOrder',
'/system/menu/uploadIcon',
'/system/menu/deleteIcon'
];
if (!menuPaths.some(p => config.url.includes(p))) {
config.headers.tenant_id = '4';
}
const user = useUserStoreHook(); const user = useUserStoreHook();
if (user.Token) { if (user.Token) {
config.headers.token = getToken(); config.headers.token = getToken();

View File

@ -47,7 +47,7 @@ const basicSearchRef = ref<any>();
const btnLoading = ref<boolean>(false); const btnLoading = ref<boolean>(false);
const initSearchData = { const initSearchData = {
rvcd: 'all', reachcd: 'all',
stcd: null, stcd: null,
reportMonth: dayjs().subtract(1, 'month').format('YYYY-MM') reportMonth: dayjs().subtract(1, 'month').format('YYYY-MM')
}; };
@ -57,7 +57,7 @@ const searchData = ref<any>({ ...initSearchData });
const searchList: any = computed(() => [ const searchList: any = computed(() => [
{ {
type: 'waterStation', type: 'waterStation',
name: 'rvcd', name: 'reachcd',
label: '流域', label: '流域',
fieldProps: { fieldProps: {
allowClear: true allowClear: true
@ -86,7 +86,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
searchData.value = { ...searchData.value, ...allValues }; searchData.value = { ...searchData.value, ...allValues };
if ( if (
Object.keys(changedValues)[0] == 'rstcd' || Object.keys(changedValues)[0] == 'rstcd' ||
Object.keys(changedValues)[0] == 'rvcd' Object.keys(changedValues)[0] == 'reachcd'
) { ) {
const formInstance = basicSearchRef.value?.formData; const formInstance = basicSearchRef.value?.formData;
formInstance.stcd = null; formInstance.stcd = null;

View File

@ -353,11 +353,11 @@ const handleDetailSearchFinish = (values: any) => {
dataType: 'date', dataType: 'date',
value: values.strdt[1] + ' 23:59:59' value: values.strdt[1] + ' 23:59:59'
}, },
values.rvcd !== 'all' && { values.reachcd !== 'all' && {
field: 'basinCode', field: 'basinCode',
operator: 'eq', operator: 'eq',
dataType: 'string', dataType: 'string',
value: values.rvcd value: values.reachcd
}, },
values.rstcd && { values.rstcd && {
field: 'stationCode', field: 'stationCode',

View File

@ -35,7 +35,7 @@ const localTypeDate = ref<string>(null);
const basicSearchRef = ref<any>(); const basicSearchRef = ref<any>();
const initSearchData = { const initSearchData = {
rvcd: "all", reachcd: "all",
stcd: null, stcd: null,
rstcd: null, rstcd: null,
ftp: null, ftp: null,
@ -52,7 +52,7 @@ const searchData = ref<any>({ ...initSearchData });
const searchList: any = computed(() => [ const searchList: any = computed(() => [
{ {
type: "waterStation", type: "waterStation",
name: "rvcd", name: "reachcd",
label: "流域", label: "流域",
fieldProps: { fieldProps: {
allowClear: true, allowClear: true,
@ -121,7 +121,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
if ( if (
Object.keys(changedValues)[0] == "rstcd" || Object.keys(changedValues)[0] == "rstcd" ||
Object.keys(changedValues)[0] == "baseId" || Object.keys(changedValues)[0] == "baseId" ||
Object.keys(changedValues)[0] == "rvcd" Object.keys(changedValues)[0] == "reachcd"
) { ) {
const formInstance = basicSearchRef.value?.formData; const formInstance = basicSearchRef.value?.formData;
formInstance.stcd = null; formInstance.stcd = null;

View File

@ -315,11 +315,11 @@ const handleSearchFinish = (values: any) => {
dataType: 'string', dataType: 'string',
value: values.rstcd value: values.rstcd
}, },
values.rvcd !== 'all' && { values.reachcd !== 'all' && {
field: 'rvcd', field: 'rvcd',
operator: 'eq', operator: 'eq',
dataType: 'string', dataType: 'string',
value: values.rvcd value: values.reachcd
} }
].filter(Boolean); ].filter(Boolean);

View File

@ -18,9 +18,9 @@
> >
<a-row :gutter="16"> <a-row :gutter="16">
<a-col :span="12"> <a-col :span="12">
<a-form-item label="流域" name="rvcd"> <a-form-item label="流域" name="reachcd">
<a-select <a-select
v-model:value="formData.rvcd" v-model:value="formData.reachcd"
:loading="hbrvcdLoading" :loading="hbrvcdLoading"
placeholder="请选择流域" placeholder="请选择流域"
:disabled="isView" :disabled="isView"
@ -67,7 +67,7 @@
v-model:value="formData.rstcd" v-model:value="formData.rstcd"
:loading="engLoading" :loading="engLoading"
placeholder="请选择电站名称" placeholder="请选择电站名称"
:disabled="isView || !formData.rvcd" :disabled="isView || !formData.reachcd"
show-search show-search
allowClear allowClear
:filter-option="filterOption" :filter-option="filterOption"
@ -395,16 +395,16 @@ const getHbrvcdDropdownSelect = async () => {
// await getEngInfoDropdownSelect(baseId); // await getEngInfoDropdownSelect(baseId);
// await getFpssDropdownSelect(formData.rstcd, baseId); // await getFpssDropdownSelect(formData.rstcd, baseId);
// }; // };
const hbrvcdChange = async (rvcd: string) => { const hbrvcdChange = async (reachcd: string) => {
formData.rstcd = undefined; formData.rstcd = undefined;
formData.stcd = undefined; formData.stcd = undefined;
await getEngInfoDropdownSelect(rvcd); await getEngInfoDropdownSelect(reachcd);
// await getFpssDropdownSelect(formData.rstcd, rvcd); // await getFpssDropdownSelect(formData.rstcd, rvcd);
}; };
const getEngInfoDropdownSelect = async (rvcd: string) => { const getEngInfoDropdownSelect = async (reachcd: string) => {
try { try {
engLoading.value = true; engLoading.value = true;
const res = await getEngInfoDropdown({ rvcd }); const res = await getEngInfoDropdown({ reachcd });
engOption.value = res.data; engOption.value = res.data;
} catch (error) { } catch (error) {
console.error('获取电站列表失败', error); console.error('获取电站列表失败', error);
@ -414,12 +414,12 @@ const getEngInfoDropdownSelect = async (rvcd: string) => {
}; };
const engChange = async (rstcd: string) => { const engChange = async (rstcd: string) => {
formData.stcd = undefined; formData.stcd = undefined;
await getFpssDropdownSelect(rstcd, formData.rvcd); await getFpssDropdownSelect(rstcd, formData.reachcd);
}; };
const getFpssDropdownSelect = async (rstcd: string, rvcd: string) => { const getFpssDropdownSelect = async (rstcd: string, reachcd: string) => {
try { try {
fpssLoading.value = true; fpssLoading.value = true;
const res = await getFpssDropdown({ rstcd, rvcd }); const res = await getFpssDropdown({ rstcd, reachcd });
fpssOption.value = res.data; fpssOption.value = res.data;
} catch (error) { } catch (error) {
console.error('获取流量列表失败', error); console.error('获取流量列表失败', error);
@ -454,7 +454,7 @@ const weightError = ref<string>('');
// //
const defaultFormData = reactive({ const defaultFormData = reactive({
id: undefined, id: undefined,
rvcd: undefined, reachcd: undefined,
stcd: undefined, stcd: undefined,
rstcd: undefined, rstcd: undefined,
strdt: undefined, strdt: undefined,
@ -479,7 +479,7 @@ const filterOption = (inputValue: string, option: any) => {
}; };
// //
const rules: Record<string, Rule[]> = { const rules: Record<string, Rule[]> = {
rvcd: [{ required: true, message: '请选择流域', trigger: 'change' }], reachcd: [{ required: true, message: '请选择流域', trigger: 'change' }],
rstcd: [{ required: true, message: '请选择电站', trigger: 'change' }], rstcd: [{ required: true, message: '请选择电站', trigger: 'change' }],
stcd: [{ required: true, message: '请选择过鱼设施', trigger: 'change' }], stcd: [{ required: true, message: '请选择过鱼设施', trigger: 'change' }],
strdt: [{ required: true, message: '请选择过鱼时间', trigger: 'change' }], strdt: [{ required: true, message: '请选择过鱼时间', trigger: 'change' }],
@ -858,8 +858,8 @@ watch(
// //
// getBaseDropdownSelect();// // getBaseDropdownSelect();//
getHbrvcdDropdownSelect(); // getHbrvcdDropdownSelect(); //
getEngInfoDropdownSelect(formData.rvcd); getEngInfoDropdownSelect(formData.reachcd);
getFpssDropdownSelect(formData.rstcd, formData.rvcd); getFpssDropdownSelect(formData.rstcd, formData.reachcd);
initForm(); initForm();
} }
}, },

View File

@ -133,7 +133,7 @@ const localTypeDate = ref<string>(null);
const basicSearchRef = ref<any>(); const basicSearchRef = ref<any>();
const initSearchData = { const initSearchData = {
rvcd: "all", reachcd: "all",
// baseId: "all", // baseId: "all",
stcd: null, stcd: null,
rstcd: null, rstcd: null,
@ -150,7 +150,7 @@ const searchData = ref<any>({ ...initSearchData });
const searchList: any = computed(() => [ const searchList: any = computed(() => [
{ {
type: "waterStation", type: "waterStation",
name: "rvcd", name: "reachcd",
label: "流域", label: "流域",
fieldProps: { fieldProps: {
allowClear: true allowClear: true
@ -222,7 +222,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
if ( if (
Object.keys(changedValues)[0] == "rstcd" || Object.keys(changedValues)[0] == "rstcd" ||
Object.keys(changedValues)[0] == "baseId" || Object.keys(changedValues)[0] == "baseId" ||
Object.keys(changedValues)[0] == "rvcd" Object.keys(changedValues)[0] == "reachcd"
) { ) {
const formInstance = basicSearchRef.value?.formData; const formInstance = basicSearchRef.value?.formData;
formInstance.stcd = null; formInstance.stcd = null;

View File

@ -885,12 +885,18 @@ const handleSearchFinish = (values: any) => {
dataType: 'string', dataType: 'string',
value: values.rstcd value: values.rstcd
}, },
values.rvcd !== 'all' && { values.reachcd !== 'all' && {
field: 'rvcd', field: 'rvcd',
operator: 'eq', operator: 'eq',
dataType: 'string', dataType: 'string',
value: values.rvcd value: values.reachcd
} },
// values.rvcd !== 'all' && {
// field: 'reachcd',
// operator: 'eq',
// dataType: 'string',
// value: values.reachcd
// }
// values.baseId !== "all" && { // values.baseId !== "all" && {
// field: "baseId", // field: "baseId",
// operator: "eq", // operator: "eq",

View File

@ -30,7 +30,7 @@ const localTypeDate = ref<string>(null);
const basicSearchRef = ref<any>(); const basicSearchRef = ref<any>();
const initSearchData = { const initSearchData = {
rvcd: 'all', reachcd: 'all',
stcd: null, stcd: null,
rstcd: null rstcd: null
// strdt: [ // strdt: [
@ -44,7 +44,7 @@ const searchData = ref<any>({ ...initSearchData });
const searchList: any = computed(() => [ const searchList: any = computed(() => [
{ {
type: 'waterStation', type: 'waterStation',
name: 'rvcd', name: 'reachcd',
label: '流域', label: '流域',
fieldProps: { fieldProps: {
allowClear: true allowClear: true
@ -74,7 +74,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
searchData.value = { ...searchData.value, ...allValues }; searchData.value = { ...searchData.value, ...allValues };
if ( if (
Object.keys(changedValues)[0] == 'rstcd' || Object.keys(changedValues)[0] == 'rstcd' ||
Object.keys(changedValues)[0] == 'rvcd' Object.keys(changedValues)[0] == 'reachcd'
) { ) {
const formInstance = basicSearchRef.value?.formData; const formInstance = basicSearchRef.value?.formData;
formInstance.stcd = null; formInstance.stcd = null;

View File

@ -361,11 +361,11 @@ const handleSearchFinish = (values: any) => {
dataType: 'string', dataType: 'string',
value: values.status value: values.status
}, },
values.rvcd !== 'all' && { values.reachcd !== 'all' && {
field: 'rvcd', field: 'rvcd',
operator: 'eq', operator: 'eq',
dataType: 'string', dataType: 'string',
value: values.rvcd value: values.reachcd
}, },
values.stcd && { values.stcd && {
field: 'stcd', field: 'stcd',
@ -605,11 +605,11 @@ const handleDetailSearchFinish = (values: any) => {
dataType: 'string', dataType: 'string',
value: values.rstcd value: values.rstcd
}, },
values.rvcd !== 'all' && { values.reachcd !== 'all' && {
field: 'rvcd', field: 'rvcd',
operator: 'eq', operator: 'eq',
dataType: 'string', dataType: 'string',
value: values.rvcd value: values.reachcd
}, },
approvalId.value && { approvalId.value && {
field: 'approvalId', // field: 'approvalId', //

View File

@ -61,7 +61,7 @@ const emit = defineEmits<{
// initSearchData // initSearchData
const initSearchData = { const initSearchData = {
rvcd: "all", reachcd: "all",
stcd: "", stcd: "",
status: "", status: "",
}; };
@ -71,7 +71,7 @@ const searchData = ref<any>({ ...initSearchData });
const searchList: any = computed(() => [ const searchList: any = computed(() => [
{ {
type: "waterStation", type: "waterStation",
name: "rvcd", name: "reachcd",
label: "流域", label: "流域",
fieldProps: { fieldProps: {
allowClear: true, allowClear: true,

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from "vue"; import { ref, onMounted } from 'vue';
import { ElForm, ElMessageBox, ElMessage } from "element-plus"; import { ElForm, ElMessageBox, ElMessage } from 'element-plus';
import { import {
getdata, getdata,
addmenu, addmenu,
@ -8,20 +8,20 @@ import {
deltmenu, deltmenu,
moveOrderno, moveOrderno,
uploadIcon, uploadIcon,
moveIcon, moveIcon
} from "@/api/menu"; } from '@/api/menu';
import Sortable from "sortablejs"; import Sortable from 'sortablejs';
// //
const url = import.meta.env.VITE_APP_BASE_API; const url = import.meta.env.VITE_APP_BASE_API;
const tableData: any = ref([]); const tableData: any = ref([]);
function gteTabledata() { function gteTabledata() {
const params = { const params = {
systemcode: systemcode.value, systemcode: systemcode.value,
name: "", name: ''
}; };
loading.value = true; loading.value = true;
getdata(params) getdata(params)
.then((res) => { .then(res => {
tableData.value = res; tableData.value = res;
loading.value = false; loading.value = false;
}) })
@ -34,56 +34,54 @@ const menuInfoRef = ref();
const btnInfoRef = ref(); const btnInfoRef = ref();
const loading = ref(false); const loading = ref(false);
//tabbar //tabbar
const systemcode = ref("4"); const systemcode = ref('1');
const activeIndex = ref("4"); const activeIndex = ref('1');
function handleSelect(key: string) { function handleSelect(key: string) {
if (key == "1") { if (key == '1') {
systemcode.value = "1"; systemcode.value = '1';
} else if (key == "2") { } else if (key == '2') {
systemcode.value = "2"; systemcode.value = '2';
} else if (key == "3") { } else if (key == '4') {
systemcode.value = "3"; systemcode.value = '4';
} else if (key == "4") {
systemcode.value = "4";
} }
gteTabledata(); gteTabledata();
} }
// //
const menuname = ref(""); const menuname = ref('');
// //
function search() { function search() {
menuname.value = menuname.value.replace(/\s+/g, ""); menuname.value = menuname.value.replace(/\s+/g, '');
let params = { let params = {
systemcode: systemcode.value, systemcode: systemcode.value,
name: menuname.value, name: menuname.value,
isdisplay: "", isdisplay: ''
}; };
getdata(params).then((res) => { getdata(params).then(res => {
tableData.value = res; tableData.value = res;
}); });
} }
// //
const title = ref(""); const title = ref('');
const expertInfo: any = ref({ const expertInfo: any = ref({
name: "", name: '',
type: "0", type: '0',
opturl: "", opturl: '',
permission: "", permission: '',
isdisplay: true, isdisplay: true,
systemcode: "", systemcode: '',
icon: "", icon: '',
code: "", code: ''
}); });
const dialogVisible = ref(false); const dialogVisible = ref(false);
function addClick() { function addClick() {
title.value = "新增目录"; title.value = '新增目录';
const orgnamemage = ref({ const orgnamemage = ref({
name: "", name: '',
type: "3", type: '3',
opturl: "", opturl: '',
permission: "", permission: '',
orderno: 1, orderno: 1,
isdisplay: "1", isdisplay: '1'
}); });
expertInfo.value = orgnamemage.value; expertInfo.value = orgnamemage.value;
dialogVisible.value = true; dialogVisible.value = true;
@ -99,35 +97,37 @@ function handleClose() {
} }
// //
const rules = ref({ const rules = ref({
name: [{ required: true, message: "请输入目录名称", trigger: "blur" }], name: [{ required: true, message: '请输入目录名称', trigger: 'blur' }],
opturl: [{ required: true, message: "请输入操作URL", trigger: "blur" }], opturl: [{ required: true, message: '请输入操作URL', trigger: 'blur' }],
permission: [{ required: true, message: "请输入目录权限标识", trigger: "blur" }], permission: [
{ required: true, message: '请输入目录权限标识', trigger: 'blur' }
]
}); });
// //
const parentID = ref(""); const parentID = ref('');
function addchilder(row: any) { function addchilder(row: any) {
title.value = "新增子目录"; title.value = '新增子目录';
const orgnamemage = ref({ const orgnamemage = ref({
name: "", name: '',
type: "3", type: '3',
opturl: "", opturl: '',
permission: "", permission: '',
orderno: 1, orderno: 1,
isdisplay: "1", isdisplay: '1'
}); });
parentID.value = row.id; parentID.value = row.id;
expertInfo.value = orgnamemage.value; expertInfo.value = orgnamemage.value;
dialogVisible.value = true; dialogVisible.value = true;
iconall.value = ""; iconall.value = '';
getid.value = row.id; getid.value = row.id;
} }
//- //-
function expertsubmit() { function expertsubmit() {
if (expertInfo.value.name == "") { if (expertInfo.value.name == '') {
ElMessage({ ElMessage({
message: "请填写目录名称", message: '请填写目录名称',
type: "error", type: 'error'
}); });
return false; return false;
} }
@ -135,116 +135,120 @@ function expertsubmit() {
let params = { let params = {
name: expertInfo.value.name, name: expertInfo.value.name,
systemcode: systemcode.value, systemcode: systemcode.value,
type: "0", type: '0',
parentid: "0", parentid: '0',
id: expertInfo.value.id, id: expertInfo.value.id,
icon: iconall.value, icon: iconall.value,
opturl: expertInfo.value.opturl, opturl: expertInfo.value.opturl,
isdisplay: expertInfo.value.isdisplay, isdisplay: expertInfo.value.isdisplay
}; };
editmenu(params).then(() => { editmenu(params).then(() => {
gteTabledata(); gteTabledata();
dialogVisible.value = false; dialogVisible.value = false;
ElMessage({ ElMessage({
message: "修改成功", message: '修改成功',
type: "success", type: 'success'
}); });
}); });
} else if (title.value == "新增子目录") { } else if (title.value == '新增子目录') {
let params = { let params = {
name: expertInfo.value.name, name: expertInfo.value.name,
systemcode: systemcode.value, systemcode: systemcode.value,
type: "0", type: '0',
opturl: expertInfo.value.opturl, opturl: expertInfo.value.opturl,
isdisplay: expertInfo.value.isdisplay, isdisplay: expertInfo.value.isdisplay,
parentid: parentID.value, parentid: parentID.value,
icon: iconall.value, icon: iconall.value
}; };
addmenu(params).then(() => { addmenu(params).then(() => {
gteTabledata(); gteTabledata();
dialogVisible.value = false; dialogVisible.value = false;
ElMessage({ ElMessage({
message: "新建成功", message: '新建成功',
type: "success", type: 'success'
}); });
}); });
} else { } else {
let params = { let params = {
name: expertInfo.value.name, name: expertInfo.value.name,
systemcode: systemcode.value, systemcode: systemcode.value,
type: "0", type: '0',
opturl: expertInfo.value.opturl, opturl: expertInfo.value.opturl,
isdisplay: expertInfo.value.isdisplay, isdisplay: expertInfo.value.isdisplay,
parentid: "0", parentid: '0',
id: expertInfo.value.id, id: expertInfo.value.id,
icon: iconall.value, icon: iconall.value
}; };
addmenu(params).then(() => { addmenu(params).then(() => {
gteTabledata(); gteTabledata();
dialogVisible.value = false; dialogVisible.value = false;
ElMessage({ ElMessage({
message: "新建成功", message: '新建成功',
type: "success", type: 'success'
}); });
}); });
} }
} }
// //
const menurules = ref({ const menurules = ref({
name: [{ required: true, message: "请输入菜单名称", trigger: "blur" }], name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
opturl: [{ required: true, message: "请输入操作URL", trigger: "blur" }], opturl: [{ required: true, message: '请输入操作URL', trigger: 'blur' }],
permission: [{ required: true, message: "请输入菜单权限标识", trigger: "blur" }], permission: [
{ required: true, message: '请输入菜单权限标识', trigger: 'blur' }
]
}); });
const menuVisible = ref(false); const menuVisible = ref(false);
const menutitle = ref(""); const menutitle = ref('');
// //
const btnInfo: any = ref({ const btnInfo: any = ref({
name: " ", name: ' ',
orderno: " ", orderno: ' ',
islink: " ", islink: ' ',
opturl: " ", opturl: ' ',
permission: " ", permission: ' ',
isdisplay: " ", isdisplay: ' ',
icon: "", icon: ''
}); });
const btnVisible = ref(false); const btnVisible = ref(false);
const btnrules = ref({ const btnrules = ref({
name: [{ required: true, message: "请输入按钮名称", trigger: "blur" }], name: [{ required: true, message: '请输入按钮名称', trigger: 'blur' }],
permission: [{ required: true, message: "请输入按钮权限标识", trigger: "blur" }], permission: [
{ required: true, message: '请输入按钮权限标识', trigger: 'blur' }
]
}); });
// //
const menuInfo: any = ref({ const menuInfo: any = ref({
name: "", name: '',
orderno: "", orderno: '',
islink: "", islink: '',
opturl: "", opturl: '',
permission: "", permission: '',
isdisplay: "", isdisplay: '',
icon: "", icon: ''
}); });
// //
const btntitle = ref(""); const btntitle = ref('');
const getid = ref(""); const getid = ref('');
const allId = ref(""); const allId = ref('');
function handleEdit(row: any) { function handleEdit(row: any) {
iconall.value = row.icon; iconall.value = row.icon;
const Row = JSON.parse(JSON.stringify(row)); const Row = JSON.parse(JSON.stringify(row));
getid.value = row.id; getid.value = row.id;
btnparentid.value = row.parentid; btnparentid.value = row.parentid;
if (row.type == "2") { if (row.type == '2') {
btntitle.value = "修改按钮"; btntitle.value = '修改按钮';
let newInfo = ref({}); let newInfo = ref({});
newInfo.value = Row; newInfo.value = Row;
btnInfo.value = newInfo.value; btnInfo.value = newInfo.value;
btnVisible.value = true; btnVisible.value = true;
} else if (row.type == "1") { } else if (row.type == '1') {
menutitle.value = "修改菜单"; menutitle.value = '修改菜单';
let newInfo = ref({}); let newInfo = ref({});
newInfo.value = Row; newInfo.value = Row;
menuInfo.value = newInfo.value; menuInfo.value = newInfo.value;
menuVisible.value = true; menuVisible.value = true;
} else { } else {
title.value = "修改目录"; title.value = '修改目录';
let newInfo = ref({}); let newInfo = ref({});
newInfo.value = Row; newInfo.value = Row;
expertInfo.value = newInfo.value; expertInfo.value = newInfo.value;
@ -252,39 +256,39 @@ function handleEdit(row: any) {
} }
} }
// //
const btnparentid = ref(""); const btnparentid = ref('');
function menuclick(row: any) { function menuclick(row: any) {
if (row.id == undefined) { if (row.id == undefined) {
btnparentid.value = "0"; btnparentid.value = '0';
} else { } else {
btnparentid.value = row.id; btnparentid.value = row.id;
} }
menutitle.value = "添加菜单"; menutitle.value = '添加菜单';
(menuInfo.value = { (menuInfo.value = {
name: "", name: '',
type: "1", type: '1',
islink: "0", islink: '0',
opturl: "", opturl: '',
permission: "", permission: '',
orderno: 1, orderno: 1,
isdisplay: "1", isdisplay: '1'
}), }),
(menuVisible.value = true); (menuVisible.value = true);
iconall.value = ""; iconall.value = '';
getid.value = row.id; getid.value = row.id;
} }
// //
function btnclick(row: any) { function btnclick(row: any) {
getid.value = row.id; getid.value = row.id;
btntitle.value = "添加按钮"; btntitle.value = '添加按钮';
(btnInfo.value = { (btnInfo.value = {
name: "", name: '',
type: "2", type: '2',
islink: "0", islink: '0',
opturl: "", opturl: '',
permission: "", permission: '',
orderno: 1, orderno: 1,
isdisplay: "1", isdisplay: '1'
}), }),
(btnVisible.value = true); (btnVisible.value = true);
btnparentid.value = row.id; btnparentid.value = row.id;
@ -292,36 +296,36 @@ function btnclick(row: any) {
// //
function handleDelete(row: any) { function handleDelete(row: any) {
const message = ref(); const message = ref();
if (row.type == "0") { if (row.type == '0') {
message.value = "确定删除此目录及此目录下的所有菜单吗?"; message.value = '确定删除此目录及此目录下的所有菜单吗?';
} else if (row.type == "1") { } else if (row.type == '1') {
message.value = "确定删除此菜单及此菜单下的所有按钮吗?"; message.value = '确定删除此菜单及此菜单下的所有按钮吗?';
} else if (row.type == "2") { } else if (row.type == '2') {
message.value = "确定删除此按钮吗?"; message.value = '确定删除此按钮吗?';
} }
ElMessageBox.confirm(message.value, "删除提示", { ElMessageBox.confirm(message.value, '删除提示', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning'
}).then(() => { }).then(() => {
const params = { const params = {
id: row.id, id: row.id
}; };
deltmenu(params).then(() => { deltmenu(params).then(() => {
gteTabledata(); gteTabledata();
ElMessage({ ElMessage({
message: "删除成功", message: '删除成功',
type: "success", type: 'success'
}); });
}); });
}); });
} }
//- //-
function menusubmit() { function menusubmit() {
if (menuInfo.value.name == "") { if (menuInfo.value.name == '') {
ElMessage({ ElMessage({
message: "请填写菜单名称", message: '请填写菜单名称',
type: "error", type: 'error'
}); });
return false; return false;
} }
@ -329,41 +333,41 @@ function menusubmit() {
let params = { let params = {
name: menuInfo.value.name, name: menuInfo.value.name,
systemcode: systemcode.value, systemcode: systemcode.value,
type: "1", type: '1',
opturl: menuInfo.value.opturl, opturl: menuInfo.value.opturl,
permission: menuInfo.value.permission, permission: menuInfo.value.permission,
islink: menuInfo.value.islink, islink: menuInfo.value.islink,
isdisplay: menuInfo.value.isdisplay, isdisplay: menuInfo.value.isdisplay,
// parentid: '', // parentid: '',
id: getid.value, id: getid.value,
icon: iconall.value, icon: iconall.value
}; };
editmenu(params).then(() => { editmenu(params).then(() => {
gteTabledata(); gteTabledata();
menuVisible.value = false; menuVisible.value = false;
ElMessage({ ElMessage({
message: "修改成功", message: '修改成功',
type: "success", type: 'success'
}); });
}); });
} else { } else {
let params = { let params = {
name: menuInfo.value.name, name: menuInfo.value.name,
systemcode: systemcode.value, systemcode: systemcode.value,
type: "1", type: '1',
opturl: menuInfo.value.opturl, opturl: menuInfo.value.opturl,
islink: menuInfo.value.islink, islink: menuInfo.value.islink,
isdisplay: menuInfo.value.isdisplay, isdisplay: menuInfo.value.isdisplay,
parentid: btnparentid.value, parentid: btnparentid.value,
id: expertInfo.value.id, id: expertInfo.value.id,
icon: iconall.value, icon: iconall.value
}; };
addmenu(params).then(() => { addmenu(params).then(() => {
gteTabledata(); gteTabledata();
menuVisible.value = false; menuVisible.value = false;
ElMessage({ ElMessage({
message: "新建成功", message: '新建成功',
type: "success", type: 'success'
}); });
}); });
} }
@ -371,10 +375,10 @@ function menusubmit() {
//- //-
function btnsubmit() { function btnsubmit() {
if (btnInfo.value.name == "" || btnInfo.value.permission == "") { if (btnInfo.value.name == '' || btnInfo.value.permission == '') {
ElMessage({ ElMessage({
message: "请填写按钮名称和权限标识", message: '请填写按钮名称和权限标识',
type: "error", type: 'error'
}); });
return false; return false;
} }
@ -383,19 +387,19 @@ function btnsubmit() {
code: btnInfo.value.code, code: btnInfo.value.code,
name: btnInfo.value.name, name: btnInfo.value.name,
systemcode: systemcode.value, systemcode: systemcode.value,
type: "2", type: '2',
opturl: btnInfo.value.opturl, opturl: btnInfo.value.opturl,
permission: btnInfo.value.permission, permission: btnInfo.value.permission,
islink: btnInfo.value.islink, islink: btnInfo.value.islink,
// isdisplay: btnInfo.value.isdisplay, // isdisplay: btnInfo.value.isdisplay,
id: getid.value, id: getid.value
}; };
editmenu(params).then(() => { editmenu(params).then(() => {
gteTabledata(); gteTabledata();
dialogVisible.value = false; dialogVisible.value = false;
ElMessage({ ElMessage({
message: "修改成功", message: '修改成功',
type: "success", type: 'success'
}); });
btnVisible.value = false; btnVisible.value = false;
}); });
@ -403,19 +407,19 @@ function btnsubmit() {
let params = { let params = {
name: btnInfo.value.name, name: btnInfo.value.name,
systemcode: systemcode.value, systemcode: systemcode.value,
type: "2", type: '2',
opturl: btnInfo.value.opturl, opturl: btnInfo.value.opturl,
permission: btnInfo.value.permission, permission: btnInfo.value.permission,
islink: btnInfo.value.islink, islink: btnInfo.value.islink,
isdisplay: btnInfo.value.isdisplay, isdisplay: btnInfo.value.isdisplay,
parentid: btnparentid.value, parentid: btnparentid.value
}; };
addmenu(params).then(() => { addmenu(params).then(() => {
gteTabledata(); gteTabledata();
dialogVisible.value = false; dialogVisible.value = false;
ElMessage({ ElMessage({
message: "新建成功", message: '新建成功',
type: "success", type: 'success'
}); });
btnVisible.value = false; btnVisible.value = false;
}); });
@ -427,70 +431,88 @@ function dateFormat(row: any) {
var date = new Date(daterc); var date = new Date(daterc);
var year = date.getFullYear(); var year = date.getFullYear();
var month = var month =
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; date.getMonth() + 1 < 10
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; ? '0' + (date.getMonth() + 1)
var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); : date.getMonth() + 1;
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours(); date.getMonth() + 1 < 10
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes(); ? '0' + (date.getMonth() + 1)
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds(); : date.getMonth() + 1;
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
var minutes =
date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
var seconds =
date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
// //
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; return (
year +
'-' +
month +
'-' +
day +
' ' +
hours +
':' +
minutes +
':' +
seconds
);
} }
} }
// //
function fileClick(val: any) { function fileClick(val: any) {
allId.value = val; allId.value = val;
const avatar = document.getElementById("avatar"); const avatar = document.getElementById('avatar');
avatar?.click(); avatar?.click();
} }
const iconall = ref(""); const iconall = ref('');
function changeFile(e: any) { function changeFile(e: any) {
const files = new FormData(); const files = new FormData();
files.append("icon", e.target.files[0]); files.append('icon', e.target.files[0]);
files.append("menuId", allId.value); files.append('menuId', allId.value);
uploadIcon(files) uploadIcon(files)
.then((res) => { .then(res => {
iconall.value = res.data; iconall.value = res.data;
gteTabledata(); gteTabledata();
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "上传成功", message: '上传成功'
}); });
// location.reload() // location.reload()
var file: any = document.getElementById("avatar"); var file: any = document.getElementById('avatar');
file.value = ""; file.value = '';
}) })
.catch(() => { .catch(() => {
ElMessage({ ElMessage({
type: "error", type: 'error',
message: "上传失败", message: '上传失败'
}); });
var file: any = document.getElementById("avatar"); var file: any = document.getElementById('avatar');
file.value = ""; file.value = '';
}); });
} }
// //
function delectIcon(id: any) { function delectIcon(id: any) {
ElMessageBox.confirm("确定删除此图标吗?", "删除提示", { ElMessageBox.confirm('确定删除此图标吗?', '删除提示', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning'
}).then(() => { }).then(() => {
const params = { const params = {
id: id, id: id
}; };
moveIcon(params).then(() => { moveIcon(params).then(() => {
iconall.value = ""; iconall.value = '';
gteTabledata(); gteTabledata();
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "删除成功", message: '删除成功'
}); });
}); });
}); });
} }
// Icon // Icon
function treeToTile(treeData: any, childKey = "children") { function treeToTile(treeData: any, childKey = 'children') {
const arr = [] as any[]; const arr = [] as any[];
const expanded = (data: any) => { const expanded = (data: any) => {
if (data && data.length > 0) { if (data && data.length > 0) {
@ -507,9 +529,11 @@ function treeToTile(treeData: any, childKey = "children") {
} }
const activeRows: any = ref([]); const activeRows: any = ref([]);
function rowDrop() { function rowDrop() {
const tbody = document.querySelector(".draggable .el-table__body-wrapper tbody"); const tbody = document.querySelector(
'.draggable .el-table__body-wrapper tbody'
);
Sortable.create(tbody, { Sortable.create(tbody, {
draggable: ".draggable .el-table__row", draggable: '.draggable .el-table__row',
onMove: () => { onMove: () => {
activeRows.value = treeToTile(tableData.value); // activeRows.value = treeToTile(tableData.value); //
}, },
@ -519,8 +543,8 @@ function rowDrop() {
if (oldRow.type != newRow.type) { if (oldRow.type != newRow.type) {
ElMessage({ ElMessage({
message: "拖拽同级目录排序", message: '拖拽同级目录排序',
type: "warning", type: 'warning'
}); });
tableData.value = []; tableData.value = [];
gteTabledata(); gteTabledata();
@ -528,22 +552,22 @@ function rowDrop() {
} }
const params = { const params = {
fromId: oldRow.id, fromId: oldRow.id,
toId: newRow.id, toId: newRow.id
}; };
moveOrderno(params).then((res: any) => { moveOrderno(params).then((res: any) => {
if (res.code == 1) { if (res.code == 1) {
tableData.value = []; tableData.value = [];
gteTabledata(); gteTabledata();
ElMessage({ ElMessage({
type: "error", type: 'error',
message: "修改失败", message: '修改失败'
}); });
} else { } else {
tableData.value = []; tableData.value = [];
gteTabledata(); gteTabledata();
} }
}); });
}, }
}); });
} }
onMounted(() => { onMounted(() => {
@ -561,10 +585,9 @@ onMounted(() => {
mode="horizontal" mode="horizontal"
@select="handleSelect" @select="handleSelect"
> >
<!-- <el-menu-item index="1">Web端</el-menu-item> <el-menu-item index="1">水电水利建设项目全过程环境管理信息平台</el-menu-item>
<el-menu-item index="2">手机App</el-menu-item> <el-menu-item index="2">全过程数据管理子系统</el-menu-item>
<el-menu-item index="3">Pad端</el-menu-item> --> <el-menu-item index="4">填报管理子系统</el-menu-item>
<el-menu-item index="4">数据填报</el-menu-item>
</el-menu> </el-menu>
<div <div
style=" style="
@ -615,10 +638,15 @@ onMounted(() => {
:header-cell-style="{ :header-cell-style="{
background: 'rgb(250 250 250)', background: 'rgb(250 250 250)',
color: '#383838', color: '#383838',
height: '50px', height: '50px'
}" }"
> >
<el-table-column label="菜单标题" width="250" prop="name" show-overflow-tooltip> <el-table-column
label="菜单标题"
width="250"
prop="name"
show-overflow-tooltip
>
<template #default="scope"> <template #default="scope">
<div style="position: absolute; left: 15px"> <div style="position: absolute; left: 15px">
<img src="@/assets/MenuIcon/lbcz_td.png" alt="" /> <img src="@/assets/MenuIcon/lbcz_td.png" alt="" />
@ -626,7 +654,12 @@ onMounted(() => {
<div style="margin-left: 20px">{{ scope.row.name }}</div> <div style="margin-left: 20px">{{ scope.row.name }}</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="菜单类型" width="100" align="center" prop="type"> <el-table-column
label="菜单类型"
width="100"
align="center"
prop="type"
>
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.type == '2'">按钮</span> <span v-if="scope.row.type == '2'">按钮</span>
<span v-else-if="scope.row.type == '1'">菜单</span> <span v-else-if="scope.row.type == '1'">菜单</span>
@ -639,12 +672,16 @@ onMounted(() => {
width="100" width="100"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column label="系统类型" width="120" prop="systemcode" align="center"> <el-table-column
label="系统类型"
width="170"
prop="systemcode"
align="center"
>
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.systemcode == '1'">Web端</span> <span v-if="scope.row.systemcode == '1'">水电水利建设项目全过程环境管理信息平台</span>
<span v-else-if="scope.row.systemcode == '2'">手机App</span> <span v-else-if="scope.row.systemcode == '2'">全过程数据管理子系统</span>
<span v-else-if="scope.row.systemcode == '3'">Pad端</span> <span v-else>填报管理子系统</span>
<span v-else-if="scope.row.systemcode == '4'">数据填报</span>
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="图标" width="100" prop="icon" align="center"> <!-- <el-table-column label="图标" width="100" prop="icon" align="center">
@ -706,15 +743,21 @@ onMounted(() => {
@change="changeFile" @change="changeFile"
/> />
</div> </div>
<img :src="url + '/menu/' + scope.row.icon" alt="">
</div> </div>
</template> </template>
</el-table-column> --> </el-table-column> -->
<!-- <el-table-column label="是否外链" width="100" prop="islink" align="center"> <el-table-column
label="是否外链"
width="100"
prop="islink"
align="center"
>
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.islink == '1'"></span> <span v-if="scope.row.islink == '1'"></span>
<span v-else></span> <span v-else></span>
</template> </template>
</el-table-column> --> </el-table-column>
<el-table-column <el-table-column
label="操作URL" label="操作URL"
min-width="100" min-width="100"
@ -732,7 +775,12 @@ onMounted(() => {
prop="permission" prop="permission"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column label="是否显示" width="100" prop="isdisplay" align="center"> <el-table-column
label="是否显示"
width="100"
prop="isdisplay"
align="center"
>
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.isdisplay == '1'"></span> <span v-if="scope.row.isdisplay == '1'"></span>
<span v-else></span> <span v-else></span>
@ -743,7 +791,11 @@ onMounted(() => {
label="最近修改者" label="最近修改者"
width="120" width="120"
></el-table-column> ></el-table-column>
<el-table-column prop="lastmodifydate" label="最近修改日期" width="170"> <el-table-column
prop="lastmodifydate"
label="最近修改日期"
width="170"
>
<template #default="scope"> <template #default="scope">
{{ dateFormat(scope.row.lastmodifydate) }} {{ dateFormat(scope.row.lastmodifydate) }}
</template> </template>
@ -866,7 +918,12 @@ onMounted(() => {
width="620px" width="620px"
class="dialogClass" class="dialogClass"
> >
<el-form ref="expertInfoRef" :model="expertInfo" :rules="rules" label-width="90px"> <el-form
ref="expertInfoRef"
:model="expertInfo"
:rules="rules"
label-width="90px"
>
<el-form-item label="目录编号" prop="name"> <el-form-item label="目录编号" prop="name">
<el-input <el-input
v-model="expertInfo.code" v-model="expertInfo.code"
@ -913,7 +970,12 @@ onMounted(() => {
width="620px" width="620px"
class="dialogClass" class="dialogClass"
> >
<el-form ref="menuInfoRef" :model="menuInfo" :rules="menurules" label-width="90px"> <el-form
ref="menuInfoRef"
:model="menuInfo"
:rules="menurules"
label-width="90px"
>
<el-form-item label="菜单编号"> <el-form-item label="菜单编号">
<el-input <el-input
v-model="menuInfo.code" v-model="menuInfo.code"
@ -923,15 +985,19 @@ onMounted(() => {
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item label="菜单名称" prop="name"> <el-form-item label="菜单名称" prop="name">
<el-input v-model="menuInfo.name" placeholder="" style="width: 100%"></el-input> <el-input
v-model="menuInfo.name"
placeholder=""
style="width: 100%"
></el-input>
</el-form-item> </el-form-item>
<!-- <el-form-item label="是否外链" prop="islink"> <el-form-item label="是否外链" prop="islink">
<el-radio-group v-model="menuInfo.islink"> <el-radio-group v-model="menuInfo.islink">
<el-radio label="1"></el-radio> <el-radio label="1"></el-radio>
<el-radio label="0"></el-radio> <el-radio label="0"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> --> </el-form-item>
<el-form-item label="操作URL" prop="opturl"> <el-form-item label="操作URL" prop="opturl">
<el-input <el-input
v-model="menuInfo.opturl" v-model="menuInfo.opturl"
@ -970,7 +1036,12 @@ onMounted(() => {
class="dialogClass" class="dialogClass"
draggable draggable
> >
<el-form ref="btnInfoRef" :model="btnInfo" :rules="btnrules" label-width="90px"> <el-form
ref="btnInfoRef"
:model="btnInfo"
:rules="btnrules"
label-width="90px"
>
<el-form-item label="按钮编号"> <el-form-item label="按钮编号">
<el-input <el-input
v-model="btnInfo.code" v-model="btnInfo.code"
@ -980,7 +1051,11 @@ onMounted(() => {
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item label="按钮名称" prop="name"> <el-form-item label="按钮名称" prop="name">
<el-input v-model="btnInfo.name" placeholder="" style="width: 100%"></el-input> <el-input
v-model="btnInfo.name"
placeholder=""
style="width: 100%"
></el-input>
</el-form-item> </el-form-item>
<el-form-item label="权限标识" prop="permission"> <el-form-item label="权限标识" prop="permission">
<el-input <el-input

View File

@ -1,14 +1,14 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: "record", name: 'record'
}; };
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from "vue"; import { onMounted, ref } from 'vue';
import { getLogList, exportExcel } from "@/api/record"; import { getLogList, exportExcel } from '@/api/record';
import { downloadFile } from "@/utils/index"; import { downloadFile } from '@/utils/index';
import Page from "@/components/Pagination/page.vue"; import Page from '@/components/Pagination/page.vue';
// import { VueDevToolsTimelineColors } from "@intlify/vue-devtools"; // import { VueDevToolsTimelineColors } from "@intlify/vue-devtools";
// //
@ -18,7 +18,7 @@ const tableData: any = ref([]);
const queryParams = ref({ const queryParams = ref({
current: 1, current: 1,
size: 20, size: 20,
opttype: "", opttype: ''
}); });
// //
const operationTime: any = ref(); const operationTime: any = ref();
@ -26,12 +26,12 @@ const operationTime: any = ref();
const total = ref(0); const total = ref(0);
// //
const type: any = ref([ const type: any = ref([
{ name: "登录(login)", value: "00" }, { name: '登录(login)', value: '00' },
{ name: "添加(insert)", value: "01" }, { name: '添加(insert)', value: '01' },
{ name: "修改(update)", value: "02" }, { name: '修改(update)', value: '02' },
{ name: "删除(delete)", value: "03" }, { name: '删除(delete)', value: '03' },
{ name: "查询(select)", value: "04" }, { name: '查询(select)', value: '04' },
{ name: "其他(other)", value: "05" }, { name: '其他(other)', value: '05' }
]); ]);
// //
const loading = ref(false); const loading = ref(false);
@ -43,8 +43,8 @@ function init() {
optType: queryParams.value.opttype, optType: queryParams.value.opttype,
current: queryParams.value.current, current: queryParams.value.current,
size: queryParams.value.size, size: queryParams.value.size,
startDate: "", startDate: '',
endDate: "", endDate: ''
}; };
if (operationTime.value != null) { if (operationTime.value != null) {
params.startDate = operationTime.value[0]; params.startDate = operationTime.value[0];
@ -71,14 +71,32 @@ function dateFormat(row: any) {
var date = new Date(daterc); var date = new Date(daterc);
var year = date.getFullYear(); var year = date.getFullYear();
var month = var month =
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; date.getMonth() + 1 < 10
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; ? '0' + (date.getMonth() + 1)
var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); : date.getMonth() + 1;
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours(); date.getMonth() + 1 < 10
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes(); ? '0' + (date.getMonth() + 1)
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds(); : date.getMonth() + 1;
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
var minutes =
date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
var seconds =
date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
// //
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; return (
year +
'-' +
month +
'-' +
day +
' ' +
hours +
':' +
minutes +
':' +
seconds
);
} }
} }
@ -88,15 +106,15 @@ function leadingOut() {
optType: queryParams.value.opttype, optType: queryParams.value.opttype,
current: queryParams.value.current, current: queryParams.value.current,
size: queryParams.value.size, size: queryParams.value.size,
startDate: "", startDate: '',
endDate: "", endDate: ''
}; };
if (operationTime.value != null) { if (operationTime.value != null) {
params.startDate = operationTime.value[0]; params.startDate = operationTime.value[0];
params.endDate = operationTime.value[1]; params.endDate = operationTime.value[1];
} }
exportExcel(params).then((response: any) => { exportExcel(params).then((response: any) => {
downloadFile(response, "日志", "xlsx"); downloadFile(response, '日志', 'xlsx');
}); });
} }
// //
@ -158,7 +176,9 @@ function handleClose() {
@change="init" @change="init"
/> />
</div> </div>
<el-button type="primary" style="margin-left: 10px" @click="init">搜索</el-button> <el-button type="primary" style="margin-left: 10px" @click="init"
>搜索</el-button
>
<div <div
style=" style="
width: 100%; width: 100%;
@ -190,17 +210,37 @@ function handleClose() {
width="70" width="70"
align="center" align="center"
></el-table-column> ></el-table-column>
<el-table-column prop="usercode" label="操作账户" width="100"></el-table-column> <el-table-column
<el-table-column prop="username" label="用户姓名" width="180"></el-table-column> prop="usercode"
<el-table-column prop="requestip" label="IP地址" width="140"></el-table-column> label="操作账户"
<el-table-column prop="browser" label="浏览器" width="130"></el-table-column> width="100"
></el-table-column>
<el-table-column
prop="username"
label="用户姓名"
width="180"
></el-table-column>
<el-table-column
prop="requestip"
label="IP地址"
width="140"
></el-table-column>
<el-table-column
prop="browser"
label="浏览器"
width="130"
></el-table-column>
<el-table-column <el-table-column
prop="opttype" prop="opttype"
label="日志类型" label="日志类型"
width="130" width="130"
align="center" align="center"
></el-table-column> ></el-table-column>
<el-table-column prop="module" label="模块名称" width="170"></el-table-column> <el-table-column
prop="module"
label="模块名称"
width="170"
></el-table-column>
<el-table-column prop="description" label="日志描述" min-width="100"> <el-table-column prop="description" label="日志描述" min-width="100">
<template #default="scope"> <template #default="scope">
<div <div
@ -248,6 +288,7 @@ function handleClose() {
top="30px" top="30px"
draggable draggable
:destroy-on-close="false" :destroy-on-close="false"
style="pointer-events: all"
> >
<el-table <el-table
v-loading="loading" v-loading="loading"
@ -262,8 +303,16 @@ function handleClose() {
width="70" width="70"
align="center" align="center"
></el-table-column> ></el-table-column>
<el-table-column prop="username" label="用户姓名" width="110"></el-table-column> <el-table-column
<el-table-column prop="module" label="模块名称" width="120"></el-table-column> prop="username"
label="用户姓名"
width="110"
></el-table-column>
<el-table-column
prop="module"
label="模块名称"
width="120"
></el-table-column>
<el-table-column <el-table-column
prop="description" prop="description"
label="日志描述" label="日志描述"

View File

@ -9,7 +9,7 @@ import { ref, onMounted, nextTick, watch } from "vue";
import { import {
queryPendingAuditUsers, queryPendingAuditUsers,
deltableData, deltableData,
getRole, listGroupedByTenant,
addUsers, addUsers,
updataUser, updataUser,
setpass, setpass,
@ -660,7 +660,7 @@ function getrole() {
const params = { const params = {
rolename: "", rolename: "",
}; };
getRole(params).then((res) => { listGroupedByTenant(params).then((res) => {
rolesdata.value = res; rolesdata.value = res;
}); });
} }
@ -1202,14 +1202,26 @@ function handleClearSelection() {
placeholder="请输入登录账号" placeholder="请输入登录账号"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item label="所属角色"> <el-form-item label="所属角色">
<el-select v-model="info.roleinfo" placeholder=" " style="width: 100%" multiple> <el-select
<el-option v-model="info.roleinfo"
v-for="item in rolesdata" placeholder=" "
:key="item.id" style="width: 100%"
:label="item.rolename" multiple
:value="item.id" filterable
/> >
<el-option-group
v-for="group in rolesdata"
:key="group.tenantName"
:label="group.tenantName"
>
<el-option
v-for="item in group.roles"
:key="item.id"
:label="item.rolename"
:value="item.id"
/>
</el-option-group>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -1526,4 +1538,7 @@ function handleClearSelection() {
.el-message-box { .el-message-box {
width: 300px !important; width: 300px !important;
} }
:deep(.el-select-group__title){
font-size: 16px !important;
}
</style> </style>

View File

@ -1,23 +1,24 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: "role", name: 'role'
}; };
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref, nextTick } from "vue"; import { onMounted, ref, nextTick } from 'vue';
import { ElForm, ElMessage, ElMessageBox } from "element-plus"; import { ElForm, ElMessage, ElMessageBox } from 'element-plus';
import { import {
listRolePages, listRolePages,
isvaildTo, isvaildTo,
addDept, addDept,
renewDept, renewDept,
deleDept, deleDept,
assignmentPer, permissionAssignmentGrouped,
setMenuById, setMenuById,
setOrgscope, setOrgscope,
postOrgscope, postOrgscope
} from "@/api/role"; } from '@/api/role';
import { getDictItemsByCode } from '@/api/dict';
// //
const tableData: any = ref([]); const tableData: any = ref([]);
const multipleSelection = ref([]); const multipleSelection = ref([]);
@ -29,10 +30,11 @@ const loading = ref(false);
function gettableData() { function gettableData() {
let params = { let params = {
rolename: input.value, rolename: input.value,
tenantId:tenValue.value,
}; };
loading.value = true; loading.value = true;
listRolePages(params) listRolePages(params)
.then((result) => { .then(result => {
tableData.value = result; tableData.value = result;
loading.value = false; loading.value = false;
}) })
@ -46,26 +48,26 @@ function handleSelectionChange(val: any) {
} }
function switchChange(row: any) { function switchChange(row: any) {
const elMessage = ref(); const elMessage = ref();
if (row.isvaild == "0") { if (row.isvaild == '0') {
elMessage.value = "确定设置该角色为无效吗?"; elMessage.value = '确定设置该角色为无效吗?';
} else if (row.isvaild == "1") { } else if (row.isvaild == '1') {
elMessage.value = "确定设置该角色为有效吗?"; elMessage.value = '确定设置该角色为有效吗?';
} }
ElMessageBox.confirm(elMessage.value, "提示信息", { ElMessageBox.confirm(elMessage.value, '提示信息', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning'
}) })
.then(() => { .then(() => {
let params = { let params = {
isvaild: row.isvaild, isvaild: row.isvaild,
id: row.id, id: row.id
}; };
isvaildTo(params).then(() => { isvaildTo(params).then(() => {
gettableData(); gettableData();
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "改变成功", message: '改变成功'
}); });
}); });
}) })
@ -75,35 +77,35 @@ function switchChange(row: any) {
} }
const infoForm = ref(); const infoForm = ref();
// //
const input = ref(""); const input = ref('');
// //
const title = ref(""); const title = ref('');
const info: any = ref({ const info: any = ref({
rolename: "", rolename: '',
level: "2", level: '2',
description: "", description: ''
}); });
const faultList: any = [ const faultList: any = [
{ {
value: "1", value: '1',
label: "超级管理员", label: '超级管理员'
}, },
{ {
value: "2", value: '2',
label: "系统管理员", label: '系统管理员'
}, },
{ {
value: "3", value: '3',
label: "一般用户", label: '一般用户'
}, }
]; ];
const dialogVisible = ref(false); const dialogVisible = ref(false);
function addClick() { function addClick() {
title.value = "新增角色"; title.value = '新增角色';
info.value = { info.value = {
rolename: "", rolename: '',
level: "2", level: '2',
description: "", description: ''
}; };
dialogVisible.value = true; dialogVisible.value = true;
} }
@ -116,6 +118,7 @@ function confirmClick(formEl: any) {
rolename: info.value.rolename, rolename: info.value.rolename,
level: info.value.level, level: info.value.level,
description: info.value.description, description: info.value.description,
tenantId:tenValue.value
}; };
addDept(params).then(() => { addDept(params).then(() => {
gettableData(); gettableData();
@ -127,6 +130,7 @@ function confirmClick(formEl: any) {
level: info.value.level, level: info.value.level,
description: info.value.description, description: info.value.description,
id: info.value.id, id: info.value.id,
tenantId:tenValue.value
}; };
renewDept(params).then(() => { renewDept(params).then(() => {
gettableData(); gettableData();
@ -150,12 +154,12 @@ function handleClose() {
} }
//-rules //-rules
const rules = ref({ const rules = ref({
rolename: [{ required: true, message: "请输入角色名称", trigger: "blur" }], rolename: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
level: [{ required: true, message: "请选择角色级别", trigger: "change" }], level: [{ required: true, message: '请选择角色级别', trigger: 'change' }]
}); });
// //
function editrole(row: any) { function editrole(row: any) {
title.value = "修改角色"; title.value = '修改角色';
info.value = JSON.parse(JSON.stringify(row)); info.value = JSON.parse(JSON.stringify(row));
dialogVisible.value = true; dialogVisible.value = true;
} }
@ -163,9 +167,9 @@ function editrole(row: any) {
const businessVisible = ref(false); const businessVisible = ref(false);
function businessclick() { function businessclick() {
// businessVisible.value = true; // businessVisible.value = true;
ElMessageBox.confirm("此模块允许用户进行定制。", "提示信息", { ElMessageBox.confirm('此模块允许用户进行定制。', '提示信息', {
confirmButtonText: "确定", confirmButtonText: '确定',
type: "warning", type: 'warning'
}).then(() => { }).then(() => {
businessVisible.value = false; businessVisible.value = false;
}); });
@ -178,14 +182,14 @@ function businessclick() {
// //
const organizeVisible = ref(false); const organizeVisible = ref(false);
const deptdata = ref(); const deptdata = ref();
const roleIda = ref(""); const roleIda = ref('');
function organizeclick(row: any) { function organizeclick(row: any) {
organizeVisible.value = true; organizeVisible.value = true;
roleIda.value = row.id; roleIda.value = row.id;
const params = { const params = {
roleId: row.id, roleId: row.id
}; };
setOrgscope(params).then((res) => { setOrgscope(params).then(res => {
deptdata.value = res; deptdata.value = res;
}); });
} }
@ -194,7 +198,9 @@ function accessCheckAllChange(indexone: any) {
for (var j = 0; j < deptdata.value[indexone].children.length; j++) { for (var j = 0; j < deptdata.value[indexone].children.length; j++) {
Arrayall.value.push(deptdata.value[indexone].children[j].orgname); Arrayall.value.push(deptdata.value[indexone].children[j].orgname);
} }
deptdata.value[indexone].array = deptdata.value[indexone].checkinfo ? Arrayall : []; deptdata.value[indexone].array = deptdata.value[indexone].checkinfo
? Arrayall
: [];
deptdata.value[indexone].bool = false; deptdata.value[indexone].bool = false;
} }
function accessCheckedCitiesChanges(indexone: any) { function accessCheckedCitiesChanges(indexone: any) {
@ -216,31 +222,31 @@ function organizesubmit() {
}); });
const params = { const params = {
id: roleIda.value, id: roleIda.value,
orgscope: allid.value.toString(), orgscope: allid.value.toString()
}; };
postOrgscope(params).then(() => { postOrgscope(params).then(() => {
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "组织范围修改成功", message: '组织范围修改成功'
}); });
organizeVisible.value = false; organizeVisible.value = false;
}); });
} }
// //
function delrole(row: any) { function delrole(row: any) {
ElMessageBox.confirm("确定删除此角色吗?", "删除提示", { ElMessageBox.confirm('确定删除此角色吗?', '删除提示', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning'
}).then(() => { }).then(() => {
let params = { let params = {
id: row.id, id: row.id
}; };
deleDept(params).then(() => { deleDept(params).then(() => {
gettableData(); gettableData();
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "删除成功", message: '删除成功'
}); });
}); });
}); });
@ -253,8 +259,8 @@ const DefaultDeployment: any = ref([]);
//id //id
const Passparameter: any = ref([]); const Passparameter: any = ref([]);
const defaultProps = { const defaultProps = {
children: "children", children: 'children',
label: "name", label: 'name'
}; };
const rowid = ref(); const rowid = ref();
function menuChange(data: any, ids: any) { function menuChange(data: any, ids: any) {
@ -273,12 +279,12 @@ function assignment(row: any) {
accessVisible.value = true; accessVisible.value = true;
const params = { const params = {
roleId: rowid.value, roleId: rowid.value,
code: '4' tenantId:tenValue.value
}; };
assignmentPer(params).then((res: any) => { permissionAssignmentGrouped(params).then((res: any) => {
accessdata.value = res; accessdata.value = res[0]?.menus || [];
let ids: any = []; let ids: any = [];
menuChange(res, ids); menuChange(res[0]?.menus, ids);
nextTick(() => { nextTick(() => {
tree.value.setCheckedKeys(ids); tree.value.setCheckedKeys(ids);
}); });
@ -287,42 +293,44 @@ function assignment(row: any) {
// //
function currentChecked(_nodeObj: any, SelectedObj: any) { function currentChecked(_nodeObj: any, SelectedObj: any) {
Passparameter.value = SelectedObj.checkedKeys.concat(SelectedObj.halfCheckedKeys); Passparameter.value = SelectedObj.checkedKeys.concat(
SelectedObj.halfCheckedKeys
);
} }
// -- // --
function accesssubmit() { function accesssubmit() {
const parans = { const parans = {
id: rowid.value, id: rowid.value,
menuIds: Passparameter.value.toString(), menuIds: Passparameter.value.toString()
}; };
setMenuById(parans).then(() => { setMenuById(parans).then(() => {
accessVisible.value = false; accessVisible.value = false;
gettableData(); gettableData();
ElMessage({ ElMessage({
type: "success", type: 'success',
message: "修改成功", message: '修改成功'
}); });
}); });
} }
// //
function delClick() { function delClick() {
ElMessageBox.confirm("确定删除已选择角色吗?", "删除提示", { ElMessageBox.confirm('确定删除已选择角色吗?', '删除提示', {
confirmButtonText: "确定", confirmButtonText: '确定',
cancelButtonText: "取消", cancelButtonText: '取消',
type: "warning", type: 'warning'
}).then(() => { }).then(() => {
let id = [] as any[]; let id = [] as any[];
multipleSelection.value.forEach((item: any) => { multipleSelection.value.forEach((item: any) => {
id.push(item.id); id.push(item.id);
}); });
let params = { let params = {
id: id.join(","), id: id.join(',')
}; };
deleDept(params).then(() => { deleDept(params).then(() => {
gettableData(); gettableData();
ElMessage({ ElMessage({
message: "删除成功", message: '删除成功',
type: "success", type: 'success'
}); });
}); });
}); });
@ -333,19 +341,41 @@ function dateFormat(row: any) {
var date = new Date(daterc); var date = new Date(daterc);
var year = date.getFullYear(); var year = date.getFullYear();
var month = var month =
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; date.getMonth() + 1 < 10
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; ? '0' + (date.getMonth() + 1)
var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); : date.getMonth() + 1;
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours(); date.getMonth() + 1 < 10
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes(); ? '0' + (date.getMonth() + 1)
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds(); : date.getMonth() + 1;
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
var minutes =
date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
var seconds =
date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
// //
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; return (
year +
'-' +
month +
'-' +
day +
' ' +
hours +
':' +
minutes +
':' +
seconds
);
} }
} }
let tenValue = ref('1')
let tenOption = ref([])
onMounted(() => { onMounted(() => {
gettableData(); gettableData();
getDictItemsByCode({ dictCode: 'PLATFORM_TENANT' }).then(res => {
tenOption.value = res.data;
});
}); });
</script> </script>
@ -369,13 +399,29 @@ onMounted(() => {
style="width: 200px" style="width: 200px"
clearable clearable
/> />
<el-button type="primary" style="margin-left: 10px" @click="gettableData" <el-select v-model="tenValue" placeholder=" " style="width: 320px;margin-left: 10px">
<el-option
v-for="item in tenOption"
:key="item.itemCode"
:label="item.dictName"
:value="item.itemCode"
/>
<!-- PLATFORM_TENANT -->
</el-select>
<el-button
type="primary"
style="margin-left: 10px"
@click="gettableData"
>搜索</el-button >搜索</el-button
> >
</div> </div>
<div> <div>
<el-button v-hasPerm="['add:role']" type="primary" @click="addClick"> <el-button v-hasPerm="['add:role']" type="primary" @click="addClick">
<img src="@/assets/MenuIcon/jscz_xz.png" alt="" style="margin-right: 3px" /> <img
src="@/assets/MenuIcon/jscz_xz.png"
alt=""
style="margin-right: 3px"
/>
新增</el-button 新增</el-button
> >
<el-button <el-button
@ -399,12 +445,24 @@ onMounted(() => {
:header-cell-style="{ :header-cell-style="{
background: 'rgb(250 250 250)', background: 'rgb(250 250 250)',
color: '#383838', color: '#383838',
height: '50px', height: '50px'
}" }"
> >
<el-table-column type="selection" width="50" align="center"></el-table-column> <el-table-column
<el-table-column prop="rolecode" label="角色编号" width="100"></el-table-column> type="selection"
<el-table-column prop="rolename" label="角色名称" width="180"></el-table-column> width="50"
align="center"
></el-table-column>
<el-table-column
prop="rolecode"
label="角色编号"
width="100"
></el-table-column>
<el-table-column
prop="rolename"
label="角色名称"
width="180"
></el-table-column>
<el-table-column prop="level" label="角色级别" width="116"> <el-table-column prop="level" label="角色级别" width="116">
<template #default="scope"> <template #default="scope">
<span v-show="scope.row.level == '1'">超级管理员</span> <span v-show="scope.row.level == '1'">超级管理员</span>
@ -417,7 +475,12 @@ onMounted(() => {
label="角色描述" label="角色描述"
min-width="100" min-width="100"
></el-table-column> ></el-table-column>
<el-table-column prop="isvaild" label="是否有效" align="center" width="120"> <el-table-column
prop="isvaild"
label="是否有效"
align="center"
width="120"
>
<template #default="scope"> <template #default="scope">
<el-switch <el-switch
v-model="scope.row.isvaild" v-model="scope.row.isvaild"
@ -426,7 +489,9 @@ onMounted(() => {
active-value="1" active-value="1"
inactive-value="0" inactive-value="0"
></el-switch> ></el-switch>
<span v-if="scope.row.isvaild == 1" style="color: #0099ff">有效</span> <span v-if="scope.row.isvaild == 1" style="color: #0099ff"
>有效</span
>
<span v-else style="color: #d7d7d7">无效</span> <span v-else style="color: #d7d7d7">无效</span>
</template> </template>
</el-table-column> </el-table-column>
@ -538,7 +603,9 @@ onMounted(() => {
" "
> >
<el-button @click="handleClose"> </el-button> <el-button @click="handleClose"> </el-button>
<el-button type="primary" @click="confirmClick(infoForm)"> </el-button> <el-button type="primary" @click="confirmClick(infoForm)"
> </el-button
>
</span> </span>
</el-form> </el-form>
</el-dialog> </el-dialog>
@ -586,9 +653,12 @@ onMounted(() => {
@change="accessCheckedCitiesChanges(indexone)" @change="accessCheckedCitiesChanges(indexone)"
style="margin-left: 20px" style="margin-left: 20px"
> >
<el-checkbox v-for="k in item.children" :key="k.id" :label="k.orgname">{{ <el-checkbox
k.orgname v-for="k in item.children"
}}</el-checkbox> :key="k.id"
:label="k.orgname"
>{{ k.orgname }}</el-checkbox
>
</el-checkbox-group> </el-checkbox-group>
</div> </div>
</div> </div>
@ -682,7 +752,7 @@ onMounted(() => {
display: inline-block; display: inline-block;
width: 120px; width: 120px;
font-size: 14px; font-size: 14px;
font-family: "微软雅黑"; font-family: '微软雅黑';
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
color: #787878; color: #787878;

View File

@ -11,7 +11,7 @@ import {
gettableData, gettableData,
DataStatus, DataStatus,
deltableData, deltableData,
getRole, listGroupedByTenant,
addUsers, addUsers,
updataUser, updataUser,
setpass, setpass,
@ -786,7 +786,7 @@ function getrole() {
const params = { const params = {
rolename: '' rolename: ''
}; };
getRole(params).then(res => { listGroupedByTenant(params).then(res => {
rolesdata.value = res; rolesdata.value = res;
}); });
} }
@ -1250,19 +1250,26 @@ function handleClearSelection() {
placeholder="请输入登录账号" placeholder="请输入登录账号"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item label="所属角色"> <el-form-item label="所属角色">
<el-select <el-select
v-model="info.roleinfo" v-model="info.roleinfo"
placeholder=" " placeholder=" "
style="width: 100%" style="width: 100%"
multiple multiple
filterable
> >
<el-option <el-option-group
v-for="item in rolesdata" v-for="group in rolesdata"
:key="item.id" :key="group.tenantName"
:label="item.rolename" :label="group.tenantName"
:value="item.id" >
/> <el-option
v-for="item in group.roles"
:key="item.id"
:label="item.rolename"
:value="item.id"
/>
</el-option-group>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -1565,4 +1572,7 @@ function handleClearSelection() {
.el-message-box { .el-message-box {
width: 300px !important; width: 300px !important;
} }
:deep(.el-select-group__title){
font-size: 16px !important;
}
</style> </style>

View File

@ -51,6 +51,14 @@ export function assignmentPer (queryParams:any){
params: queryParams params: queryParams
}); });
} }
//获取分配权限(改动之后)
export function permissionAssignmentGrouped (queryParams:any){
return request({
url:'/system/menu/permissionAssignmentGrouped' ,
method: 'post',
params: queryParams
});
}
//发出分配权限 //发出分配权限
export function setMenuById (queryParams:any){ export function setMenuById (queryParams:any){
return request({ return request({

View File

@ -57,6 +57,14 @@ export function getRole (queryParams:any) {
params: queryParams params: queryParams
}); });
} }
//获取角色
export function listGroupedByTenant (queryParams:any) {
return request({
url: '/system/role/listGroupedByTenant',
method: 'POST',
data: queryParams
});
}
//新建用户 //新建用户
export function addUsers (queryParams:any,roleids:any) { export function addUsers (queryParams:any,roleids:any) {
return request({ return request({

Some files were not shown because too many files have changed in this diff Show More