已添加13个文件
已重命名1个文件
已修改94个文件
| | |
| | | é对客æ·åºæ¯ï¼æ¿åºãååºãä¼ä¸ãå·¥ç¿ãå
Œ
±å»ºççã |
| | | |
| | | ## ãæ³¨æã宿´è½ç¢³ç®¡çå¹³å°å
å«ä¸ä¸ªé¨åï¼<span style="color: red;">æ¬ä»åºåªå
å«è½ç¢³å¹³å°åå°ç®¡ç端</span> |
| | | 1. è½ç¢³å¹³å°åå°ç®¡ç端ï¼<span style="color: red;">ä¹å³æ¬é¡¹ç®è½ç¢³å¹³å°åå°å±ç¤ºé¨åï¼ä»£ç å®å¤ï¼è¿è¡æ£å¸¸ãéè¿æ¬é¡¹ç®ï¼å¦ä¹ è
å¯ä»¥ææ¡è½æºç®¡çè¡ä¸çåè½åä¸å¡ï¼ä»¥åææ¯æ¶æã</span> |
| | | 2. æ°æ®ééç¨åºï¼ä¹å³mqttâ¡ï¸æ¶åºåºåè½ï¼è¯·åè[æä»¬å¦ä¸ä¸ªä»åºï¼ç¹å»è¶
龿¥ï¼ï¼MQTTééç½å
³](https://github.com/zhitan-cloud/zhitan-gateway)ï¼ |
| | | 3. æ°æ®æ¸
æ´æå¡ï¼ä¹å³æ¶åºåºâ¡ï¸å
³ç³»åºï¼å¦ä¹ è
å¯ä»¥ä½¿ç¨javaèªå¸¦çXXL jobç计åä»»å¡å·¥å
·èªå·±æç
§ä¸å¡åè½ï¼æ¥å®ç°æ°æ®æ¸
æ´æå¡ã |
| | | |
| | | ## æ°æå¿
读 |
| | | æè¿æå¾å¤å¼åæ°æå¨å°è¯è¿è¡æ¬é¡¹ç®ï¼å¾å¤å¤§å¦æ¯ä¸çè¦åæ¯ä¸è®ºæï¼ï¼éå°äºä¸å°é®é¢ãè§£å³åæ³ï¼ |
| | | 䏿¯å¯ä»¥å æå¾®ä¿¡ï¼ææä½ è¿å¼åå¾®ä¿¡ç¾¤ï¼æè
ä½ èªå©å qq群ãæçå°é®é¢æç©ºåºæ¬é½ä¼è§£çã |
| | | äºæ¯æ¬é¡¹ç®åºå±æ¯åºäºè¥ä¾ï¼å¤§å®¶å¯ä»¥ç§»æ¥è¥ä¾ä»åºï¼è¿è¡å¥½è¥ä¾ç示ä¾åè¿æ¥ç ç©¶æ¬é¡¹ç®ï¼ä»¥é¿å
è½è¯¯å¤§å®¶å¤ªå¤æ¶é´ï¼æè
ç»å¤§å®¶é æå¾å¤å°æ°ã |
| | | |
| | | ç©èç½é¡¹ç®æ¬èº«å°±æä¸äºé¨æ§ï¼å¸æè½å¸®å°åä½ã |
| | | ##### 1. è½ç¢³å¹³å°åå°ç®¡ç端ï¼<span style="color: red;">ä¹å³æ¬é¡¹ç®è½ç¢³å¹³å°åå°å±ç¤ºé¨åï¼ä»£ç å®å¤ï¼è¿è¡æ£å¸¸ãéè¿æ¬é¡¹ç®ï¼å¦ä¹ è
å¯ä»¥ææ¡è½æºç®¡çè¡ä¸çåè½åä¸å¡ï¼ä»¥åææ¯æ¶æã</span> |
| | | ##### 2. æ°æ®ééç¨åºï¼ä¹å³mqttâ¡ï¸æ¶åºåºåè½ï¼è¯·åè[æä»¬å¦ä¸ä¸ªä»åºï¼ç¹å»è¶
龿¥ï¼ï¼MQTTééç½å
³](https://github.com/zhitan-cloud/zhitan-gateway)ï¼æè
å¯åèthingsjsçç¥å项ç®ï¼æè
èªå·±ç¨nettyèªå·±å®ç°ã |
| | | ##### 3. æ°æ®æ¸
æ´æå¡ï¼ä¹å³æ¶åºåºâ¡ï¸å
³ç³»åºï¼å¦ä¹ è
å¯ä»¥ä½¿ç¨javaèªå¸¦çXXL jobç计åä»»å¡å·¥å
·èªå·±æç
§ä¸å¡åè½ï¼æ¥å®ç°æ°æ®æ¸
æ´æå¡ã |
| | | |
| | | ## ææ¡£--åå¨wikiç®å½ |
| | | ### github wikiå°åï¼https://github.com/zhitan-cloud/zhitan-ems/wiki |
| | |
| | | /** |
| | | * å¯å¨ç¨åº |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) |
| | | public class AdminApplication |
| | |
| | | /** |
| | | * web容å¨ä¸è¿è¡é¨ç½² |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public class AdminServletInitializer extends SpringBootServletInitializer |
| | | { |
| | |
| | | /** |
| | | *æ¯è·¯ç¨è½åæ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zt |
| | | * @date 2025-03-26 |
| | | */ |
| | | @RestController |
| | |
| | | /** |
| | | * ç¢³ææ¾æ ¸ç®Controller |
| | | * |
| | | * @author ZhiTan |
| | | * @author lsk |
| | | * @date 2024-10-29 |
| | | */ |
| | | @RestController |
| | |
| | | /** |
| | | * HomePageController |
| | | * |
| | | * @author ZhiTan |
| | | * @author hmj |
| | | * @date 2024-10-08 |
| | | */ |
| | | @RestController |
| | |
| | | |
| | | /** |
| | | * @description: è½èè¶å¿ |
| | | * @author ZhiTan |
| | | * @author: hmj |
| | | * @date: 2024/10/8 13:41 |
| | | */ |
| | | @GetMapping("/energyConsumptionTrend") |
| | |
| | | |
| | | /** |
| | | * @description: ç§å®¤è½èæå |
| | | * @author ZhiTan |
| | | * @author: hmj |
| | | * @date: 2024/10/8 13:41 |
| | | */ |
| | | @GetMapping("/energyConsumptionRanking") |
| | |
| | | |
| | | /** |
| | | * @description: å³°å¹³è°·å æ¯ |
| | | * @author ZhiTan |
| | | * @author: hmj |
| | | * @date: 2024/10/8 13:41 |
| | | */ |
| | | @GetMapping("/peakValley") |
| | |
| | | /** |
| | | * 模åèç¹Controller |
| | | * |
| | | * @author ZhiTan |
| | | * @author fanxinfu |
| | | * @date 2020-02-10 |
| | | */ |
| | | @RestController |
| | |
| | | /** |
| | | * ç»å½éªè¯ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | @RestController |
| | | public class SysLoginController |
| | |
| | | /** |
| | | * å¿å访é®ä¸é´ææ³¨è§£ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | @Target({ ElementType.METHOD, ElementType.TYPE }) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | |
| | | /** |
| | | * æ°æ®æéè¿æ»¤æ³¨è§£ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | @Target(ElementType.METHOD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | |
| | | * |
| | | * ä¼å
级ï¼å
æ¹æ³ï¼åç±»ï¼å¦ææ¹æ³è¦çäºç±»ä¸çæ°æ®æºç±»åï¼ä»¥æ¹æ³ç为åï¼å¦å以类ä¸ç为å |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | @Target({ ElementType.METHOD, ElementType.TYPE }) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | |
| | | /** |
| | | * Excel注解é |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | @Target(ElementType.FIELD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | |
| | | /** |
| | | * èªå®ä¹æä½æ¥å¿è®°å½æ³¨è§£ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | * |
| | | */ |
| | | @Target({ ElementType.PARAMETER, ElementType.METHOD }) |
| | |
| | | /** |
| | | * èªå®ä¹æ³¨è§£é²æ¢è¡¨åéå¤æäº¤ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | * |
| | | */ |
| | | @Inherited |
| | |
| | | /** |
| | | * 读å项ç®ç¸å
³é
ç½® |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | @Component |
| | | @ConfigurationProperties(prefix = "base") |
| | |
| | | /** |
| | | * ç¼åçkey 常é |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public class CacheConstants |
| | | { |
| | |
| | | |
| | | /** |
| | | * @Description: 常éå°è£
|
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´02æ02æ¥ 11:37 |
| | | */ |
| | | public class CommonConst { |
| | |
| | | /** |
| | | * éç¨å¸¸éä¿¡æ¯ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public class Constants |
| | | { |
| | |
| | | /** |
| | | * 代ç çæéç¨å¸¸é |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public class GenConstants |
| | | { |
| | |
| | | /** |
| | | * è¿åç¶æç |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public class HttpStatus |
| | | { |
| | |
| | | package com.zhitan.common.constant; |
| | | |
| | | /** |
| | | * @author ZhiTan |
| | | * @Author DYL |
| | | **/ |
| | | public class MessageConstant { |
| | | |
| | |
| | | /** |
| | | * ä»»å¡è°åº¦éç¨å¸¸é |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public class ScheduleConstants |
| | | { |
| | |
| | | |
| | | /** |
| | | * @Description: å¨æç±»å |
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´03æ17æ¥ 12:33 |
| | | */ |
| | | public class TimeTypeConst { |
| | |
| | | /** |
| | | * ç¨æ·å¸¸éä¿¡æ¯ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public class UserConstants |
| | | { |
| | |
| | | /** |
| | | * æä½æ¶æ¯æé |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public class AjaxResult extends HashMap<String, Object> |
| | | { |
| | |
| | | /** |
| | | * Entityåºç±» |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public class BaseEntity implements Serializable |
| | | { |
| | |
| | | /** |
| | | * æä½ç¶æ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | * |
| | | */ |
| | | public enum BusinessStatus |
| | |
| | | /** |
| | | * ä¸å¡æä½ç±»å |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public enum BusinessType |
| | | { |
| | |
| | | package com.zhitan.common.enums; |
| | | |
| | | /** |
| | | * @author ZhiTan |
| | | * @author èæ°å¯ |
| | | * |
| | | * 宿¶æ°æ®ç»è®¡ç±»å. |
| | | */ |
| | |
| | | /** |
| | | * æ°æ®æº |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public enum DataSourceType |
| | | { |
| | |
| | | /** |
| | | * è±æç±»å |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public enum DesensitizedType |
| | | { |
| | |
| | | /** |
| | | * åç»æ¶é´ç±»å |
| | | * |
| | | * @author ZhiTan |
| | | * @Author: Zhujw |
| | | * @Date: 2023/5/24 |
| | | */ |
| | | public enum GroupTimeType { |
| | |
| | | /** |
| | | * è¯·æ±æ¹å¼ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zhitan |
| | | */ |
| | | public enum HttpMethod |
| | | { |
| | |
| | | package com.zhitan.common.enums; |
| | | |
| | | /** |
| | | * @author ZhiTan |
| | | * @author èæ°å¯ |
| | | * |
| | | * è·å宿¶æ°æ®æ¹å¼. |
| | | */ |
| | |
| | | /** |
| | | * èªå®ä¹å¼å¸¸ |
| | | * |
| | | * @author ZhiTan |
| | | * @author ruoyi |
| | | */ |
| | | public class CustomException extends RuntimeException |
| | | { |
| | |
| | | |
| | | /** |
| | | * @Description: ç»è®¡å¾ç¸å
³æ°æ®å·¥å
·ç±» |
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´04æ28æ¥ 15:29 |
| | | */ |
| | | public class ChartUtils { |
| | |
| | | |
| | | /** |
| | | * @Description: æ¶é´å·¥å
·ç±» |
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´02æ02æ¥ 12:23 |
| | | */ |
| | | @Slf4j |
| | |
| | | |
| | | /** |
| | | * @Description: æ°åå·¥å
·ç±» |
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´02æ07æ¥ 15:03 |
| | | */ |
| | | public class DoubleUtil { |
| | |
| | | |
| | | /** |
| | | * @Description: æ´æ°ç¸å
³å·¥å
·ç±» |
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´03æ10æ¥ 17:31 |
| | | */ |
| | | public class IntegerUtil { |
| | |
| | | |
| | | /** |
| | | * @Description: 屿§å¼æä½å·¥å
·ç±» |
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´03æ07æ¥ 9:57 |
| | | */ |
| | | public class PropUtils { |
| | |
| | | /** |
| | | * åå°ç¸å
³å·¥å
·ç±» |
| | | * |
| | | * @author ZhiTan |
| | | * @author Silence |
| | | * @version 1.0 |
| | | */ |
| | | public class ReflectionUtils { |
| | |
| | | |
| | | /** |
| | | * @Description: å符串工å
·ç±» |
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´02æ02æ¥ 12:27 |
| | | */ |
| | | public class StringUtil { |
| | |
| | | |
| | | /** |
| | | * çæID |
| | | * @author ZhiTan |
| | | * @author Geoffrey |
| | | * @date 2024/12/31 |
| | | */ |
| | | public class IdGenUtil { |
| | |
| | | /** |
| | | * å项ç¨è½åæè¿åç±» |
| | | * |
| | | * @author ZhiTan |
| | | * @author å¼ |
| | | */ |
| | | @Data |
| | | public class ItemizedEnergyAnalysisVO { |
| | |
| | | /** |
| | | * å项ç¨è½åæ |
| | | * |
| | | * @author ZhiTan |
| | | * @author sys |
| | | * @date 2025-03-25 |
| | | */ |
| | | @Service |
| | |
| | | /** |
| | | *æ¯è·¯ç¨è½åæ |
| | | * |
| | | * @author ZhiTan |
| | | * @author sys |
| | | * @date 2021-01-11 |
| | | */ |
| | | public interface BranchAnalysisMapper { |
| | |
| | | /** |
| | | * æ¯è·¯ç¨è½åæ |
| | | * |
| | | * @author ZhiTan |
| | | * @author sys |
| | | * @date 2021-01-11 |
| | | */ |
| | | BranchAnalysisVO getBranchAnalysisService(BranchAnalysisDTO dataItem); |
| | |
| | | /** |
| | | * æ¯è·¯ç¨è½åæ |
| | | * |
| | | * @author ZhiTan |
| | | * @author zt |
| | | * @date 2025-03-27 |
| | | */ |
| | | @Service |
| | |
| | | /** |
| | | * ãç¢³ææ¾æ ¸ç®ãServiceä¸å¡å±å¤ç |
| | | * |
| | | * @author ZhiTan |
| | | * @author lsk |
| | | * @date 2024-10-29 |
| | | */ |
| | | @Service |
| | |
| | | /** |
| | | * é¶æ®µæ°æ®å½å
¥æ¥å£ |
| | | * |
| | | * @author ZhiTan |
| | | * @author sys |
| | | * @date 2020-03-25 |
| | | */ |
| | | public interface DataItemMapper extends BaseMapper<DataItem> { |
| | |
| | | /** |
| | | * é¶æ®µæ°æ®å½å
¥æ¥å£ |
| | | * |
| | | * @author ZhiTan |
| | | * @author sys |
| | | * @date 2020-03-25 |
| | | */ |
| | | public interface IDataItemService { |
| | |
| | | /** |
| | | * description todu |
| | | * |
| | | * @author ZhiTan |
| | | * @author hmj |
| | | * @date 2024-10-31 18:07 |
| | | */ |
| | | @Service |
| | |
| | | final Double tongbiCount = tongbiMap.get(energyNo).stream().map(HomeEnergyStatisticsVO::getCount).mapToDouble(Double::doubleValue).sum(); |
| | | final Double huanbiCount = huanbiMap.get(energyNo).stream().map(HomeEnergyStatisticsVO::getCount).mapToDouble(Double::doubleValue).sum(); |
| | | |
| | | vo.setTonCount(format2Double(count)); |
| | | vo.setTonCount(format2Double(vo.getCount() * Double.valueOf(vo.getCoefficient()))); |
| | | if (tongbiCount != 0) { |
| | | vo.setTongbi(format2Double((count - tongbiCount) / tongbiCount * 100)); |
| | | } else { |
| | |
| | | /** |
| | | * 模åèç¹å¯¹è±¡ model_node |
| | | * |
| | | * @author ZhiTan |
| | | * @author fanxinfu |
| | | * @date 2020-02-10 |
| | | */ |
| | | public class ModelNode extends BaseEntity { |
| | |
| | | /** |
| | | * 模åèç¹Mapperæ¥å£ |
| | | * |
| | | * @author ZhiTan |
| | | * @author fanxinfu |
| | | * @date 2020-02-10 |
| | | */ |
| | | public interface ModelNodeMapper extends BaseMapper<ModelNode> { |
| | |
| | | /** |
| | | * @description: æ ¹æ®èç¹idåè½æºç±»åæ¥è¯¢ç¹ä½ä¿¡æ¯ |
| | | * @param nodeId |
| | | * @author ZhiTan |
| | | * @author: hmj |
| | | * @date: 2024/10/16 19:16 |
| | | */ |
| | | List<ModelNodeIndexInfo> getModelNodeIndexIdByNodeId(@Param("nodeId")String nodeId, @Param("energyType")String energyType); |
| | |
| | | * @description: æ ¹æ®nodeIdæ¥è¯¢åèç¹çææç»è®¡ææ |
| | | * @param parentId |
| | | * @return java.util.List<com.zhitan.model.domain.vo.ModelNodeIndexInfor> |
| | | * @author ZhiTan |
| | | * @author: hmj |
| | | * @date: 2024/10/18 16:12 |
| | | */ |
| | | List<ModelNodeIndexInfo> getModelNodeByParentId(String parentId); |
| | |
| | | /** |
| | | * 模åèç¹Serviceæ¥å£ |
| | | * |
| | | * @author ZhiTan |
| | | * @author fanxinfu |
| | | * @date 2020-02-10 |
| | | */ |
| | | public interface IModelNodeService { |
| | |
| | | /** |
| | | * 模åèç¹Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author ZhiTan |
| | | * @author fanxinfu |
| | | * @date 2020-02-10 |
| | | */ |
| | | @Service |
| | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * @author ZhiTan |
| | | * @author Geoffrey |
| | | * @date 2025/01/13 |
| | | */ |
| | | @Data |
| | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author ZhiTan |
| | | * @author Geoffrey |
| | | * @date 2025/01/13 |
| | | */ |
| | | @Data |
| | |
| | | |
| | | /** |
| | | * æ¿çæ³è§å¯¹è±¡ |
| | | * @author ZhiTan |
| | | * @author Geoffrey |
| | | * @date 2025/01/13 |
| | | */ |
| | | @Data |
| | |
| | | |
| | | /** |
| | | * æ¿çæ³è§å¯¹è±¡vo |
| | | * @author ZhiTan |
| | | * @author Geoffrey |
| | | * @date 2025/01/13 |
| | | */ |
| | | @Data |
| | |
| | | |
| | | /** |
| | | * æ¿çæ³è§page vo |
| | | * @author ZhiTan |
| | | * @author Geoffrey |
| | | * @date 2025/01/13 |
| | | */ |
| | | @Data |
| | |
| | | if (ObjectUtils.isEmpty(timeType)) { |
| | | return TimeType.DAY; |
| | | } |
| | | switch (timeType) { |
| | | case DAY: |
| | | return TimeType.HOUR; |
| | | case MONTH: |
| | | return TimeType.DAY; |
| | | case YEAR: |
| | | return TimeType.MONTH; |
| | | default: |
| | | return timeType; |
| | | } |
| | | } |
| | | } |
| | |
| | | || BigDecimal.ZERO.compareTo(difference) == 0) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | // å
è®¡ç®æ¯ä¾ï¼åä¹ä»¥ 100 转æ¢ä¸ºç¾åæ° |
| | | return energyLossRatio = difference.divide(totalAccumulatedAmount, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP); |
| | | return energyLossRatio = difference.divide(totalAccumulatedAmount, 2, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | public FlowChartsVO() { |
| | |
| | | |
| | | /** |
| | | * @Description: æ°æ®æ¥è¯¢æ¡ä»¶å®ä½ |
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´01æ28æ¥ 14:49 |
| | | */ |
| | | @Data |
| | |
| | | |
| | | /** |
| | | * @Description: TODO |
| | | * @author ZhiTan |
| | | * @author: yxw |
| | | * @date: 2022å¹´04æ12æ¥ 14:15 |
| | | */ |
| | | @Service |
| | |
| | | VITE_APP_ENV = 'development' |
| | | |
| | | # ç³»ç»/å¼åç¯å¢ |
| | | # test |
| | | VITE_APP_BASE_API = 'http://127.0.0.1:8080' |
| | | VITE_APP_BASE_API = '/dev-api' |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm0 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16z"></path><path d="M12 6a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm-4 6a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4z"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg> |
| | |
| | | display: flex; |
| | | |
| | | .page-container-left { |
| | | width: 280px; |
| | | width: 220px; |
| | | min-height: calc(100vh - 148px); |
| | | border-right: 1px solid #1a235d; |
| | | background: #1F1C49; |
| | | background: #08234F; |
| | | |
| | | .el-tree { |
| | | &.el-tree--highlight-current, |
| | | &:not(.el-tree--highlight-current) { |
| | | .el-tree-node { |
| | | .el-tree-node__content { |
| | | .el-tree-node__label, |
| | | span { |
| | | font-size: 14px !important; |
| | | } |
| | | } |
| | | |
| | | .el-tree-node__expand-icon { |
| | | font-size: 14px !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .tree-container, .tree { |
| | | .el-tree-node__label, |
| | | .el-tree-node__content span { |
| | | font-size: 14px !important; |
| | | } |
| | | } |
| | | |
| | | .tree { |
| | | height: calc(100vh - 170px); |
| | |
| | | } |
| | | |
| | | .form-card { |
| | | background: #1a235d; |
| | | border-radius: 0px 0px 0px 0px; |
| | | border: 1px solid #000000; |
| | | padding: 18px 0 0 15px; |
| | | background: #08234F; |
| | | border-radius: 0px; |
| | | height: 52px; |
| | | line-height: 52px; |
| | | margin: 0 16px; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .el-form.el-form--inline { |
| | | margin-left: 10px; |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: nowrap; |
| | | width: 100%; |
| | | |
| | | .el-form-item { |
| | | margin-right: 15px; |
| | | margin-bottom: 0; |
| | | height: 32px; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | &.is-required { |
| | | .el-form-item__label::before { |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | |
| | | .el-form-item__label { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .el-form-item__content { |
| | | display: flex; |
| | | align-items: center; |
| | | height: 32px; |
| | | line-height: 32px; |
| | | |
| | | .el-input, .el-select, .el-date-editor { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .el-input__wrapper { |
| | | height: 32px; |
| | | } |
| | | |
| | | .el-button { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | padding-top: 0; |
| | | padding-bottom: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-bg-style { |
| | |
| | | border-right: 1px solid #fff; |
| | | background: #f1f4fa; |
| | | |
| | | // border-right: 1px solid #1a235d; |
| | | .el-tree { |
| | | &.el-tree--highlight-current, |
| | | &:not(.el-tree--highlight-current) { |
| | | .el-tree-node { |
| | | .el-tree-node__content { |
| | | .el-tree-node__label, |
| | | span { |
| | | font-size: 14px !important; |
| | | } |
| | | } |
| | | |
| | | .el-tree-node__expand-icon { |
| | | font-size: 14px !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .tree-container, .tree { |
| | | .el-tree-node__label, |
| | | .el-tree-node__content span { |
| | | font-size: 14px !important; |
| | | } |
| | | } |
| | | |
| | | .tree { |
| | | height: calc(100vh - 170px) !important; |
| | | max-height: calc(100vh - 170px) !important; |
| | |
| | | |
| | | .form-card { |
| | | background: #fff; |
| | | // background: #F7F8FA; |
| | | border-radius: 0px 0px 0px 0px; |
| | | // border: 1px solid #000000; |
| | | padding: 18px 0 0 15px; |
| | | border-radius: 0px; |
| | | height: 52px; |
| | | line-height: 52px; |
| | | margin: 0 16px; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .el-form.el-form--inline { |
| | | margin-left: 10px; |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: nowrap; |
| | | width: 100%; |
| | | |
| | | .el-form-item { |
| | | margin-right: 15px; |
| | | margin-bottom: 0; |
| | | height: 32px; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .el-form-item__label { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .el-form-item__content { |
| | | display: flex; |
| | | align-items: center; |
| | | height: 32px; |
| | | line-height: 32px; |
| | | |
| | | .el-input, .el-select, .el-date-editor { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | } |
| | | |
| | | .el-input__wrapper { |
| | | height: 32px; |
| | | } |
| | | |
| | | .el-button { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | padding-top: 0; |
| | | padding-bottom: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-bg-style { |
| | |
| | | |
| | | } |
| | | |
| | | // å é¤ä¹åæ·»å çå
¨å±æ ·å¼è¦çï¼é¿å
å½±åå
¨å± |
| | | // ä¿çè°è¯å»ºè®® |
| | | /* |
| | | æ¨å¯ä»¥å¨æµè§å¨ä¸ä½¿ç¨ä»¥ä¸å
èæ ·å¼è¿è¡è°è¯: |
| | | document.querySelectorAll('.page-container-left .el-tree-node__label').forEach(el => { |
| | | el.style.cssText = 'font-size: 14px !important'; |
| | | }); |
| | | */ |
| | | |
| | | .padding { |
| | | padding: 15px; |
| | | } |
| | |
| | | // æ |
| | | .el-tree { |
| | | background: transparent; |
| | | font-size: 16px; |
| | | font-size: 14px; |
| | | color: #ffffff; |
| | | |
| | | .el-tree-node__content { |
| | |
| | | .themeDark { |
| | | #app { |
| | | .el-menu-item.is-active { |
| | | background: #3271eb !important; |
| | | // background: #3271eb !important; |
| | | // border-radius: 30px 30px 30px 30px !important; |
| | | color: #fff; |
| | | } |
| | |
| | | background-color: $base-menu-background; |
| | | height: 100%; |
| | | position: fixed; |
| | | top: 0; |
| | | top: 60px; |
| | | bottom: 0; |
| | | left: 0; |
| | | z-index: 1001; |
| | | z-index: 999; |
| | | overflow: hidden; |
| | | background-color: #002866 !important; |
| | | -webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35); |
| | | box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35); |
| | | font-family: OPPOSans, OPPOSans; |
| | |
| | | .menu-title { |
| | | overflow: hidden !important; |
| | | font-weight: 400 !important; |
| | | font-size: 16px !important; |
| | | font-size: 14px !important; |
| | | } |
| | | |
| | | // @media (min-width: 1440px) { |
| | |
| | | .themeLight { |
| | | #app { |
| | | .el-menu-item.is-active { |
| | | background: #e0eafc !important; |
| | | |
| | | // border-radius: 30px 30px 30px 30px !important; |
| | | } |
| | | |
| | |
| | | background-color: $base-menu-background; |
| | | height: 100%; |
| | | position: fixed; |
| | | top: 0; |
| | | top: 60px; |
| | | bottom: 0; |
| | | left: 0; |
| | | z-index: 1001; |
| | | z-index: 999; |
| | | overflow: hidden; |
| | | -webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35); |
| | | box-shadow: none; |
| | |
| | | $--color-danger: #F56C6C; |
| | | $--color-info: #909399; |
| | | |
| | | $base-sidebar-width: 260px; |
| | | $base-sidebar-width: 220px; |
| | | |
| | | // the :export directive is the magic sauce for webpack |
| | | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="avatar-container"> |
| | | <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click"> |
| | | <div class="avatar-wrapper"> |
| | | <img :src="userStore.avatar" class="user-avatar" /> |
| | | <el-icon><caret-bottom /></el-icon> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <router-link to="/user/profile"> |
| | | <el-dropdown-item>个人ä¸å¿</el-dropdown-item> |
| | | </router-link> |
| | | <el-dropdown-item command="toggleTheme"> |
| | | <span>飿 ¼åæ¢</span> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item divided command="logout"> |
| | | <span>éåºç»å½</span> |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ElMessageBox } from "element-plus" |
| | | import useUserStore from "@/store/modules/user" |
| | | import useSettingsStore from "@/store/modules/settings" |
| | | |
| | | const userStore = useUserStore() |
| | | const settingsStore = useSettingsStore() |
| | | |
| | | function handleCommand(command) { |
| | | switch (command) { |
| | | case "toggleTheme": |
| | | const newTheme = settingsStore.sideTheme === "theme-dark" ? "theme-light" : "theme-dark"; |
| | | settingsStore.changeSetting({ key: "sideTheme", value: newTheme }); |
| | | document.querySelector("body").className = newTheme === "theme-dark" ? "themeDark" : "themeLight"; |
| | | break; |
| | | case "logout": |
| | | ElMessageBox.confirm("ç¡®å®æ³¨éå¹¶éåºç³»ç»åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | userStore.logOut().then(() => { |
| | | location.href = "/index"; |
| | | }); |
| | | }) |
| | | .catch(() => {}); |
| | | break; |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .avatar-container { |
| | | margin-right: 20px; |
| | | |
| | | .avatar-wrapper { |
| | | margin-top: 5px; |
| | | position: relative; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .user-avatar { |
| | | cursor: pointer; |
| | | width: 40px; |
| | | height: 40px; |
| | | border-radius: 10px; |
| | | } |
| | | |
| | | .el-icon { |
| | | cursor: pointer; |
| | | margin-left: 8px; |
| | | font-size: 12px; |
| | | color: #ffffff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .right-menu-item { |
| | | display: inline-block; |
| | | padding: 0 8px; |
| | | height: 100%; |
| | | font-size: 18px; |
| | | color: #ffffff; |
| | | vertical-align: text-bottom; |
| | | |
| | | &.hover-effect { |
| | | cursor: pointer; |
| | | transition: background 0.3s; |
| | | |
| | | &:hover { |
| | | background: rgba(0, 0, 0, 0.1); |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | font-family: YouSheBiaoTiHei; |
| | | font-size: 1.25vw; //24px; |
| | | color: #fff; |
| | | position: relative; |
| | | padding-left: 12px; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 5px; |
| | | height: 18px; |
| | | background-color: #3883FA; |
| | | border-radius: 2px; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | border-radius: 7px 7px 0 0; |
| | | padding: 20px; |
| | | background-color: #22408c; |
| | | |
| | | .name { |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #fff; |
| | | position: relative; |
| | | padding-left: 12px; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 5px; |
| | | height: 18px; |
| | | background-color: #3883FA; |
| | | border-radius: 2px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | border: 1px solid #ebebeb; |
| | | padding-bottom: 10px; |
| | | background-color: #fff; |
| | | |
| | | .mycard-title { |
| | | display: flex; |
| | | justify-content: flex-start; |
| | |
| | | border-radius: 7px 7px 0 0; |
| | | padding: 20px; |
| | | background-color: #e7eefd; |
| | | |
| | | .name { |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #2d2e31; |
| | | position: relative; |
| | | padding-left: 12px; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 5px; |
| | | height: 18px; |
| | | background-color: #3883FA; |
| | | border-radius: 2px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | // only show routes with meta.title |
| | | let matched = route.matched.filter(item => item.meta && item.meta.title); |
| | | const first = matched[0] |
| | | // 夿æ¯å¦ä¸ºé¦é¡µ |
| | | if (!isDashboard(first)) { |
| | | matched = [{ path: '/index', meta: { title: 'é¦é¡µ' } }].concat(matched) |
| | | } |
| | | |
| | | // ä¸èªå¨æ·»å é¦é¡µå°é¢å
å±ä¸ |
| | | // if (!isDashboard(first)) { |
| | | // matched = [{ path: '/index', meta: { title: 'é¦é¡µ' } }].concat(matched) |
| | | // } |
| | | |
| | | levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) |
| | | } |
| | |
| | | color: #fff; |
| | | cursor: text; |
| | | } |
| | | |
| | | :deep(.el-breadcrumb__item) { |
| | | .el-breadcrumb__inner { |
| | | color: rgba(255, 255, 255, 0.8); |
| | | |
| | | &:hover { |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | .el-breadcrumb__separator { |
| | | color: rgba(255, 255, 255, 0.8); |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | window.open(path.substr(pindex, path.length), "_blank"); |
| | | } else { |
| | | if (query) { |
| | | router.push({ path: path, query: JSON.parse(query) }); |
| | | router.push({ path: path, query: query }); |
| | | } else { |
| | | router.push(path) |
| | | } |
| | |
| | | getTree(); |
| | | /** æ¥è¯¢é¨é¨ä¸ææ ç»æ */ |
| | | function getTree() { |
| | | // ç¡®ä¿query.valueæåå§å¼ |
| | | query.value = query.value || {}; |
| | | |
| | | // ä¼å
使ç¨propsä¸ä¼ å
¥çParentModelCode |
| | | if (props.ParentModelCode) { |
| | | query.value = { modelCode: props.ParentModelCode }; |
| | | query.value.modelCode = props.ParentModelCode; |
| | | } else if (useRoute().query.modelCode) { |
| | | // å
¶æ¬¡ä½¿ç¨è·¯ç±ä¸çmodelCode |
| | | query.value.modelCode = useRoute().query.modelCode; |
| | | } else { |
| | | query.value = { ...useRoute().query }; |
| | | // æå使ç¨é»è®¤å¼ |
| | | query.value.modelCode = 'JCZBK_CODE'; |
| | | } |
| | | |
| | | console.log('LeftTree getTree modelCode:', query.value.modelCode); |
| | | |
| | | treeList(query.value).then((response) => { |
| | | nodeOptions.value = response.data; |
| | | if (response.data.length > 0) { |
| | | defaultExpandedKeys.value = []; // æ¸
空已æçkeyï¼é¿å
éå¤ |
| | | response.data.map((item) => { |
| | | defaultExpandedKeys.value.push(item.id); |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | function isTags(route) { |
| | | return !route.hidden && route.name && |
| | | route.name !== 'login' && |
| | | route.name !== '404' && |
| | | route.name !== '401' && |
| | | route.name !== 'index' && |
| | | route.path !== '/index' && |
| | | route.path !== '/'; |
| | | } |
| | | |
| | | function addTags() { |
| | | const { name } = route; |
| | | if (name) { |
| | | // æ£æ¥æ¯å¦ä¸ºé¦é¡µ |
| | | if (name === 'index' || route.path === '/index' || route.path === '/') { |
| | | return; |
| | | } |
| | | store.dispatch('tagsView/addView', route); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | // åå§åæ ç¾ï¼ç¡®ä¿é¦é¡µä¸è¢«æ·»å 为åºå®æ ç¾ |
| | | function initTags() { |
| | | const affixTags = filterAffixTags(routes); |
| | | for (const tag of affixTags) { |
| | | // æé¤é¦é¡µ |
| | | if (tag.path === '/index' || tag.path === '/' || tag.name === 'Index') { |
| | | continue; |
| | | } |
| | | // æ·»å åºå®æ ç¾ |
| | | if (tag.name) { |
| | | store.dispatch('tagsView/addVisitedView', tag); |
| | | } |
| | | } |
| | | } |
| | |
| | | <template> |
| | | <div class="top-nav-container"> |
| | | <div class="scroll-arrow left-arrow" @click="scrollLeft" v-show="canScrollLeft"> |
| | | <el-icon><arrow-left /></el-icon> |
| | | </div> |
| | | |
| | | <div class="menu-container" ref="menuContainer"> |
| | | <el-menu |
| | | :default-active="activeMenu" |
| | | mode="horizontal" |
| | | @select="handleSelect" |
| | | :ellipsis="false" |
| | | class="top-menu" |
| | | :class="{ 'theme-dark': theme === 'dark' }" |
| | | > |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"> |
| | | <svg-icon |
| | | v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" |
| | | :icon-class="item.meta.icon"/> |
| | | <template v-for="(item, index) in topMenus" :key="index"> |
| | | <el-menu-item :style="{'--theme': theme}" :index="item.path"> |
| | | {{ item.meta.title }} |
| | | </el-menu-item> |
| | | </template> |
| | | |
| | | <!-- é¡¶é¨èåè¶
åºæ°éæå --> |
| | | <el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber"> |
| | | <template #title>æ´å¤èå</template> |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item |
| | | :index="item.path" |
| | | :key="index" |
| | | v-if="index >= visibleNumber"> |
| | | <svg-icon |
| | | v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" |
| | | :icon-class="item.meta.icon"/> |
| | | {{ item.meta.title }} |
| | | </el-menu-item> |
| | | </template> |
| | | </el-sub-menu> |
| | | </el-menu> |
| | | </div> |
| | | |
| | | <div class="scroll-arrow right-arrow" @click="scrollRight" v-show="canScrollRight"> |
| | | <el-icon><arrow-right /></el-icon> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | |
| | | import useAppStore from '@/store/modules/app' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue' |
| | | |
| | | // 顶鍿 åå§æ° |
| | | const visibleNumber = ref(null); |
| | | // æ»å¨ç¸å
³ |
| | | const menuContainer = ref(null); |
| | | const canScrollLeft = ref(false); |
| | | const canScrollRight = ref(false); |
| | | |
| | | // å½åæ¿æ´»èåç index |
| | | const currentIndex = ref(null); |
| | | // éèä¾§è¾¹æ è·¯ç± |
| | |
| | | if (!route.meta.link) { |
| | | appStore.toggleSideBarHide(false); |
| | | } |
| | | } else if (path === '/index' || path === '/') { |
| | | // é¦é¡µæ¶éèä¾§è¾¹æ |
| | | activePath = path; |
| | | appStore.toggleSideBarHide(true); |
| | | } else if(!route.children) { |
| | | activePath = path; |
| | | appStore.toggleSideBarHide(true); |
| | |
| | | return activePath; |
| | | }) |
| | | |
| | | function setVisibleNumber() { |
| | | const width = document.body.getBoundingClientRect().width / 3; |
| | | visibleNumber.value = parseInt(width / 85); |
| | | function updateScrollButtons() { |
| | | if (!menuContainer.value) return; |
| | | |
| | | const container = menuContainer.value; |
| | | canScrollLeft.value = container.scrollLeft > 10; |
| | | canScrollRight.value = container.scrollLeft < (container.scrollWidth - container.clientWidth - 10); |
| | | } |
| | | |
| | | function scrollLeft() { |
| | | if (!menuContainer.value) return; |
| | | menuContainer.value.scrollBy({ left: -200, behavior: 'smooth' }); |
| | | setTimeout(updateScrollButtons, 300); |
| | | } |
| | | |
| | | function scrollRight() { |
| | | if (!menuContainer.value) return; |
| | | menuContainer.value.scrollBy({ left: 200, behavior: 'smooth' }); |
| | | setTimeout(updateScrollButtons, 300); |
| | | } |
| | | |
| | | function handleSelect(key, keyPath) { |
| | | currentIndex.value = key; |
| | | const route = routers.value.find(item => item.path === key); |
| | | |
| | | if (isHttp(key)) { |
| | | // http(s):// è·¯å¾æ°çªå£æå¼ |
| | | window.open(key, "_blank"); |
| | | } else if (!route || !route.children) { |
| | | // 没æåè·¯ç±è·¯å¾å
é¨æå¼ |
| | | return; |
| | | } |
| | | |
| | | if (key === '/index' || key === '/') { |
| | | // é¦é¡µæ¶æ¾ç¤ºæå çä¾§è¾¹æ ï¼è䏿¯éè |
| | | router.push({ path: key }); |
| | | appStore.showCollapsedSidebar(); |
| | | return; |
| | | } |
| | | |
| | | // æ£æ¥æ¯å¦æåè·¯ç± |
| | | if (route && route.children && route.children.length > 0) { |
| | | // æåè·¯ç±ï¼æ¾ç¤ºä¾§è¾¹æ |
| | | activeRoutes(key); |
| | | const firstChild = route.children[0]; |
| | | const path = firstChild.path.startsWith('/') ? firstChild.path : `${key}/${firstChild.path}`; |
| | | if (firstChild.query) { |
| | | router.push({ path, query: firstChild.query }); |
| | | } else { |
| | | router.push({ path }); |
| | | } |
| | | } else { |
| | | // 没æåè·¯ç±ï¼éèä¾§è¾¹æ |
| | | const routeMenu = childrenMenus.value.find(item => item.path === key); |
| | | if (routeMenu && routeMenu.query) { |
| | | let query = JSON.parse(routeMenu.query); |
| | | router.push({ path: key, query: query }); |
| | | // query å·²ç»å¨ permission.js ä¸è¢«å¤çä¸ºå¯¹è±¡ï¼æ é忬¡è§£æ |
| | | router.push({ path: key, query: routeMenu.query }); |
| | | } else { |
| | | router.push({ path: key }); |
| | | } |
| | | appStore.toggleSideBarHide(true); |
| | | } else { |
| | | // æ¾ç¤ºå·¦ä¾§èå¨èå |
| | | activeRoutes(key); |
| | | appStore.toggleSideBarHide(false); |
| | | } |
| | | } |
| | | |
| | | function activeRoutes(key) { |
| | | let routes = []; |
| | | if (key === '/index' || key === '/') { |
| | | // é¦é¡µæ¶æ¾ç¤ºæå çä¾§è¾¹æ ï¼è䏿¯éè |
| | | appStore.showCollapsedSidebar(); |
| | | return []; |
| | | } |
| | | |
| | | // æ¥æ¾å¹é
çè·¯ç± |
| | | if (childrenMenus.value && childrenMenus.value.length > 0) { |
| | | childrenMenus.value.map((item) => { |
| | | if (key == item.parentPath || (key == "index" && "" == item.path)) { |
| | |
| | | } |
| | | }); |
| | | } |
| | | |
| | | if(routes.length > 0) { |
| | | // æåè·¯ç±ï¼åæ¾ç¤ºä¾§è¾¹æ |
| | | permissionStore.setSidebarRouters(routes); |
| | | appStore.toggleSideBarHide(false); |
| | | } else { |
| | | // 没æåè·¯ç±ï¼éèä¾§è¾¹æ |
| | | appStore.toggleSideBarHide(true); |
| | | } |
| | | return routes; |
| | | } |
| | | |
| | | onMounted(() => { |
| | | window.addEventListener('resize', setVisibleNumber) |
| | | }) |
| | | onBeforeUnmount(() => { |
| | | window.removeEventListener('resize', setVisibleNumber) |
| | | // æ ¹æ®å½åè·¯ç±å³å®æ¯å¦æ¾ç¤ºä¾§è¾¹æ ï¼è䏿¯ç´æ¥éè |
| | | const currentPath = route.path; |
| | | if (currentPath === '/index' || currentPath === '/') { |
| | | // 妿å½åæ¯é¦é¡µï¼èªå¨è·³è½¬å°ç¬¬ä¸ä¸ªå¨æè·¯ç± |
| | | if (topMenus.value.length > 0) { |
| | | const firstRoute = topMenus.value[0]; |
| | | handleSelect(firstRoute.path); |
| | | } |
| | | } else { |
| | | // æ£æ¥å½åè·¯ç±æ¯å¦éè¦æ¾ç¤ºä¾§è¾¹æ |
| | | const routeConfig = routers.value.find(item => currentPath.startsWith(item.path) && item.path !== '/'); |
| | | if (routeConfig && routeConfig.children && routeConfig.children.length > 0) { |
| | | // æåèåï¼æ¾ç¤ºä¾§è¾¹æ |
| | | activeRoutes(routeConfig.path); |
| | | appStore.toggleSideBarHide(false); |
| | | } else { |
| | | // æ åèåï¼å¯ä»¥éèä¾§è¾¹æ |
| | | appStore.toggleSideBarHide(true); |
| | | } |
| | | } |
| | | |
| | | // ç嬿»å¨ç¶æ |
| | | if (menuContainer.value) { |
| | | menuContainer.value.addEventListener('scroll', updateScrollButtons); |
| | | nextTick(() => { |
| | | updateScrollButtons(); |
| | | }); |
| | | } |
| | | |
| | | window.addEventListener('resize', () => { |
| | | updateScrollButtons(); |
| | | }); |
| | | }) |
| | | |
| | | onMounted(() => { |
| | | setVisibleNumber() |
| | | onBeforeUnmount(() => { |
| | | if (menuContainer.value) { |
| | | menuContainer.value.removeEventListener('scroll', updateScrollButtons); |
| | | } |
| | | window.removeEventListener('resize', updateScrollButtons); |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .topmenu-container.el-menu--horizontal > .el-menu-item { |
| | | float: left; |
| | | height: 50px !important; |
| | | line-height: 50px !important; |
| | | color: #999093 !important; |
| | | padding: 0 5px !important; |
| | | margin: 0 10px !important; |
| | | .top-nav-container { |
| | | display: flex; |
| | | align-items: center; |
| | | flex: 1; |
| | | position: relative; |
| | | height: 60px; |
| | | overflow: hidden; |
| | | padding: 0 40px; /* Increase padding for arrows */ |
| | | |
| | | .scroll-arrow { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 28px; |
| | | height: 28px; |
| | | background: rgba(255, 255, 255, 0.2); |
| | | border-radius: 50%; |
| | | cursor: pointer; |
| | | color: #ffffff; |
| | | z-index: 20; |
| | | opacity: 0; |
| | | transition: opacity 0.3s; |
| | | position: absolute; |
| | | box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); |
| | | |
| | | &:hover { |
| | | background: rgba(255, 255, 255, 0.3); |
| | | } |
| | | |
| | | .topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-sub-menu.is-active .el-submenu__title { |
| | | border-bottom: 2px solid #{'var(--theme)'} !important; |
| | | color: #303133; |
| | | &.left-arrow { |
| | | left: 8px; |
| | | } |
| | | |
| | | /* sub-menu item */ |
| | | .topmenu-container.el-menu--horizontal > .el-sub-menu .el-sub-menu__title { |
| | | float: left; |
| | | height: 50px !important; |
| | | line-height: 50px !important; |
| | | color: #999093 !important; |
| | | padding: 0 5px !important; |
| | | margin: 0 10px !important; |
| | | &.right-arrow { |
| | | right: 8px; |
| | | } |
| | | } |
| | | |
| | | /* èæ¯è²éè */ |
| | | .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover { |
| | | background-color: #ffffff !important; |
| | | &:hover { |
| | | .scroll-arrow { |
| | | opacity: 1; |
| | | } |
| | | } |
| | | |
| | | .menu-container { |
| | | width: 100%; |
| | | height: 100%; |
| | | overflow-x: auto; |
| | | overflow-y: hidden; |
| | | scrollbar-width: none; /* Firefox */ |
| | | -ms-overflow-style: none; /* IE and Edge */ |
| | | |
| | | &::-webkit-scrollbar { |
| | | display: none; /* Chrome, Safari, Opera */ |
| | | } |
| | | } |
| | | } |
| | | |
| | | .top-menu { |
| | | height: 60px; |
| | | border-bottom: none !important; |
| | | white-space: nowrap; |
| | | background: transparent !important; |
| | | |
| | | &.theme-dark { |
| | | background: #002866 !important; |
| | | } |
| | | } |
| | | |
| | | .el-menu--horizontal { |
| | | border-bottom: none !important; |
| | | |
| | | > .el-menu-item { |
| | | display: inline-block; |
| | | float: none; |
| | | height: 60px !important; |
| | | line-height: 60px !important; |
| | | color: #ffffff !important; |
| | | padding: 0 20px !important; |
| | | margin: 0 !important; |
| | | border-bottom: none !important; |
| | | position: relative; |
| | | font-size: 16px; |
| | | |
| | | &.is-active { |
| | | background-color: transparent !important; |
| | | color: #ffffff !important; |
| | | font-weight: bold; |
| | | |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | bottom: 10px; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | width: calc(100% - 40px); |
| | | height: 2px; |
| | | background-color: #ffffff; |
| | | } |
| | | } |
| | | |
| | | &:hover { |
| | | background-color: rgba(255, 255, 255, 0.1) !important; |
| | | color: #ffffff !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 徿 å³é´è· */ |
| | | .topmenu-container .svg-icon { |
| | | margin-right: 4px; |
| | | .svg-icon { |
| | | margin-right: 8px; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | /* topmenu more arrow */ |
| | | .topmenu-container .el-sub-menu .el-sub-menu__icon-arrow { |
| | | position: static; |
| | | vertical-align: middle; |
| | | margin-left: 8px; |
| | | margin-top: 0px; |
| | | /* é¦é¡µæé®æ ·å¼ */ |
| | | .el-menu-item:first-child { |
| | | margin-left: 0 !important; |
| | | font-weight: bold; |
| | | |
| | | .svg-icon { |
| | | font-size: 18px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | position: relative; |
| | | overflow: hidden; |
| | | background: #110f2e; |
| | | padding: 14px 0 0 14px; |
| | | padding: 14px; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .fixed-header + .app-main { |
| | |
| | | .hasTagsView { |
| | | .app-main { |
| | | /* 84 = navbar + tags-view + padding = 70 + 56 + 14 */ |
| | | min-height: calc(100vh - 125px); |
| | | // padding: 20px; |
| | | min-height: calc(100vh - 110px); |
| | | } |
| | | |
| | | .fixed-header + .app-main { |
| | |
| | | position: relative; |
| | | overflow: hidden; |
| | | background: #f7f8fa; |
| | | padding: 14px 0 0 14px; |
| | | padding: 14px; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .fixed-header + .app-main { |
| | |
| | | .hasTagsView { |
| | | .app-main { |
| | | /* 84 = navbar + tags-view + padding = 70 + 56 + 14 */ |
| | | min-height: calc(100vh - 125px); |
| | | // padding: 20px; |
| | | min-height: calc(100vh - 110px); |
| | | } |
| | | |
| | | .fixed-header + .app-main { |
| | |
| | | </div> |
| | | |
| | | <div class="right-menu"> |
| | | <!-- <template v-if="appStore.device !== 'mobile'"> |
| | | <header-search id="header-search" class="right-menu-item" /> |
| | | |
| | | <screenfull id="screenfull" class="right-menu-item hover-effect" /> |
| | | |
| | | <el-tooltip content="å¸å±å¤§å°" effect="dark" placement="bottom"> |
| | | <size-select id="size-select" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | </template> --> |
| | | <!-- <el-button @click="toggleTheme">忢</el-button> --> |
| | | <div class="avatar-container"> |
| | | <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click"> |
| | | <div class="avatar-wrapper"> |
| | | <img :src="userStore.avatar" class="user-avatar" /> |
| | | <el-icon><caret-bottom /></el-icon> |
| | | <!-- æ¥è¦æé® --> |
| | | <div class="right-menu-item hover-effect nav-btn-item"> |
| | | <el-tooltip content="æ¥è¦" effect="dark" placement="bottom"> |
| | | <div class="nav-btn" @click="handleAlarm"> |
| | | <img src="@/assets/images/alarm.png" alt="æ¥è¦" /> |
| | | <span>æ¥è¦</span> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <router-link to="/user/profile"> |
| | | <el-dropdown-item>个人ä¸å¿</el-dropdown-item> |
| | | </router-link> |
| | | <el-dropdown-item command="toggleTheme"> |
| | | <span>飿 ¼åæ¢</span> |
| | | </el-dropdown-item> |
| | | <!-- |
| | | <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings"> |
| | | <span>å¸å±è®¾ç½®</span> |
| | | </el-dropdown-item> --> |
| | | <el-dropdown-item divided command="logout"> |
| | | <span>éåºç»å½</span> |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </el-tooltip> |
| | | </div> |
| | | |
| | | <!-- 大模åæé® --> |
| | | <div class="right-menu-item hover-effect nav-btn-item"> |
| | | <el-tooltip content="大模å" effect="dark" placement="bottom"> |
| | | <div class="nav-btn" @click="handleRobot"> |
| | | <img src="@/assets/images/robot.png" alt="大模å" /> |
| | | <span>大模å</span> |
| | | </div> |
| | | </el-tooltip> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ElMessageBox } from "element-plus" |
| | | import Breadcrumb from "@/components/Breadcrumb" |
| | | import TopNav from "@/components/TopNav" |
| | | import Hamburger from "@/components/Hamburger" |
| | | import Screenfull from "@/components/Screenfull" |
| | | import SizeSelect from "@/components/SizeSelect" |
| | | import HeaderSearch from "@/components/HeaderSearch" |
| | | import useAppStore from "@/store/modules/app" |
| | | import useUserStore from "@/store/modules/user" |
| | | import useSettingsStore from "@/store/modules/settings" |
| | | |
| | | const appStore = useAppStore() |
| | | const userStore = useUserStore() |
| | | const settingsStore = useSettingsStore() |
| | | |
| | | function toggleTheme() { |
| | | if (settingsStore.sideTheme == "theme-dark") { |
| | | settingsStore.sideTheme = "theme-light" |
| | | document.querySelector("body").className = "themeLight" |
| | | } else { |
| | | settingsStore.sideTheme = "theme-dark" |
| | | document.querySelector("body").className = "themeDark" |
| | | } |
| | | } |
| | | |
| | | function toggleSideBar() { |
| | | appStore.toggleSideBar() |
| | | } |
| | | |
| | | function handleCommand(command) { |
| | | switch (command) { |
| | | case "toggleTheme": |
| | | toggleTheme() |
| | | break |
| | | case "setLayout": |
| | | setLayout() |
| | | break |
| | | case "logout": |
| | | logout() |
| | | break |
| | | default: |
| | | break |
| | | } |
| | | function handleAlarm() { |
| | | // å¤çæ¥è¦æé®ç¹å»äºä»¶ |
| | | console.log('æ¥è¦æé®è¢«ç¹å»') |
| | | } |
| | | |
| | | function logout() { |
| | | ElMessageBox.confirm("ç¡®å®æ³¨éå¹¶éåºç³»ç»åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | userStore.logOut().then(() => { |
| | | location.href = "/index" |
| | | }) |
| | | }) |
| | | .catch(() => {}) |
| | | } |
| | | |
| | | const emits = defineEmits(["setLayout"]) |
| | | function setLayout() { |
| | | emits("setLayout") |
| | | function handleRobot() { |
| | | // å¤ç大模åæé®ç¹å»äºä»¶ |
| | | console.log('大模åæé®è¢«ç¹å»') |
| | | } |
| | | </script> |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | .avatar-container { |
| | | margin-right: 40px; |
| | | .nav-btn-item { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 20px; |
| | | height: 70px; |
| | | |
| | | .avatar-wrapper { |
| | | margin-top: 5px; |
| | | position: relative; |
| | | |
| | | .user-avatar { |
| | | .nav-btn { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | width: 40px; |
| | | height: 40px; |
| | | border-radius: 10px; |
| | | color: #fff; |
| | | background-color: rgba(255, 255, 255, 0.1); |
| | | border-radius: 4px; |
| | | padding: 8px 16px; |
| | | |
| | | &:hover { |
| | | background-color: rgba(255, 255, 255, 0.2); |
| | | } |
| | | |
| | | i { |
| | | cursor: pointer; |
| | | position: absolute; |
| | | right: -20px; |
| | | top: 25px; |
| | | font-size: 12px; |
| | | img { |
| | | width: 20px; |
| | | height: 20px; |
| | | margin-right: 6px; |
| | | } |
| | | |
| | | span { |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | .avatar-container { |
| | | margin-right: 40px; |
| | | .nav-btn-item { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 20px; |
| | | height: 70px; |
| | | |
| | | .avatar-wrapper { |
| | | margin-top: 5px; |
| | | position: relative; |
| | | |
| | | .user-avatar { |
| | | .nav-btn { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | width: 40px; |
| | | height: 40px; |
| | | border-radius: 10px; |
| | | color: #333; |
| | | background-color: rgba(0, 0, 0, 0.05); |
| | | border-radius: 4px; |
| | | padding: 8px 16px; |
| | | |
| | | &:hover { |
| | | background-color: rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | i { |
| | | cursor: pointer; |
| | | position: absolute; |
| | | right: -20px; |
| | | top: 25px; |
| | | font-size: 12px; |
| | | img { |
| | | width: 20px; |
| | | height: 20px; |
| | | margin-right: 6px; |
| | | } |
| | | |
| | | span { |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | } |
| | |
| | | function handleTheme(val) { |
| | | settingsStore.sideTheme = val |
| | | sideTheme.value = val |
| | | // Update body class to match the theme |
| | | document.querySelector("body").className = val === 'theme-dark' ? "themeDark" : "themeLight" |
| | | } |
| | | function saveSetting() { |
| | | proxy.$modal.loading("æ£å¨ä¿åå°æ¬å°ï¼è¯·ç¨å...") |
| | |
| | | return props.basePath |
| | | } |
| | | if (routeQuery) { |
| | | let query = JSON.parse(routeQuery); |
| | | let query = routeQuery; |
| | | // 妿 routeQuery æ¯å符串ï¼åå°è¯è§£æå® |
| | | if (typeof routeQuery === 'string') { |
| | | try { |
| | | query = JSON.parse(routeQuery); |
| | | } catch (error) { |
| | | console.error('Error parsing query string:', routeQuery, error); |
| | | } |
| | | } |
| | | return { path: getNormalPath(props.basePath + '/' + routePath), query: query } |
| | | } |
| | | return getNormalPath(props.basePath + '/' + routePath) |
| | |
| | | :class="{ 'has-logo': showLogo }" |
| | | :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }" |
| | | > |
| | | <logo v-if="showLogo" :collapse="isCollapse" /> |
| | | <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper"> |
| | | <!-- é¦é¡µæ¶ä¸æ¾ç¤ºä»»ä½èå项 --> |
| | | <el-menu |
| | | v-if="!isHomePage" |
| | | :default-active="activeMenu" |
| | | :collapse="isCollapse" |
| | | :background-color="sideTheme === 'theme-dark' ? '#232D70' : '#fff'" |
| | | :background-color="'transparent'" |
| | | :text-color="sideTheme === 'theme-dark' ? '#fff' : '#000'" |
| | | :unique-opened="true" |
| | | :active-text-color="theme" |
| | | :collapse-transition="false" |
| | | mode="vertical" |
| | | class="custom-menu" |
| | | > |
| | | <sidebar-item |
| | | v-for="(route, index) in sidebarRouters" |
| | |
| | | :base-path="route.path" |
| | | /> |
| | | </el-menu> |
| | | <!-- é¦é¡µæ¶ç空ç½åºå --> |
| | | <div v-else class="home-empty-menu"></div> |
| | | </el-scrollbar> |
| | | |
| | | <!-- åºé¨ç¨æ·åºå --> |
| | | <div class="sidebar-footer" :class="{ 'collapsed': isCollapse, 'theme-light': sideTheme === 'theme-light' }"> |
| | | <div class="user-avatar-container"> |
| | | <img :src="userStore.avatar" class="user-avatar" /> |
| | | </div> |
| | | |
| | | <!-- å±å¼ç¶æä¸æ¾ç¤ºå®æ´å
容 --> |
| | | <div class="user-info" v-if="!isCollapse"> |
| | | <div class="username">{{ userStore.name || 'admin' }}</div> |
| | | |
| | | <div class="action-buttons"> |
| | | <div class="action-button" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toUserProfile"> |
| | | <el-icon><User /></el-icon> |
| | | <span>个人ä¸å¿</span> |
| | | </div> |
| | | |
| | | <div class="action-button" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toggleTheme"> |
| | | <el-icon><Brush /></el-icon> |
| | | <span>忢䏻é¢</span> |
| | | </div> |
| | | |
| | | <div class="action-button" :class="{'theme-light': sideTheme === 'theme-light'}" @click="handleLogout"> |
| | | <el-icon><SwitchButton /></el-icon> |
| | | <span>éåºç»å½</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- æå ç¶æä¸åªæ¾ç¤ºå¾æ æé® --> |
| | | <div class="collapsed-actions" v-if="isCollapse"> |
| | | <div class="action-icon" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toUserProfile" title="个人ä¸å¿"> |
| | | <el-icon><User /></el-icon> |
| | | </div> |
| | | |
| | | <div class="action-icon" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toggleTheme" title="忢䏻é¢"> |
| | | <el-icon><Brush /></el-icon> |
| | | </div> |
| | | |
| | | <div class="action-icon" :class="{'theme-light': sideTheme === 'theme-light'}" @click="handleLogout" title="éåºç»å½"> |
| | | <el-icon><SwitchButton /></el-icon> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import Logo from "./Logo" |
| | | import SidebarItem from "./SidebarItem" |
| | | import variables from "@/assets/styles/variables.module.scss" |
| | | import useAppStore from "@/store/modules/app" |
| | | import useSettingsStore from "@/store/modules/settings" |
| | | import usePermissionStore from "@/store/modules/permission" |
| | | import useUserStore from "@/store/modules/user" |
| | | import { User, Brush, SwitchButton } from '@element-plus/icons-vue' |
| | | import { ElMessageBox } from 'element-plus' |
| | | import { useRouter } from 'vue-router' |
| | | |
| | | const router = useRouter() |
| | | const route = useRoute() |
| | | const appStore = useAppStore() |
| | | const settingsStore = useSettingsStore() |
| | | const permissionStore = usePermissionStore() |
| | | const userStore = useUserStore() |
| | | |
| | | const sidebarRouters = computed(() => permissionStore.sidebarRouters) |
| | | |
| | | // 夿å½åæ¯å¦ä¸ºé¦é¡µ |
| | | const isHomePage = computed(() => { |
| | | return route.path === '/index' || route.path === '/' || route.fullPath.startsWith('/index') |
| | | }) |
| | | |
| | | // é¦é¡µä¸ç¨è·¯ç±ï¼åªæé¦é¡µä¸ä¸ªèå项 |
| | | const homePageRouters = computed(() => { |
| | | // ä»åå§è·¯ç±ä¸çéåºé¦é¡µè·¯ç± |
| | | const homeRoute = sidebarRouters.value.find(route => { |
| | | return route.children && route.children.find(child => child.path === '/index') |
| | | }) |
| | | |
| | | return homeRoute ? [homeRoute] : [] |
| | | }) |
| | | |
| | | const showLogo = computed(() => settingsStore.sidebarLogo) |
| | | const sideTheme = computed(() => settingsStore.sideTheme) |
| | | const theme = computed(() => settingsStore.theme) |
| | |
| | | } |
| | | return path |
| | | }) |
| | | |
| | | function toUserProfile() { |
| | | router.push('/user/profile') |
| | | } |
| | | |
| | | function toggleTheme() { |
| | | if (settingsStore.sideTheme == "theme-dark") { |
| | | settingsStore.sideTheme = "theme-light" |
| | | document.querySelector("body").className = "themeLight" |
| | | } else { |
| | | settingsStore.sideTheme = "theme-dark" |
| | | document.querySelector("body").className = "themeDark" |
| | | } |
| | | } |
| | | |
| | | function handleLogout() { |
| | | ElMessageBox.confirm("ç¡®å®æ³¨éå¹¶éåºç³»ç»åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | userStore.logOut().then(() => { |
| | | location.href = "/index" |
| | | }) |
| | | }) |
| | | .catch(() => {}) |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped></style> |
| | | <style lang="scss" scoped> |
| | | :deep(.custom-menu) { |
| | | padding: 6px 0; |
| | | height: calc(100% - 150px); // çåºåºé¨ç¨æ·åºåçç©ºé´ |
| | | |
| | | // Override Element Plus default menu styles |
| | | .el-menu-item { |
| | | height: 38px !important; |
| | | line-height: 38px !important; |
| | | border-radius: 4px; |
| | | margin: 4px 10px; |
| | | width: calc(100% - 20px); |
| | | |
| | | &.is-active { |
| | | background-color: #3883FA !important; |
| | | color: #fff !important; |
| | | } |
| | | |
| | | &:hover { |
| | | background-color: rgba(56, 131, 250, 0.1) !important; |
| | | } |
| | | } |
| | | |
| | | .el-sub-menu { |
| | | .el-sub-menu__title { |
| | | height: 38px !important; |
| | | line-height: 38px !important; |
| | | border-radius: 4px; |
| | | margin: 4px 10px; |
| | | width: calc(100% - 20px); |
| | | |
| | | &:hover { |
| | | background-color: rgba(56, 131, 250, 0.1) !important; |
| | | } |
| | | } |
| | | |
| | | .el-menu-item { |
| | | padding-left: 45px !important; |
| | | min-width: auto !important; |
| | | |
| | | &.is-active { |
| | | padding-left: 45px !important; |
| | | } |
| | | } |
| | | |
| | | // For nested submenus |
| | | .el-menu { |
| | | .el-menu-item, |
| | | .el-sub-menu__title { |
| | | height: 38px !important; |
| | | line-height: 38px !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // é¦é¡µç©ºç½èååºåæ ·å¼ |
| | | .home-empty-menu { |
| | | height: calc(100% - 150px); |
| | | } |
| | | |
| | | // åºé¨ç¨æ·åºåæ ·å¼ |
| | | .sidebar-footer { |
| | | position: absolute; |
| | | bottom: 72px; |
| | | left: 0; |
| | | width: 100%; |
| | | border-top: 1px solid rgba(255, 255, 255, 0.1); |
| | | padding: 16px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | |
| | | &.collapsed { |
| | | padding: 10px; |
| | | |
| | | .user-avatar-container { |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | |
| | | &.theme-light { |
| | | background-color: rgba(255, 255, 255, 0.6); |
| | | border-top: 1px solid rgba(0, 0, 0, 0.1); |
| | | |
| | | .user-avatar-container { |
| | | border-color: rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .user-info { |
| | | .username { |
| | | color: #333; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .user-avatar-container { |
| | | margin-bottom: 10px; |
| | | border: 2px dashed rgba(255, 255, 255, 0.3); |
| | | border-radius: 4px; |
| | | width: 54px; |
| | | height: 54px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | .user-avatar { |
| | | width: 38px; |
| | | height: 38px; |
| | | border-radius: 4px; |
| | | } |
| | | } |
| | | |
| | | .user-info { |
| | | width: 100%; |
| | | text-align: center; |
| | | |
| | | .username { |
| | | color: #fff; |
| | | font-size: 16px; |
| | | font-weight: 500; |
| | | margin-bottom: 16px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .action-buttons { |
| | | .action-button { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | background: rgba(56, 131, 250, 0.11); |
| | | border-radius: 9px; |
| | | border: 1px solid rgba(255, 255, 255, 0.3); |
| | | color: #fff; |
| | | padding: 10px; |
| | | margin-bottom: 10px; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | transition: background-color 0.3s; |
| | | |
| | | &:hover { |
| | | background: rgba(56, 131, 250, 0.2); |
| | | } |
| | | |
| | | .el-icon { |
| | | margin-right: 8px; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | span { |
| | | font-size: 14px; |
| | | } |
| | | |
| | | &.theme-light { |
| | | background-color: rgba(56, 131, 250, 1); |
| | | color: #fff; |
| | | border: 1px solid rgba(56, 131, 250, 0.8); |
| | | |
| | | &:hover { |
| | | background-color: rgba(56, 131, 250, 0.9); |
| | | } |
| | | |
| | | .el-icon { |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .collapsed-actions { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | width: 100%; |
| | | |
| | | .action-icon { |
| | | width: 40px; |
| | | height: 40px; |
| | | margin-bottom: 8px; |
| | | background: rgba(56, 131, 250, 0.11); |
| | | border: 1px solid rgba(255, 255, 255, 0.3); |
| | | border-radius: 4px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | background: rgba(56, 131, 250, 0.2); |
| | | } |
| | | |
| | | .el-icon { |
| | | font-size: 20px; |
| | | color: #fff; |
| | | } |
| | | |
| | | &.theme-light { |
| | | background: rgba(56, 131, 250, 1); |
| | | border: 1px solid rgba(56, 131, 250, 0.8); |
| | | |
| | | &:hover { |
| | | background: rgba(56, 131, 250, 0.9); |
| | | } |
| | | |
| | | .el-icon { |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .theme-light { |
| | | :deep(.custom-menu) { |
| | | // Override Element Plus menu styles for light theme |
| | | .el-menu-item { |
| | | &.is-active { |
| | | background-color: #3883FA !important; |
| | | color: #fff !important; |
| | | } |
| | | |
| | | &:hover { |
| | | background-color: rgba(56, 131, 250, 0.1) !important; |
| | | } |
| | | } |
| | | |
| | | .el-sub-menu { |
| | | .el-sub-menu__title { |
| | | &:hover { |
| | | background-color: rgba(56, 131, 250, 0.1) !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Add global style to override Element Plus defaults |
| | | :global(.el-menu--vertical .el-menu-item), |
| | | :global(.el-menu--vertical .el-sub-menu__title) { |
| | | height: 38px !important; |
| | | line-height: 38px !important; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }"> |
| | | <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/> |
| | | <div class="navbar-container"> |
| | | <div class="navbar"> |
| | | <div class="left"> |
| | | <div class="sidebar-logo-container" :class="{ collapse: !sidebar.opened }"> |
| | | <div class="logo" v-if="systemInfo && systemInfo.leftLogo"> |
| | | <img v-if="sideTheme === 'theme-dark'" :src="systemInfo.leftLogo" class="sidebar-logo" /> |
| | | <img v-else :src="systemInfo.leftLogo" class="sidebar-logo" /> |
| | | </div> |
| | | <div class="name" v-if="sidebar.opened" :style="{ color: '#fff' }"> |
| | | {{ title }} |
| | | </div> |
| | | </div> |
| | | <hamburger |
| | | id="hamburger-container" |
| | | :is-active="appStore.sidebar.opened" |
| | | class="hamburger-container" |
| | | @toggleClick="toggleSideBar" |
| | | /> |
| | | </div> |
| | | <top-nav /> |
| | | <div class="right"> |
| | | <!-- æ¥è¦å大模åæé® --> |
| | | <div class="right-menu"> |
| | | <!-- æ¥è¦æé® --> |
| | | <div class="right-menu-item alarm-btn" @click="goToAlarm"> |
| | | <el-badge :value="alarmCount" :max="99" class="alarm-badge"> |
| | | <svg-icon icon-class="bell" class="right-menu-icon" /> |
| | | </el-badge> |
| | | <span class="right-menu-text">æ¥è¦</span> |
| | | </div> |
| | | |
| | | <!-- 大模åæé® --> |
| | | <div class="right-menu-item ai-btn" @click="openAIModel"> |
| | | <svg-icon icon-class="ai" class="right-menu-icon" /> |
| | | <span class="right-menu-text">æºè½å©æ</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="content-container"> |
| | | <sidebar v-if="!sidebar.hide" class="sidebar-container" /> |
| | | <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container"> |
| | | <div :class="{ 'fixed-header': fixedHeader }"> |
| | | <navbar @setLayout="setLayout" v-if="!sidebar.hide"/> |
| | | <tags-view v-if="needTagsView" v-show="!sidebar.hide"/> |
| | | </div> |
| | | <app-main /> |
| | | <settings ref="settingRef" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, watchEffect, onMounted } from 'vue' |
| | | import { useWindowSize } from '@vueuse/core' |
| | | import { useRoute, useRouter } from 'vue-router' |
| | | import Sidebar from './components/Sidebar/index.vue' |
| | | import { AppMain, Navbar, Settings, TagsView } from './components' |
| | | import { AppMain, Settings, TagsView } from './components' |
| | | import TopNav from '@/components/TopNav' |
| | | import Hamburger from '@/components/Hamburger' |
| | | import defaultSettings from '@/settings' |
| | | import Cookies from "js-cookie" |
| | | |
| | | import useAppStore from '@/store/modules/app' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | const appStore = useAppStore() |
| | | const settingsStore = useSettingsStore() |
| | | const theme = computed(() => settingsStore.theme); |
| | | const sideTheme = computed(() => settingsStore.sideTheme); |
| | | const sidebar = computed(() => useAppStore().sidebar); |
| | | const device = computed(() => useAppStore().device); |
| | | const sidebar = computed(() => appStore.sidebar); |
| | | const device = computed(() => appStore.device); |
| | | const needTagsView = computed(() => settingsStore.tagsView); |
| | | const fixedHeader = computed(() => settingsStore.fixedHeader); |
| | | const systemInfo = JSON.parse(Cookies.get("SystemInfo") || '{"systemName":"æºæ±è½æºç®¡çç³»ç»","leftLogo":""}') |
| | | const title = systemInfo.systemName || import.meta.env.VITE_APP_TITLE |
| | | |
| | | // æ¥è¦æ°éï¼å¯ä»¥ä»æ¥å£è·å |
| | | const alarmCount = ref(5) |
| | | |
| | | // è·³è½¬å°æ¥è¦é¡µé¢ |
| | | function goToAlarm() { |
| | | router.push('/alarm/list') |
| | | } |
| | | |
| | | // æå¼AI大模åå¯¹è¯æ¡ |
| | | function openAIModel() { |
| | | // è¿éå¯ä»¥å®ç°æå¼AIå¯¹è¯æ¡çé»è¾ |
| | | console.log('æå¼AI大模åå¯¹è¯æ¡') |
| | | } |
| | | |
| | | const classObj = computed(() => ({ |
| | | hideSidebar: !sidebar.value.opened, |
| | |
| | | })) |
| | | |
| | | const { width, height } = useWindowSize(); |
| | | const WIDTH = 992; // refer to Bootstrap's responsive design |
| | | const WIDTH = 992; |
| | | |
| | | watchEffect(() => { |
| | | if (device.value === 'mobile' && sidebar.value.opened) { |
| | | useAppStore().closeSideBar({ withoutAnimation: false }) |
| | | appStore.closeSideBar({ withoutAnimation: false }) |
| | | } |
| | | if (width.value - 1 < WIDTH) { |
| | | useAppStore().toggleDevice('mobile') |
| | | useAppStore().closeSideBar({ withoutAnimation: true }) |
| | | appStore.toggleDevice('mobile') |
| | | appStore.closeSideBar({ withoutAnimation: true }) |
| | | } else { |
| | | useAppStore().toggleDevice('desktop') |
| | | appStore.toggleDevice('desktop') |
| | | } |
| | | }) |
| | | |
| | | // çå¬è·¯ç±ååï¼å¤çé¦é¡µçä¾§è¾¹æ æ¾ç¤º |
| | | watchEffect(() => { |
| | | // æ£æ¥æ¯å¦æ¯é¦é¡µè·¯ç± |
| | | if (route.path === '/index' || route.path === '/') { |
| | | // é¦é¡µè·¯ç±ï¼ç¡®ä¿ä¾§è¾¹æ ä¸éèï¼ä½ç¶ææ¯æå ç |
| | | appStore.showCollapsedSidebar() |
| | | } else if (route.meta && route.meta.showSidebar === false) { |
| | | // å¦æè·¯ç±æç¡®æå®éèä¾§è¾¹æ |
| | | appStore.toggleSideBarHide(true) |
| | | } |
| | | }) |
| | | |
| | | // ç»ä»¶æè½½æ¶ï¼ç¡®ä¿é¦é¡µä¾§è¾¹æ ç¶ææ£ç¡® |
| | | onMounted(() => { |
| | | // 妿å½åæ¯é¦é¡µï¼ç¡®ä¿ä¾§è¾¹æ æ¯æå çè䏿¯éèç |
| | | if (route.path === '/index' || route.path === '/') { |
| | | appStore.showCollapsedSidebar() |
| | | } |
| | | }) |
| | | |
| | | function handleClickOutside() { |
| | | useAppStore().closeSideBar({ withoutAnimation: false }) |
| | | appStore.closeSideBar({ withoutAnimation: false }) |
| | | } |
| | | |
| | | function toggleSideBar() { |
| | | appStore.toggleSideBar() |
| | | } |
| | | |
| | | const settingRef = ref(null); |
| | |
| | | .app-wrapper { |
| | | @include clearfix; |
| | | position: relative; |
| | | height: 100%; |
| | | width: 100%; |
| | | height: 100vh; |
| | | width: 100vw; |
| | | display: flex; |
| | | flex-direction: column; |
| | | overflow-x: hidden; |
| | | |
| | | &.mobile.openSidebar { |
| | | position: fixed; |
| | |
| | | z-index: 999; |
| | | } |
| | | |
| | | .fixed-header { |
| | | .navbar-container { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | height: 60px; |
| | | z-index: 1000; |
| | | width: 100%; |
| | | } |
| | | |
| | | .navbar { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | background-color: var(--current-color); |
| | | height: 60px; |
| | | width: 100%; |
| | | padding: 0; |
| | | |
| | | .left { |
| | | display: flex; |
| | | align-items: center; |
| | | padding-left: 16px; |
| | | |
| | | .sidebar-logo-container { |
| | | display: flex; |
| | | align-items: center; |
| | | height: 60px; |
| | | padding: 0 15px; |
| | | min-width: 220px; |
| | | |
| | | .logo { |
| | | width: 40px; |
| | | height: 40px; |
| | | margin-right: 10px; |
| | | flex-shrink: 0; |
| | | |
| | | .sidebar-logo { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | |
| | | .name { |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: bold; |
| | | font-size: 20px; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | |
| | | &.collapse { |
| | | min-width: 70px; |
| | | |
| | | .name { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .right { |
| | | display: flex; |
| | | align-items: center; |
| | | padding-right: 20px; |
| | | |
| | | .right-menu { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .right-menu-item { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-left: 20px; |
| | | cursor: pointer; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | transition: all 0.3s; |
| | | |
| | | &:hover { |
| | | opacity: 0.8; |
| | | } |
| | | |
| | | .right-menu-icon { |
| | | font-size: 18px; |
| | | margin-right: 5px; |
| | | } |
| | | |
| | | .right-menu-text { |
| | | margin-left: 5px; |
| | | } |
| | | } |
| | | |
| | | .alarm-badge { |
| | | :deep(.el-badge__content) { |
| | | background-color: #f56c6c; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .content-container { |
| | | display: flex; |
| | | position: relative; |
| | | margin-top: 60px; |
| | | height: calc(100vh - 60px); |
| | | width: 100%; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .sidebar-container { |
| | | position: relative; |
| | | height: 100%; |
| | | z-index: 900; |
| | | flex-shrink: 0; |
| | | width: $base-sidebar-width; |
| | | |
| | | } |
| | | |
| | | .fixed-header { |
| | | position: fixed; |
| | | top: 60px; |
| | | right: 0; |
| | | z-index: 9; |
| | | width: calc(100% - #{$base-sidebar-width}); |
| | | width: 100%; |
| | | transition: width 0.28s; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .hideSidebar .fixed-header { |
| | | width: calc(100% - 54px); |
| | | } |
| | | |
| | | .sidebarHide .fixed-header { |
| | | width: 100%; |
| | | } |
| | | |
| | | .mobile .fixed-header { |
| | | width: 100%; |
| | | } |
| | | |
| | | .main-container { |
| | | flex: 1; |
| | | position: relative; |
| | | height: 100%; |
| | | overflow-y: auto; |
| | | overflow-x: hidden; |
| | | transition: margin-left 0.28s; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .hideSidebar .main-container { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | .sidebarHide .main-container { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | .mobile .main-container { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | .hideSidebar .sidebar-container { |
| | | width: 54px; |
| | | } |
| | | |
| | | .sidebarHide .sidebar-container { |
| | | display: none; |
| | | } |
| | | |
| | | .themeDark { |
| | | .navbar-container { |
| | | background: #1a235d; |
| | | border-bottom: 2px solid #110f2e; |
| | | } |
| | | |
| | | .navbar { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | .sidebar-container { |
| | | background-color: #002866 !important; |
| | | } |
| | | } |
| | | |
| | | .themeLight { |
| | | .navbar-container { |
| | | background: #3883FA; |
| | | } |
| | | |
| | | .navbar { |
| | | background: transparent !important; |
| | | |
| | | .left { |
| | | .sidebar-logo-container { |
| | | .name { |
| | | color: #fff !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .right { |
| | | .right-menu { |
| | | .right-menu-item { |
| | | color: #fff; |
| | | |
| | | .right-menu-icon { |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | import useUserStore from '@/store/modules/user' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | import useTagsViewStore from '@/store/modules/tagsView' |
| | | |
| | | NProgress.configure({ showSpinner: false }); |
| | | |
| | |
| | | router.addRoute(route) // å¨ææ·»å å¯è®¿é®è·¯ç±è¡¨ |
| | | } |
| | | }) |
| | | |
| | | // 妿æ¯é¦é¡µï¼èªå¨éå®åå°ç¬¬ä¸ä¸ªèå |
| | | if (to.path === '/' || to.path === '/index') { |
| | | const permissionStore = usePermissionStore() |
| | | const topMenus = permissionStore.topbarRouters.filter(menu => !menu.hidden) |
| | | if (topMenus.length > 0) { |
| | | // 跳转å°ç¬¬ä¸ä¸ªèå |
| | | const firstMenu = topMenus[0] |
| | | if (firstMenu.children && firstMenu.children.length > 0) { |
| | | // æåèåï¼è·³è½¬å°ç¬¬ä¸ä¸ªåèå |
| | | const firstChild = firstMenu.children[0] |
| | | const path = firstMenu.path.endsWith('/') ? firstMenu.path + firstChild.path : `${firstMenu.path}/${firstChild.path}` |
| | | next({ path: path, replace: true }) |
| | | return |
| | | } else { |
| | | // 没æåèåï¼ç´æ¥è·³è½¬ |
| | | next({ path: firstMenu.path, replace: true }) |
| | | return |
| | | } |
| | | } |
| | | } |
| | | |
| | | next({ ...to, replace: true }) // hackæ¹æ³ ç¡®ä¿addRoutes已宿 |
| | | }) |
| | | }).catch(err => { |
| | |
| | | }) |
| | | }) |
| | | } else { |
| | | // 妿æ¯é¦é¡µï¼èªå¨éå®åå°ç¬¬ä¸ä¸ªèå |
| | | if (to.path === '/' || to.path === '/index') { |
| | | const permissionStore = usePermissionStore() |
| | | const topMenus = permissionStore.topbarRouters.filter(menu => !menu.hidden) |
| | | if (topMenus.length > 0) { |
| | | // 跳转å°ç¬¬ä¸ä¸ªèå |
| | | const firstMenu = topMenus[0] |
| | | if (firstMenu.children && firstMenu.children.length > 0) { |
| | | // æåèåï¼è·³è½¬å°ç¬¬ä¸ä¸ªåèå |
| | | const firstChild = firstMenu.children[0] |
| | | const path = firstMenu.path.endsWith('/') ? firstMenu.path + firstChild.path : `${firstMenu.path}/${firstChild.path}` |
| | | next({ path: path, replace: true }) |
| | | return |
| | | } else { |
| | | // 没æåèåï¼ç´æ¥è·³è½¬ |
| | | next({ path: firstMenu.path, replace: true }) |
| | | return |
| | | } |
| | | } |
| | | } |
| | | next() |
| | | } |
| | | } |
| | |
| | | |
| | | router.afterEach(() => { |
| | | NProgress.done() |
| | | |
| | | // ç§»é¤ææå¯è½çé¦é¡µæ ç¾ |
| | | const tagsViewStore = useTagsViewStore(); |
| | | if (tagsViewStore && tagsViewStore.visitedViews) { |
| | | tagsViewStore.visitedViews = tagsViewStore.visitedViews.filter( |
| | | tag => tag.path !== '/index' && tag.path !== '/' && tag.name !== 'Index' |
| | | ); |
| | | } |
| | | }) |
| | |
| | | import { createWebHistory, createRouter } from 'vue-router' |
| | | /* Layout */ |
| | | import Layout from '@/layout' |
| | | import useAppStore from '@/store/modules/app' |
| | | |
| | | /** |
| | | * Note: è·¯ç±é
置项 |
| | |
| | | path: '/index', |
| | | component: () => import('@/views/index'), |
| | | name: 'Index', |
| | | meta: { title: 'é¦é¡µ', icon: 'dashboard', affix: true } |
| | | meta: { title: 'é¦é¡µ', icon: 'dashboard', affix: true, showSidebar: true, breadcrumb: false }, |
| | | beforeEnter: (to, from, next) => { |
| | | // è·åapp store并设置侧边æ 为æå ç¶æ |
| | | const appStore = useAppStore() |
| | | appStore.showCollapsedSidebar() |
| | | next() |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | |
| | | sidebar: { |
| | | opened: sessionStorage.getItem('sidebarStatus') ? !!+sessionStorage.getItem('sidebarStatus') : true, |
| | | withoutAnimation: false, |
| | | hide: false |
| | | hide: sessionStorage.getItem('sidebarHide') ? JSON.parse(sessionStorage.getItem('sidebarHide')) : false |
| | | }, |
| | | device: 'desktop', |
| | | size: sessionStorage.getItem('size') || 'default' |
| | |
| | | }, |
| | | toggleSideBarHide(status) { |
| | | this.sidebar.hide = status |
| | | sessionStorage.setItem('sidebarHide', status) |
| | | }, |
| | | openMenu() { |
| | | this.sidebar.hide = false |
| | | this.sidebar.opened = true |
| | | sessionStorage.setItem('sidebarHide', 'false') |
| | | sessionStorage.setItem('sidebarStatus', 1) |
| | | }, |
| | | showCollapsedSidebar() { |
| | | this.sidebar.hide = false |
| | | this.sidebar.opened = false |
| | | this.sidebar.withoutAnimation = false |
| | | sessionStorage.setItem('sidebarHide', 'false') |
| | | sessionStorage.setItem('sidebarStatus', 0) |
| | | } |
| | | } |
| | | }) |
| | |
| | | route.component = loadView(route.component) |
| | | } |
| | | } |
| | | // å¤ç query åæ°ï¼å°å符串转æ¢ä¸ºå¯¹è±¡ |
| | | if (route.query && typeof route.query === 'string') { |
| | | try { |
| | | route.query = JSON.parse(route.query); |
| | | } catch (error) { |
| | | console.error('Error parsing query string:', route.query, error); |
| | | } |
| | | } |
| | | if (route.children != null && route.children && route.children.length) { |
| | | route.children = filterAsyncRouter(route.children, route, type) |
| | | } else { |
| | |
| | | // ä¿®æ¹å¸å±è®¾ç½® |
| | | changeSetting(data) { |
| | | const { key, value } = data |
| | | if (this.hasOwnProperty(key)) { |
| | | if (key in this.$state) { |
| | | this[key] = value |
| | | } |
| | | }, |
| | |
| | | ) |
| | | }, |
| | | addVisitedView(view) { |
| | | // è¿æ»¤é¦é¡µæ ç¾ |
| | | if (view.path === '/index' || view.path === '/' || view.name === 'Index') { |
| | | return; |
| | | } |
| | | |
| | | if (this.visitedViews.some(v => v.path === view.path)) return |
| | | this.visitedViews.push( |
| | | Object.assign({}, view, { |
| | |
| | | }, |
| | | delAllVisitedViews(view) { |
| | | return new Promise(resolve => { |
| | | const affixTags = this.visitedViews.filter(tag => tag.meta.affix) |
| | | // è¿æ»¤æé¦é¡µæ ç¾ï¼åªä¿çå
¶ä»åºå®æ ç¾ |
| | | const affixTags = this.visitedViews.filter(tag => tag.meta.affix && tag.path !== '/index' && tag.path !== '/' && tag.name !== 'Index') |
| | | this.visitedViews = affixTags |
| | | this.iframeViews = [] |
| | | resolve([...this.visitedViews]) |
| | |
| | | <template> |
| | | <div class="page"> |
| | | <div class="page-title"> |
| | | <div class="title-bar"> |
| | | <span class="title-text">ç½å
³ç¶æçæµ</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table-box"> |
| | | <div class="border"> |
| | | <div class="table" v-for="(item, index) in dataList" :key="index"> |
| | |
| | | ]) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/styles/page.scss"; |
| | | |
| | | .page { |
| | | background: #08234F; |
| | | min-height: calc(100vh - 145px) |
| | | } |
| | | |
| | | .page-title { |
| | | position: relative; |
| | | |
| | | .title-bar { |
| | | position: relative; |
| | | padding: 14px 0; |
| | | padding-left: 16px; |
| | | |
| | | .title-text { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | position: relative; |
| | | padding-left: 22px; |
| | | color: #fff; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 5px; |
| | | height: 18px; |
| | | background-color: #3883FA; |
| | | border-radius: 2px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | bottom: -4px; |
| | | opacity: 0.12; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 1px; |
| | | background-color: #E6E6E6; |
| | | } |
| | | } |
| | | |
| | | .themeDark { |
| | | .border { |
| | | border: 1px solid #fff; |
| | | color: #fff; |
| | | |
| | | .table { |
| | | margin-top: 10px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: flex-start; |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-box { |
| | | margin: 20px 25px; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-box { |
| | | margin: 10px 25px; |
| | | } |
| | | } |
| | | |
| | | .page { |
| | | .table-box { |
| | | // ... ä¿æç°ææ ·å¼ |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/styles/page.scss"; |
| | | |
| | | .page { |
| | | background-color: #08234F; |
| | | } |
| | | |
| | | .themeDark { |
| | | .card-list { |
| | | width: 100%; |
| | |
| | | </template> |
| | | |
| | | <script setup name="equipment"> |
| | | import { listRegion, listDepartment } from "@/api/energyAnalysis/energyAnalysis" |
| | | import { listDepartment } from "@/api/energyAnalysis/energyAnalysis" |
| | | import { listEnergyTypeList } from "@/api/modelConfiguration/energyType" |
| | | import * as echarts from "echarts" |
| | | import request from "@/utils/request" |
| | | const { proxy } = getCurrentInstance() |
| | | const { period } = proxy.useDict("period") |
| | | import { useRoute } from "vue-router" |
| | |
| | | // } |
| | | const myChart1 = echarts.init(document.getElementById("Chart1")) |
| | | // const myChart2 = echarts.init(document.getElementById("Chart2")); |
| | | listRegion( |
| | | proxy.addDateRange({ |
| | | |
| | | // ä¿®æ¹ä¸ºç´æ¥è°ç¨consumptionanalysis/getByAreaæ¥å£ |
| | | request({ |
| | | url: "/consumptionanalysis/getByArea", |
| | | method: "get", |
| | | params: proxy.addDateRange({ |
| | | ...queryParams.value, |
| | | ...query.value, |
| | | }) |
| | | ).then((res) => { |
| | | }).then((res) => { |
| | | if (!!res.code && res.code == 200) { |
| | | loading.value = false |
| | | let xdata = [] |
| | |
| | | // è½è对æ¯åæ-设å¤è½èåæ-å¯¼åº |
| | | function handleExport() { |
| | | proxy.download( |
| | | "consumptionanalysis/energyExport", |
| | | "consumptionanalysis/getByArea/export", |
| | | { |
| | | ...queryParams.value, |
| | | ...query.value, |
| | |
| | | <template> |
| | | <div class="page" style="padding-left: 8px; padding-top: 8px"> |
| | | <CardHeader :showBtn="true" :active="'0'" :period="period" @handleClick="handleTimeType"> |
| | | <span> |
| | | <span class="card-header-title"> |
| | | å
¨åè½èç»è®¡ |
| | | <el-button @click="dialogVisible = true" v-if="list.length > 1"> æ¥çæ´å¤ </el-button> |
| | | <el-button @click="dialogVisible = true" v-if="list.length > 1" type="primary" size="small" class="header-more-btn"> æ¥çæ´å¤ </el-button> |
| | | </span> |
| | | </CardHeader> |
| | | <template v-for="(row, rowIndex) in list" :key="rowIndex" v-loading="loading02"> |
| | | <div class="card-list" v-if="settingsStore.sideTheme == 'theme-dark' && rowIndex == 0"> |
| | | <template v-for="(item, index) in row" :key="index"> |
| | | <div |
| | | class="card-list-item" |
| | | <div class="card-list-item"> |
| | | <div class="item-left"> |
| | | <div class="top-icon" |
| | | :style="{ |
| | | backgroundImage: 'url(' + bgList[index].bg + ')', |
| | | backgroundImage: 'url(' + bgList[index].icon + ')', |
| | | backgroundColor: bgList[index].iconBg, |
| | | width: '73px', |
| | | height: '73px', |
| | | backgroundSize: '40px' |
| | | }" |
| | | > |
| | | <div class="item-top"> |
| | | <div class="top-icon" :style="{ backgroundImage: 'url(' + bgList[index].icon + ')' }" /> |
| | | /> |
| | | </div> |
| | | <div class="item-right"> |
| | | <div class="top-right"> |
| | | <div class="right-name"> |
| | | {{ item.energyName }} |
| | |
| | | </div> |
| | | <div class="right-value"> |
| | | <span> {{ item.count }}</span> |
| | | <!-- <span class="unit">{{ item.energyUnit }}</span> --> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="item-bottom"> |
| | | <div class="bottom-left"> |
| | | <span> |
| | | 忝: {{ Math.abs(item.tongbi) }} |
| | | <el-icon :color="item.tongbi > 0 ? 'green' : item.tongbi < 0 ? 'red' : ''"> |
| | | 忝: {{ Math.abs(item.tongbi).toFixed(1) }} |
| | | <el-icon :color="item.tongbi > 0 ? '#4CAF50' : item.tongbi < 0 ? '#F44336' : ''"> |
| | | <Top v-if="item.tongbi > 0" /> |
| | | <Bottom v-if="item.tongbi < 0" /> |
| | | </el-icon> |
| | | </span> |
| | | </div> |
| | | <div class="bottom-right"> |
| | | <span |
| | | >ç¯æ¯: {{ Math.abs(item.huanbi) }} |
| | | <el-icon :color="item.huanbi > 0 ? 'green' : item.huanbi < 0 ? 'red' : ''"> |
| | | <span> |
| | | ç¯æ¯: {{ Math.abs(item.huanbi).toFixed(1) }} |
| | | <el-icon :color="item.huanbi > 0 ? '#4CAF50' : item.huanbi < 0 ? '#F44336' : ''"> |
| | | <Top v-if="item.huanbi > 0" /> |
| | | <Bottom v-if="item.huanbi < 0" /> |
| | | </el-icon> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="card-list" v-if="settingsStore.sideTheme != 'theme-dark' && rowIndex == 0"> |
| | | <template v-for="(item, index) in row" :key="index" v-show="rowIndex == 0"> |
| | | <div class="card-list-item"> |
| | | <div class="item-top"> |
| | | <div class="top-icon" :style="{ backgroundImage: 'url(' + bgList[index].icon2 + ')' }" /> |
| | | <div class="item-left"> |
| | | <div class="top-icon" |
| | | :style="{ |
| | | backgroundImage: 'url(' + bgList[index].icon2 + ')', |
| | | backgroundColor: bgList[index].iconBg, |
| | | width: '73px', |
| | | height: '73px', |
| | | backgroundSize: '40px' |
| | | }" |
| | | /> |
| | | </div> |
| | | <div class="item-right"> |
| | | <div class="top-right"> |
| | | <div class="right-name"> |
| | | {{ item.energyName }} |
| | | <span v-if="item.energyUnit" class="unit">({{ item.energyUnit }})</span> |
| | | </div> |
| | | <div class="right-value"> |
| | | <span>{{ item.count }}</span> |
| | | <span class="unit">{{ item.energyUnit }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="item-bottom"> |
| | | <div class="bottom-left"> |
| | | <span> |
| | | 忝: {{ Math.abs(item.tongbi) }} |
| | | <el-icon :color="item.tongbi > 0 ? 'green' : item.tongbi < 0 ? 'red' : ''"> |
| | | 忝: {{ Math.abs(item.tongbi).toFixed(1) }} |
| | | <el-icon :color="item.tongbi > 0 ? '#4CAF50' : item.tongbi < 0 ? '#F44336' : ''"> |
| | | <Top v-if="item.tongbi > 0" /> |
| | | <Bottom v-if="item.tongbi < 0" /> |
| | | </el-icon> |
| | | </span> |
| | | </div> |
| | | <div class="bottom-right"> |
| | | <span |
| | | >ç¯æ¯: {{ Math.abs(item.huanbi) }} |
| | | <el-icon :color="item.huanbi > 0 ? 'green' : item.huanbi < 0 ? 'red' : ''"> |
| | | <span> |
| | | ç¯æ¯: {{ Math.abs(item.huanbi).toFixed(1) }} |
| | | <el-icon :color="item.huanbi > 0 ? '#4CAF50' : item.huanbi < 0 ? '#F44336' : ''"> |
| | | <Top v-if="item.huanbi > 0" /> |
| | | <Bottom v-if="item.huanbi < 0" /> |
| | | </el-icon> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <el-dialog v-model="dialogVisible" title="æ¥çå
¨åè½èç»è®¡" width="80%" v-if="dialogVisible"> |
| | | <el-dialog v-model="dialogVisible" title="æ¥çå
¨åè½èç»è®¡" width="90%" v-if="dialogVisible"> |
| | | <template v-for="(row, rowIndex) in list" :key="rowIndex"> |
| | | <div class="card-list" v-if="settingsStore.sideTheme == 'theme-dark'"> |
| | | <template v-for="(item, index) in row" :key="index"> |
| | | <div |
| | | class="card-list-item" |
| | | :style="{ |
| | | backgroundImage: 'url(' + bgList[index].bg + ')', |
| | | }" |
| | | > |
| | | <div class="item-top"> |
| | | <div |
| | | class="top-icon" |
| | | <div class="card-list-item"> |
| | | <div class="item-left"> |
| | | <div class="top-icon" |
| | | :style="{ |
| | | backgroundImage: 'url(' + bgList[index].icon + ')', |
| | | backgroundColor: bgList[index].iconBg, |
| | | width: '73px', |
| | | height: '73px', |
| | | backgroundSize: '40px' |
| | | }" |
| | | /> |
| | | </div> |
| | | <div class="item-right"> |
| | | <div class="top-right"> |
| | | <div class="right-name"> |
| | | {{ item.energyName }} |
| | | <span v-if="item.energyUnit" class="unit">({{ item.energyUnit }})</span> |
| | | </div> |
| | | <div class="right-value"> |
| | | <span> {{ item.count }}</span> |
| | | <span class="unit">{{ item.energyUnit }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="item-bottom"> |
| | | <div class="bottom-left"> |
| | | <span> |
| | | 忝: {{ Math.abs(item.tongbi) }} |
| | | <el-icon :color="item.tongbi > 0 ? 'green' : item.tongbi < 0 ? 'red' : ''"> |
| | | 忝: {{ Math.abs(item.tongbi).toFixed(1) }} |
| | | <el-icon :color="item.tongbi > 0 ? '#4CAF50' : item.tongbi < 0 ? '#F44336' : ''"> |
| | | <Top v-if="item.tongbi > 0" /> |
| | | <Bottom v-if="item.tongbi < 0" /> |
| | | </el-icon> |
| | | </span> |
| | | </div> |
| | | <div class="bottom-right"> |
| | | <span |
| | | >ç¯æ¯: {{ Math.abs(item.huanbi) }} |
| | | <el-icon :color="item.huanbi > 0 ? 'green' : item.huanbi < 0 ? 'red' : ''"> |
| | | <span> |
| | | ç¯æ¯: {{ Math.abs(item.huanbi).toFixed(1) }} |
| | | <el-icon :color="item.huanbi > 0 ? '#4CAF50' : item.huanbi < 0 ? '#F44336' : ''"> |
| | | <Top v-if="item.huanbi > 0" /> |
| | | <Bottom v-if="item.huanbi < 0" /> |
| | | </el-icon> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | <div class="card-list" v-if="settingsStore.sideTheme != 'theme-dark'"> |
| | | <template v-for="(item, index) in row" :key="index" v-show="rowIndex == 0"> |
| | | <template v-for="(item, index) in row" :key="index"> |
| | | <div class="card-list-item"> |
| | | <div class="item-top"> |
| | | <div |
| | | class="top-icon" |
| | | <div class="item-left"> |
| | | <div class="top-icon" |
| | | :style="{ |
| | | backgroundImage: 'url(' + bgList[index].icon2 + ')', |
| | | backgroundColor: bgList[index].iconBg, |
| | | width: '73px', |
| | | height: '73px', |
| | | backgroundSize: '40px' |
| | | }" |
| | | /> |
| | | </div> |
| | | <div class="item-right"> |
| | | <div class="top-right"> |
| | | <div class="right-name"> |
| | | {{ item.energyName }} |
| | |
| | | <span class="unit">{{ item.energyUnit }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="item-bottom"> |
| | | <div class="bottom-left"> |
| | | <span> |
| | | 忝: {{ Math.abs(item.tongbi) }} |
| | | <el-icon :color="item.tongbi > 0 ? 'green' : item.tongbi < 0 ? 'red' : ''"> |
| | | 忝: {{ Math.abs(item.tongbi).toFixed(1) }} |
| | | <el-icon :color="item.tongbi > 0 ? '#4CAF50' : item.tongbi < 0 ? '#F44336' : ''"> |
| | | <Top v-if="item.tongbi > 0" /> |
| | | <Bottom v-if="item.tongbi < 0" /> |
| | | </el-icon> |
| | | </span> |
| | | </div> |
| | | <div class="bottom-right"> |
| | | <span |
| | | >ç¯æ¯: {{ Math.abs(item.huanbi) }} |
| | | <el-icon :color="item.huanbi > 0 ? 'green' : item.huanbi < 0 ? 'red' : ''"> |
| | | <span> |
| | | ç¯æ¯: {{ Math.abs(item.huanbi).toFixed(1) }} |
| | | <el-icon :color="item.huanbi > 0 ? '#4CAF50' : item.huanbi < 0 ? '#F44336' : ''"> |
| | | <Top v-if="item.huanbi > 0" /> |
| | | <Bottom v-if="item.huanbi < 0" /> |
| | | </el-icon> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="line"></div> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | </template> |
| | |
| | | import index_card_3 from "@/assets/images/home/index-card-3.png" |
| | | import index_card_4 from "@/assets/images/home/index-card-4.png" |
| | | import index_card_5 from "@/assets/images/home/index-card-5.png" |
| | | import card_icon_1 from "@/assets/images/home/card-icon-1.png" |
| | | import card_icon_2 from "@/assets/images/home/card-icon-2.png" |
| | | import card_icon_3 from "@/assets/images/home/card-icon-3.png" |
| | | import card_icon_4 from "@/assets/images/home/card-icon-4.png" |
| | | import card_icon_5 from "@/assets/images/home/card-icon-5.png" |
| | | import card_icon2_1 from "@/assets/images/home/card-icon2-1.png" |
| | | import card_icon2_2 from "@/assets/images/home/card-icon2-2.png" |
| | | import card_icon2_3 from "@/assets/images/home/card-icon2-3.png" |
| | | import card_icon2_4 from "@/assets/images/home/card-icon2-4.png" |
| | | import card_icon2_5 from "@/assets/images/home/card-icon2-5.png" |
| | | import card_icon_1 from "@/assets/images/2.png" |
| | | import card_icon_2 from "@/assets/images/3.png" |
| | | import card_icon_3 from "@/assets/images/5.png" |
| | | import card_icon_4 from "@/assets/images/6.png" |
| | | import card_icon_5 from "@/assets/images/7.png" |
| | | import card_icon2_1 from "@/assets/images/2.png" |
| | | import card_icon2_2 from "@/assets/images/3.png" |
| | | import card_icon2_3 from "@/assets/images/5.png" |
| | | import card_icon2_4 from "@/assets/images/6.png" |
| | | import card_icon2_5 from "@/assets/images/7.png" |
| | | import { fa } from "element-plus/es/locales.mjs" |
| | | const bgList = ref([ |
| | | { |
| | | bg: index_card_1, |
| | | icon: card_icon_1, |
| | | icon2: card_icon2_1, |
| | | iconBg: "#3F7EE8" |
| | | }, |
| | | { |
| | | bg: index_card_2, |
| | | icon: card_icon_2, |
| | | icon2: card_icon2_2, |
| | | iconBg: "#FFA024" |
| | | }, |
| | | { |
| | | bg: index_card_3, |
| | | icon: card_icon_3, |
| | | icon2: card_icon2_3, |
| | | iconBg: "#FFCC00" |
| | | }, |
| | | { |
| | | bg: index_card_4, |
| | | icon: card_icon_4, |
| | | icon2: card_icon2_4, |
| | | iconBg: "#3CC8D9" |
| | | }, |
| | | { |
| | | bg: index_card_5, |
| | | icon: card_icon_5, |
| | | icon2: card_icon2_5, |
| | | iconBg: "#8833FF" |
| | | }, |
| | | ]) |
| | | const list = ref([[{}, {}, {}, {}, {}]]) |
| | |
| | | } |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | .card-header-title { |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .header-more-btn { |
| | | margin-left: 12px; |
| | | padding: 4px 10px; |
| | | font-size: 12px; |
| | | height: 28px; |
| | | } |
| | | } |
| | | |
| | | .themeDark { |
| | | .page { |
| | | padding: 20px; |
| | | background: #120f2e; |
| | | background: #05234A; |
| | | |
| | | .card-title { |
| | | width: 132px; |
| | |
| | | .card-list { |
| | | margin-top: 14px; |
| | | display: flex; |
| | | // justify-content: space-between; |
| | | width: 100%; |
| | | flex-wrap: wrap; |
| | | justify-content: space-between; |
| | | gap: 15px; |
| | | |
| | | .card-list-item { |
| | | width: 19%; |
| | | margin-right: 1%; |
| | | height: 157px; |
| | | background-size: 100% 100%; |
| | | box-sizing: border-box; |
| | | padding: 25px 18px 12px 16px; |
| | | color: #fff; |
| | | |
| | | .item-top { |
| | | display: flex; |
| | | |
| | | .top-icon { |
| | | width: 50px; |
| | | height: 50px; |
| | | background-size: 100% 100%; |
| | | &:after { |
| | | content: ""; |
| | | flex: auto; |
| | | } |
| | | |
| | | .card-list-item { |
| | | width: 320px; |
| | | height: 127px; |
| | | background: rgba(242, 246, 250, 0.1); |
| | | box-sizing: border-box; |
| | | padding: 16px; |
| | | color: #fff; |
| | | border-radius: 9px; |
| | | box-shadow: none; |
| | | border: none; |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | |
| | | &:hover { |
| | | background: rgba(242, 246, 250, 0.15); |
| | | } |
| | | |
| | | .item-left { |
| | | margin-right: 16px; |
| | | |
| | | .top-icon { |
| | | width: 73px; |
| | | height: 73px; |
| | | background-size: 40px; |
| | | background-repeat: no-repeat; |
| | | background-position: center; |
| | | border-radius: 50%; |
| | | } |
| | | } |
| | | |
| | | .item-right { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .top-right { |
| | | margin-left: 12px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .right-name { |
| | | font-weight: bold; |
| | | font-size: 16px; |
| | | font-family: OPPOSans-Bold; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | font-family: OPPOSans-Regular; |
| | | color: rgba(255, 255, 255, 0.65); |
| | | .unit { |
| | | color: rgba(255, 255, 255, 0.65); |
| | | margin-left: 2px; |
| | | font-size: 16px; |
| | | font-size: 12px; |
| | | font-weight: normal; |
| | | } |
| | | } |
| | | |
| | | .right-value { |
| | | font-weight: 800; |
| | | font-size: 25px; |
| | | margin-top: 10px; |
| | | font-weight: 500; |
| | | font-size: 26px; |
| | | margin-top: 4px; |
| | | font-family: OPPOSans-Medium; |
| | | |
| | | .unit { |
| | | margin-left: 5px; |
| | | font-size: 16px; |
| | | font-weight: normal; |
| | | } |
| | | } |
| | | color: #fff; |
| | | line-height: 1; |
| | | } |
| | | } |
| | | |
| | | .item-bottom { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-top: 18px; |
| | | margin-top: 14px; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | font-weight: normal; |
| | | font-size: 12px; |
| | | color: rgba(255, 255, 255, 0.5); |
| | | line-height: 1; |
| | | |
| | | .bottom-left, .bottom-right { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | :deep(.el-icon) { |
| | | margin-left: 4px; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .page-main { |
| | | margin-top: 23px; |
| | | } |
| | | } |
| | | margin-top: 20px; |
| | | |
| | | .chart { |
| | | width: 100%; |
| | | height: 292px; |
| | | margin-top: 10px; |
| | | .el-card { |
| | | background-color: #0E2E5E; |
| | | border: none; |
| | | border-radius: 6px; |
| | | |
| | | :deep(.el-card__body) { |
| | | padding: 12px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .top-header { |
| | | margin-top: 15px; |
| | | height: 23px; |
| | | margin-top: 12px; |
| | | height: 32px; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 14px; |
| | | color: rgba(196, 213, 255, 0.6); |
| | | border-bottom: 1px solid rgba(196, 213, 255, 0.6); |
| | | color: rgba(255, 255, 255, 0.8); |
| | | border-bottom: 1px solid rgba(255, 255, 255, 0.2); |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 0 10px; |
| | | |
| | | .header-left { |
| | | display: flex; |
| | |
| | | margin-right: 7px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .chart { |
| | | width: 100%; |
| | | height: 292px; |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | :deep(.el-button--primary) { |
| | | background-color: #1976D2; |
| | | border-color: #1976D2; |
| | | } |
| | | |
| | | :deep(.el-card__header) { |
| | | padding: 10px 15px; |
| | | border-bottom: 1px solid rgba(255, 255, 255, 0.1); |
| | | } |
| | | |
| | | :deep(.el-tabs--card > .el-tabs__header .el-tabs__item) { |
| | | border-color: rgba(255, 255, 255, 0.1); |
| | | background-color: transparent; |
| | | color: #fff; |
| | | |
| | | &.is-active { |
| | | background-color: #1976D2; |
| | | border-color: #1976D2; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-tabs--card > .el-tabs__header) { |
| | | border-color: rgba(255, 255, 255, 0.1); |
| | | } |
| | | } |
| | | |
| | |
| | | height: 29px; |
| | | font-weight: bold; |
| | | font-size: 22px; |
| | | color: #ffffff; |
| | | color: #333; |
| | | } |
| | | |
| | | .card-list { |
| | | width: 100%; |
| | | margin-top: 14px; |
| | | display: flex; |
| | | // justify-content: space-between; |
| | | align-items: center; |
| | | background-image: url("@/assets/images/home/index-card-bg2.png"); |
| | | background-size: 100% 100%; |
| | | width: 100%; |
| | | flex-wrap: wrap; |
| | | border-radius: 20px; |
| | | justify-content: space-between; |
| | | gap: 15px; |
| | | |
| | | &:after { |
| | | content: ""; |
| | | flex: auto; |
| | | } |
| | | |
| | | .card-list-item { |
| | | width: 19%; |
| | | margin-right: 0.5%; |
| | | height: 157px; |
| | | background-size: 100% 100%; |
| | | width: 320px; |
| | | height: 127px; |
| | | background: #fff; |
| | | box-sizing: border-box; |
| | | padding: 25px 18px 12px 16px; |
| | | color: #fff; |
| | | |
| | | .item-top { |
| | | padding: 16px; |
| | | color: #333; |
| | | border-radius: 9px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05); |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | |
| | | .item-left { |
| | | margin-right: 16px; |
| | | |
| | | .top-icon { |
| | | width: 69px; |
| | | height: 69px; |
| | | background-size: 100% 100%; |
| | | width: 73px; |
| | | height: 73px; |
| | | background-size: 40px; |
| | | background-repeat: no-repeat; |
| | | background-position: center; |
| | | border-radius: 50%; |
| | | } |
| | | } |
| | | |
| | | .item-right { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .top-right { |
| | | margin-left: 16px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .right-name { |
| | | font-weight: bold; |
| | | font-size: 16px; |
| | | font-family: OPPOSans-Bold; |
| | | } |
| | | |
| | | .right-value { |
| | | font-weight: 800; |
| | | font-size: 30px; |
| | | margin-top: 10px; |
| | | font-family: OPPOSans-Medium; |
| | | |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | font-family: OPPOSans-Regular; |
| | | color: rgba(0, 0, 0, 0.65); |
| | | .unit { |
| | | margin-left: 5px; |
| | | font-size: 16px; |
| | | color: rgba(0, 0, 0, 0.65); |
| | | margin-left: 2px; |
| | | font-size: 12px; |
| | | font-weight: normal; |
| | | } |
| | | } |
| | | |
| | | .right-value { |
| | | font-weight: 500; |
| | | font-size: 26px; |
| | | margin-top: 4px; |
| | | font-family: OPPOSans-Medium; |
| | | color: #333; |
| | | line-height: 1; |
| | | } |
| | | } |
| | | |
| | | .item-bottom { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-top: 18px; |
| | | margin-top: 14px; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | font-weight: normal; |
| | | font-size: 12px; |
| | | color: rgba(0, 0, 0, 0.5); |
| | | line-height: 1; |
| | | |
| | | .line { |
| | | width: 1px; |
| | | height: 64px; |
| | | background-image: url("@/assets/images/home/line@2x.png"); |
| | | background-size: 100% 100%; |
| | | .bottom-left, .bottom-right { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | :deep(.el-icon) { |
| | | margin-left: 4px; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .page-main { |
| | | margin-top: 23px; |
| | | } |
| | | } |
| | | margin-top: 20px; |
| | | |
| | | .chart { |
| | | width: 100%; |
| | | height: 292px; |
| | | margin-top: 10px; |
| | | .el-card { |
| | | background-color: #fff; |
| | | border: none; |
| | | border-radius: 6px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05); |
| | | |
| | | :deep(.el-card__body) { |
| | | padding: 12px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .top-header { |
| | | margin-top: 15px; |
| | | height: 23px; |
| | | margin-top: 12px; |
| | | height: 32px; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 14px; |
| | | color: rgba(29, 29, 29, 0.6); |
| | | border-bottom: 1px solid rgba(196, 213, 255, 0.6); |
| | | color: rgba(0, 0, 0, 0.6); |
| | | border-bottom: 1px solid rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 0 10px; |
| | | |
| | | .header-left { |
| | | display: flex; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .chart { |
| | | width: 100%; |
| | | height: 292px; |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | :deep(.el-button--primary) { |
| | | background-color: #1976D2; |
| | | border-color: #1976D2; |
| | | } |
| | | |
| | | :deep(.el-card__header) { |
| | | padding: 10px 15px; |
| | | border-bottom: 1px solid rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | :deep(.el-tabs--card > .el-tabs__header .el-tabs__item) { |
| | | border-color: rgba(0, 0, 0, 0.1); |
| | | |
| | | &.is-active { |
| | | background-color: #1976D2; |
| | | border-color: #1976D2; |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-tabs--card > .el-tabs__header) { |
| | | border-color: rgba(0, 0, 0, 0.1); |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="page"> |
| | | <!-- æ·»å æ 颿 --> |
| | | <div class="page-title"> |
| | | <div class="title-bar"> |
| | | <span class="title-text">ç½å
³ç¶æçæµ</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table-box"> |
| | | <div class="border"> |
| | | <div class="table" v-for="(item, index) in dataList" :key="index"> |
| | | <div class="num"> |
| | | <div class="li name">{{ item.name }}</div> |
| | | <div class="firstLi"> |
| | | <div :class="item.list.length < 16 ? 'li hasRightLine' : 'li'" v-for="(i, inde) in item.list" :key="inde"> |
| | | <div class="title_num" v-if="i.title_num">{{ i.title_num }}</div> |
| | | <div class="dot" v-if="i.dot && i.dot.length > 0"> |
| | | <div class="dot_li" v-for="(j, ind) in 3" :key="ind"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | let dataList = ref([ |
| | | { |
| | | name: "ç½å
³", |
| | | list: [ |
| | | { |
| | | id: 1, |
| | | title_num: "æ°æ®åº", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 2, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 3, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 4, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 5, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 6, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 7, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 8, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 9, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 10, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 11, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 12, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 13, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 14, |
| | | title_num: "200461", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 15, |
| | | title_num: "200475", |
| | | dot: [], |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | name: "计ç®å¨å
·", |
| | | list: [ |
| | | { |
| | | id: 1, |
| | | title_num: "", |
| | | dot: [ |
| | | { |
| | | id: "001", |
| | | dot_li: "", |
| | | }, |
| | | { |
| | | id: "002", |
| | | dot_li: "", |
| | | }, |
| | | { |
| | | id: "003", |
| | | dot_li: "", |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: 2, |
| | | title_num: "", |
| | | dot: [ |
| | | { |
| | | id: "001", |
| | | dot_li: "", |
| | | }, |
| | | { |
| | | id: "002", |
| | | dot_li: "", |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: 3, |
| | | title_num: "", |
| | | dot: [ |
| | | { |
| | | id: "001", |
| | | dot_li: "", |
| | | }, |
| | | { |
| | | id: "002", |
| | | dot_li: "", |
| | | }, |
| | | { |
| | | id: "003", |
| | | dot_li: "", |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | name: "ç½å
³", |
| | | list: [ |
| | | { |
| | | id: 1, |
| | | title_num: "æ°æ®åº", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 2, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 3, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | { |
| | | id: 4, |
| | | title_num: "200311", |
| | | dot: [], |
| | | }, |
| | | ], |
| | | } |
| | | ]) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/styles/page.scss"; |
| | | |
| | | .page { |
| | | background: #08234F; |
| | | } |
| | | |
| | | // æ 颿 ·å¼ |
| | | .page-title { |
| | | margin: 0 16px 16px; |
| | | position: relative; |
| | | |
| | | .title-bar { |
| | | position: relative; |
| | | padding: 14px 0; |
| | | padding-left: 16px; |
| | | |
| | | .title-text { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | position: relative; |
| | | padding-left: 12px; |
| | | color: #fff; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 5px; |
| | | height: 18px; |
| | | background-color: #3883FA; |
| | | border-radius: 2px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | bottom: -10px; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 1px; |
| | | background-color: #E6E6E6; |
| | | } |
| | | } |
| | | |
| | | .themeDark { |
| | | .table-box { |
| | | margin: 10px 25px; |
| | | .border { |
| | | border: 1px solid #22408c; |
| | | border-radius: 8px; |
| | | background: #1a235d; |
| | | padding: 10px 0; |
| | | .table { |
| | | margin: 15px; |
| | | // border: 1px solid #22408c; |
| | | .num { |
| | | height: 56px; |
| | | display: flex; |
| | | } |
| | | .li { |
| | | height: 56px; |
| | | padding: 0 10px; |
| | | min-width: 60px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-evenly; |
| | | align-items: center; |
| | | border-top: 1px solid #22408c; |
| | | border-left: 1px solid #22408c; |
| | | border-bottom: 1px solid #22408c; |
| | | position: relative; |
| | | } |
| | | .hasRightLine { |
| | | border-right: 1px solid #22408c; |
| | | } |
| | | .name { |
| | | width: 80px; |
| | | background: #1a235d; |
| | | color: rgba(255, 255, 255, 0.8); |
| | | text-align: center; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | } |
| | | .title_num { |
| | | color: #eeeeee; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | } |
| | | .dot { |
| | | display: flex; |
| | | flex-direction: column; |
| | | // justify-content: space-evenly; |
| | | height: 30px; |
| | | width: 12px; |
| | | align-items: center; |
| | | } |
| | | .dot_li { |
| | | height: 8px; |
| | | width: 8px; |
| | | margin: 2px 0; |
| | | background: red; |
| | | border-radius: 50%; |
| | | } |
| | | .firstLi { |
| | | display: flex; |
| | | flex: 1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .themeLight { |
| | | .table-box { |
| | | margin: 10px 25px; |
| | | .border { |
| | | border: 1px solid #ebebeb; |
| | | border-radius: 8px; |
| | | background: #fff; |
| | | padding: 10px 0; |
| | | .table { |
| | | margin: 15px; |
| | | // border: 1px solid #22408c; |
| | | .num { |
| | | height: 56px; |
| | | display: flex; |
| | | } |
| | | .li { |
| | | height: 56px; |
| | | padding: 0 10px; |
| | | min-width: 60px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-evenly; |
| | | align-items: center; |
| | | border-top: 1px solid #ebebeb; |
| | | border-left: 1px solid #ebebeb; |
| | | border-bottom: 1px solid #ebebeb; |
| | | position: relative; |
| | | } |
| | | .hasRightLine { |
| | | border-right: 1px solid #ebebeb; |
| | | } |
| | | .name { |
| | | width: 80px; |
| | | background: #fff; |
| | | color: #0d0d0d; |
| | | text-align: center; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | } |
| | | .title_num { |
| | | color: #0d0d0d; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | } |
| | | .dot { |
| | | display: flex; |
| | | flex-direction: column; |
| | | // justify-content: space-evenly; |
| | | height: 30px; |
| | | width: 12px; |
| | | align-items: center; |
| | | } |
| | | .dot_li { |
| | | height: 8px; |
| | | width: 8px; |
| | | margin: 2px 0; |
| | | background: red; |
| | | border-radius: 50%; |
| | | } |
| | | .firstLi { |
| | | display: flex; |
| | | flex: 1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <div class="page"> |
| | | <div class="page-container"> |
| | | <div class="page-container-left"> |
| | | <LeftTree ref="leftTreeRef" @handleNodeClick="handleNodeClick" /> |
| | | <LeftTree ref="leftTreeRef" @handleNodeClick="handleNodeClick" ParentModelCode="YSCJMX" /> |
| | | </div> |
| | | <div class="page-container-right"> |
| | | <div class="form-card"> |
| | |
| | | text-align: left; |
| | | font-weight: bold; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | |
| | | font-size: 14px; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | |
| | | .title { |
| | | color: rgba(255, 255, 255, 0.8); |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | |
| | | font-size: 14px; |
| | | line-height: 19px; |
| | | text-align: left; |
| | | font-style: normal; |
| | |
| | | } |
| | | |
| | | .num { |
| | | font-size: 24px; |
| | | font-size: 26px; |
| | | color: #36d3ff; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 800; |
| | |
| | | text-align: center; |
| | | margin: 5px 8px; |
| | | border-radius: 8px; |
| | | padding: 7px 10px; |
| | | padding: 2px 6px; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | |
| | | } |
| | | |
| | | .num { |
| | | font-size: 24px; |
| | | font-size: 26px; |
| | | color: #3271eb; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 800; |
| | |
| | | text-align: center; |
| | | margin: 5px 8px; |
| | | border-radius: 8px; |
| | | padding: 7px 3px; |
| | | padding: 2px 6px; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | |
| | | text-align: center; |
| | | margin: 2px 6px; |
| | | border-radius: 8px; |
| | | padding: 5px 10px; |
| | | padding: 2px 6px; |
| | | font-family: OPPOSans, OPPOSans; |
| | | font-weight: 500; |
| | | font-size: 14px; |
| | |
| | | proxy: { |
| | | // https://cn.vitejs.dev/config/#server-proxy |
| | | "/dev-api": { |
| | | target: "http://localhost", |
| | | target: "https://demo-ems.zhitancloud.com", |
| | | changeOrigin: true, |
| | | rewrite: (p) => p.replace(/^\/dev-api/, ""), |
| | | rewrite: (p) => p.replace(/^\/dev-api/, "/prod-api"), |
| | | }, |
| | | "/prod-api": { |
| | | target: "https://demo-ems.zhitancloud.com", |
| | | changeOrigin: true, |
| | | secure: true, |
| | | } |
| | | }, |
| | | }, |
| | | //fix:error:stdin>:7356:1: warning: "@charset" must be the first rule in the file |