64 changed files with 26858 additions and 0 deletions
@ -0,0 +1,33 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<classpath> |
||||||
|
<classpathentry kind="src" output="target/classes" path="src/main/java"> |
||||||
|
<attributes> |
||||||
|
<attribute name="optional" value="true"/> |
||||||
|
<attribute name="maven.pomderived" value="true"/> |
||||||
|
</attributes> |
||||||
|
</classpathentry> |
||||||
|
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> |
||||||
|
<attributes> |
||||||
|
<attribute name="maven.pomderived" value="true"/> |
||||||
|
</attributes> |
||||||
|
</classpathentry> |
||||||
|
<classpathentry kind="src" output="target/test-classes" path="src/test/java"> |
||||||
|
<attributes> |
||||||
|
<attribute name="optional" value="true"/> |
||||||
|
<attribute name="maven.pomderived" value="true"/> |
||||||
|
<attribute name="test" value="true"/> |
||||||
|
</attributes> |
||||||
|
</classpathentry> |
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> |
||||||
|
<attributes> |
||||||
|
<attribute name="maven.pomderived" value="true"/> |
||||||
|
</attributes> |
||||||
|
</classpathentry> |
||||||
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> |
||||||
|
<attributes> |
||||||
|
<attribute name="maven.pomderived" value="true"/> |
||||||
|
</attributes> |
||||||
|
</classpathentry> |
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/> |
||||||
|
<classpathentry kind="output" path="target/classes"/> |
||||||
|
</classpath> |
@ -0,0 +1,23 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<projectDescription> |
||||||
|
<name>picture-bed</name> |
||||||
|
<comment></comment> |
||||||
|
<projects> |
||||||
|
</projects> |
||||||
|
<buildSpec> |
||||||
|
<buildCommand> |
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name> |
||||||
|
<arguments> |
||||||
|
</arguments> |
||||||
|
</buildCommand> |
||||||
|
<buildCommand> |
||||||
|
<name>org.eclipse.m2e.core.maven2Builder</name> |
||||||
|
<arguments> |
||||||
|
</arguments> |
||||||
|
</buildCommand> |
||||||
|
</buildSpec> |
||||||
|
<natures> |
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature> |
||||||
|
<nature>org.eclipse.m2e.core.maven2Nature</nature> |
||||||
|
</natures> |
||||||
|
</projectDescription> |
@ -0,0 +1,4 @@ |
|||||||
|
eclipse.preferences.version=1 |
||||||
|
encoding//src/main/java=UTF-8 |
||||||
|
encoding//src/main/resources=UTF-8 |
||||||
|
encoding/<project>=UTF-8 |
@ -0,0 +1,7 @@ |
|||||||
|
eclipse.preferences.version=1 |
||||||
|
org.eclipse.jdt.core.compiler.codegen.methodParameters=generate |
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 |
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.8 |
||||||
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning |
||||||
|
org.eclipse.jdt.core.compiler.release=disabled |
||||||
|
org.eclipse.jdt.core.compiler.source=1.8 |
@ -0,0 +1,4 @@ |
|||||||
|
activeProfiles= |
||||||
|
eclipse.preferences.version=1 |
||||||
|
resolveWorkspaceProjects=true |
||||||
|
version=1 |
@ -0,0 +1,14 @@ |
|||||||
|
server.port=80 |
||||||
|
server.servlet.context-path=/ |
||||||
|
version.num=1.0.0 |
||||||
|
|
||||||
|
# 程序自身数据源配置 |
||||||
|
spring.datasource.url=jdbc:mysql://localhost:3306/picture?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true |
||||||
|
spring.datasource.username=root |
||||||
|
spring.datasource.password=51131420 |
||||||
|
|
||||||
|
picture.root.path=E:/image |
||||||
|
|
||||||
|
timeout.login.token=1000000 |
||||||
|
spring.servlet.multipart.max-file-size=10MB |
||||||
|
spring.servlet.multipart.max-request-size=100MB |
@ -0,0 +1,23 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- Configuration后面的status,这个用于设置log4j2自身内部的信息输出 --> |
||||||
|
<!-- monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数。 --> |
||||||
|
<configuration status="error" monitorInterval="60"> |
||||||
|
|
||||||
|
<appenders> |
||||||
|
<!--控制台 --> |
||||||
|
<Console name="Console" target="SYSTEM_OUT"> |
||||||
|
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --> |
||||||
|
<ThresholdFilter level="debug" onMatch="ACCEPT" |
||||||
|
onMismatch="DENY" /> |
||||||
|
<!--输出日志的格式 --> |
||||||
|
<PatternLayout |
||||||
|
pattern="%d{HH:mm:ss.SSS} [%p] %class{36} %L %M - %msg%xEx%n" /> |
||||||
|
</Console> |
||||||
|
</appenders> |
||||||
|
<loggers> |
||||||
|
<logger name="vip.xumy" level="DEBUG"></logger> |
||||||
|
<root level="warn"> |
||||||
|
<appender-ref ref="Console" /> |
||||||
|
</root> |
||||||
|
</loggers> |
||||||
|
</configuration> |
@ -0,0 +1,78 @@ |
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-parent</artifactId> |
||||||
|
<version>2.0.2.RELEASE</version> |
||||||
|
</parent> |
||||||
|
<groupId>vip.xumy.picture</groupId> |
||||||
|
<artifactId>picture-bed</artifactId> |
||||||
|
<version>1.0.0</version> |
||||||
|
<name>picture-bed</name> |
||||||
|
|
||||||
|
<properties> |
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> |
||||||
|
<xumy.admin.version>1.2.0</xumy.admin.version> |
||||||
|
<log4j.version>1.2.17</log4j.version> |
||||||
|
<fastjson.version>1.2.46</fastjson.version> |
||||||
|
<mybatis-spring-boot.version>1.3.2</mybatis-spring-boot.version> |
||||||
|
<druid.version>1.1.9</druid.version> |
||||||
|
<mybatis.pagehelper.version>1.2.5</mybatis.pagehelper.version> |
||||||
|
<sqlitejdbc.version>0.5.6</sqlitejdbc.version> |
||||||
|
<bouncycastle.version>1.46</bouncycastle.version> |
||||||
|
</properties> |
||||||
|
|
||||||
|
<dependencies> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>vip.xumy.admin</groupId> |
||||||
|
<artifactId>xumy_admin</artifactId> |
||||||
|
<version>${xumy.admin.version}</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- 代码修改之后可以实时生效,该模块在完整的打包环境下运行的时候会被禁用 --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-devtools</artifactId> |
||||||
|
<optional>true</optional> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||||
|
<exclusions> |
||||||
|
<exclusion> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-logging</artifactId> |
||||||
|
</exclusion> |
||||||
|
</exclusions> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- SpringBoot 的测试依赖 --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-test</artifactId> |
||||||
|
<scope>test</scope> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
</dependencies> |
||||||
|
|
||||||
|
<!-- Package as an executable jar --> |
||||||
|
<build> |
||||||
|
<finalName>pciture</finalName> |
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId> |
||||||
|
<configuration> |
||||||
|
<executable>true</executable> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
|
||||||
|
</project> |
@ -0,0 +1,17 @@ |
|||||||
|
package vip.xumy.picture; |
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication; |
||||||
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
||||||
|
|
||||||
|
import vip.xumy.admin.sys.conf.SysInitializer; |
||||||
|
import vip.xumy.admin.verify.conf.VerifyInitializer; |
||||||
|
import vip.xumy.picture.conf.PictureRescueInitializer; |
||||||
|
|
||||||
|
public class PictureRescueApplocation extends SpringBootServletInitializer { |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
Class<?>[] arr = new Class<?>[] { VerifyInitializer.class, SysInitializer.class, PictureRescueInitializer.class }; |
||||||
|
SpringApplication.run(arr, args); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package vip.xumy.picture.conf; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.boot.ApplicationArguments; |
||||||
|
import org.springframework.boot.ApplicationRunner; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import vip.xumy.admin.sys.service.ConfigService; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author:mengyxu |
||||||
|
* @date:2020年3月25日 |
||||||
|
*/ |
||||||
|
|
||||||
|
@Component |
||||||
|
@Configuration |
||||||
|
public class PictureApplicationRunner implements ApplicationRunner { |
||||||
|
private static final String HOSTR_CFG_KEY = "intranet_host"; |
||||||
|
private static final String HOSTE_CFG_KEY = "internet_host"; |
||||||
|
public static Map<String, String> HOST_MAP = new HashMap<>();; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
public void setConfigService(ConfigService configService) { |
||||||
|
HOST_MAP.put("traHost", configService.getStringConfig(HOSTR_CFG_KEY, null)); |
||||||
|
HOST_MAP.put("tertHost", configService.getStringConfig(HOSTE_CFG_KEY, null)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run(ApplicationArguments args) throws Exception { |
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package vip.xumy.picture.conf; |
||||||
|
|
||||||
|
import org.mybatis.spring.annotation.MapperScan; |
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; |
||||||
|
import org.springframework.boot.builder.SpringApplicationBuilder; |
||||||
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
||||||
|
import org.springframework.context.annotation.ComponentScan; |
||||||
|
|
||||||
|
@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class) |
||||||
|
@ComponentScan(value = "vip.xumy.picture") |
||||||
|
@MapperScan("vip.xumy.picture.**.mapper") |
||||||
|
public class PictureRescueInitializer extends SpringBootServletInitializer { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { |
||||||
|
return builder.sources(PictureRescueInitializer.class); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
package vip.xumy.picture.ctrl; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||||
|
import org.springframework.web.bind.annotation.PutMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RestController; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import com.github.pagehelper.Page; |
||||||
|
import com.github.pagehelper.PageHelper; |
||||||
|
|
||||||
|
import vip.xumy.admin.utils.LoginUtil; |
||||||
|
import vip.xumy.core.exception.CoreException; |
||||||
|
import vip.xumy.core.pojo.com.AjaxResponse; |
||||||
|
import vip.xumy.core.pojo.com.PageResponse; |
||||||
|
import vip.xumy.picture.pojo.Picture; |
||||||
|
import vip.xumy.picture.service.PictureService; |
||||||
|
|
||||||
|
/** |
||||||
|
* Do not use for any commercial purposes without permission |
||||||
|
* |
||||||
|
* @author: mengyxu |
||||||
|
* @date: 2021年12月31日 |
||||||
|
*/ |
||||||
|
|
||||||
|
@RestController |
||||||
|
@RequestMapping("picture") |
||||||
|
public class PictureController { |
||||||
|
@Autowired |
||||||
|
private PictureService pictureService; |
||||||
|
|
||||||
|
@GetMapping |
||||||
|
public PageResponse<Picture> list(Picture example, HttpServletRequest request) { |
||||||
|
example.setUser(LoginUtil.getUserId(request)); |
||||||
|
Page<Picture> pages = PageHelper.startPage(example.getPage(), example.getSize()); |
||||||
|
List<Picture> list = pictureService.list(example); |
||||||
|
PageResponse<Picture> rsp = new PageResponse<>(); |
||||||
|
rsp.setRows(list); |
||||||
|
rsp.setTotal(pages.getTotal()); |
||||||
|
return rsp; |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping |
||||||
|
public AjaxResponse save(MultipartFile file, HttpServletRequest request) throws CoreException { |
||||||
|
pictureService.save(file, LoginUtil.getUserId(request)); |
||||||
|
return new AjaxResponse(true, "上传成功"); |
||||||
|
} |
||||||
|
|
||||||
|
@PutMapping |
||||||
|
public AjaxResponse update(@RequestBody Picture picture) throws CoreException { |
||||||
|
pictureService.update(picture); |
||||||
|
return new AjaxResponse(true, "更新成功"); |
||||||
|
} |
||||||
|
|
||||||
|
@DeleteMapping |
||||||
|
public AjaxResponse delete(@RequestBody Picture picture) throws CoreException { |
||||||
|
pictureService.delete(picture); |
||||||
|
return new AjaxResponse(true, "删除成功"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package vip.xumy.picture.ctrl; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RestController; |
||||||
|
|
||||||
|
import vip.xumy.picture.conf.PictureApplicationRunner; |
||||||
|
|
||||||
|
/** Do not use for any commercial purposes without permission |
||||||
|
* @author: mengyxu |
||||||
|
* @date: 2021年12月31日 |
||||||
|
*/ |
||||||
|
|
||||||
|
@RestController |
||||||
|
@RequestMapping("public") |
||||||
|
public class PublicControoler { |
||||||
|
|
||||||
|
@GetMapping("host") |
||||||
|
public Map<String, String> getHost(){ |
||||||
|
return PictureApplicationRunner.HOST_MAP; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
package vip.xumy.picture.mapper; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Delete; |
||||||
|
import org.apache.ibatis.annotations.Insert; |
||||||
|
import org.apache.ibatis.annotations.Mapper; |
||||||
|
import org.apache.ibatis.annotations.Select; |
||||||
|
import org.apache.ibatis.annotations.Update; |
||||||
|
|
||||||
|
import vip.xumy.picture.pojo.Picture; |
||||||
|
|
||||||
|
/** |
||||||
|
* Do not use for any commercial purposes without permission |
||||||
|
* |
||||||
|
* @author: mengyxu |
||||||
|
* @date: 2021年12月31日 |
||||||
|
*/ |
||||||
|
|
||||||
|
@Mapper |
||||||
|
public interface PictureMapper { |
||||||
|
|
||||||
|
@Select({ "<script>", "SELECT * FROM user_picture ", "<where>", "<if test='user != null'> AND user = #{user} </if>", |
||||||
|
"<if test='startTime != null'> AND time >= #{startTime} </if>", |
||||||
|
"<if test='endTime != null'> AND #{endTime} > time </if>", |
||||||
|
"<if test='remark != null'> AND remark LIKE CONCAT('%', #{remark}, '%') </if>", |
||||||
|
"<if test='status != null'> AND status = #{status} </if>", "</where>", "ORDER BY time DESC", "</script>" }) |
||||||
|
List<Picture> list(Picture example); |
||||||
|
|
||||||
|
@Insert({ "INSERT INTO user_picture VALUES (#{id}, #{user}, NOW(), #{path}, #{space}, #{status}, #{remark})" }) |
||||||
|
void save(Picture picture); |
||||||
|
|
||||||
|
@Update({ "UPDATE user_picture SET status = #{status}, remark = #{remark} WHERE id = #{id}" }) |
||||||
|
void update(Picture picture); |
||||||
|
|
||||||
|
@Delete({ "DELETE FROM user_picture WHERE id = #{id}" }) |
||||||
|
void delete(String id); |
||||||
|
|
||||||
|
@Delete({ "DELETE FROM user_picture WHERE user = #{user}" }) |
||||||
|
void deleteAll(String user); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package vip.xumy.picture.pojo; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import lombok.Setter; |
||||||
|
import vip.xumy.core.pojo.base.BasePeriod; |
||||||
|
|
||||||
|
/** |
||||||
|
* Do not use for any commercial purposes without permission |
||||||
|
* |
||||||
|
* @author: mengyxu |
||||||
|
* @date: 2021年12月31日 |
||||||
|
*/ |
||||||
|
|
||||||
|
@Setter |
||||||
|
@Getter |
||||||
|
public class Picture extends BasePeriod { |
||||||
|
|
||||||
|
private String id; |
||||||
|
private String user; |
||||||
|
private String path; |
||||||
|
private String space; |
||||||
|
private String status; |
||||||
|
private String remark; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
package vip.xumy.picture.service; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.util.List; |
||||||
|
import java.util.UUID; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.beans.factory.annotation.Value; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import vip.xumy.core.exception.CoreException; |
||||||
|
import vip.xumy.core.utils.ImageType; |
||||||
|
import vip.xumy.picture.mapper.PictureMapper; |
||||||
|
import vip.xumy.picture.pojo.Picture; |
||||||
|
|
||||||
|
/** |
||||||
|
* Do not use for any commercial purposes without permission |
||||||
|
* |
||||||
|
* @author: mengyxu |
||||||
|
* @date: 2021年12月31日 |
||||||
|
*/ |
||||||
|
|
||||||
|
@Service |
||||||
|
public class PictureService { |
||||||
|
@Autowired |
||||||
|
private PictureMapper pictureMapper; |
||||||
|
|
||||||
|
@Value("${picture.root.path}") |
||||||
|
public void setRootPath(String path) { |
||||||
|
if (path != null && path.endsWith("/")) { |
||||||
|
this.rootPath = path; |
||||||
|
} else { |
||||||
|
this.rootPath = path + "/"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private String rootPath; |
||||||
|
|
||||||
|
public List<Picture> list(Picture example) { |
||||||
|
return pictureMapper.list(example); |
||||||
|
} |
||||||
|
|
||||||
|
public Picture save(MultipartFile file, String user) throws CoreException { |
||||||
|
byte[] data; |
||||||
|
try { |
||||||
|
data = file.getBytes(); |
||||||
|
} catch (IOException e) { |
||||||
|
throw new CoreException("图片上传失败"); |
||||||
|
} |
||||||
|
ImageType type = ImageType.getImageType(data); |
||||||
|
if (type == null) { |
||||||
|
throw new CoreException("未知的图片类型"); |
||||||
|
} |
||||||
|
String uuid = UUID.randomUUID().toString(); |
||||||
|
String path = uuid.replace("-", "/") + "." + type.getType(); |
||||||
|
writeToFile(path, data); |
||||||
|
Picture picture = new Picture(); |
||||||
|
picture.setUser(user); |
||||||
|
picture.setId(uuid.replace("-", "")); |
||||||
|
picture.setPath(path); |
||||||
|
picture.setStatus("0"); |
||||||
|
picture.setSpace(Math.ceil(data.length * 1.0 / 1024) + "KB"); |
||||||
|
pictureMapper.save(picture); |
||||||
|
return picture; |
||||||
|
} |
||||||
|
|
||||||
|
private void writeToFile(String path, byte[] data) throws CoreException { |
||||||
|
File file = new File(rootPath + path); |
||||||
|
File parent = file.getParentFile(); |
||||||
|
if (!parent.exists()) { |
||||||
|
file.mkdirs(); |
||||||
|
} |
||||||
|
try (FileOutputStream fos = new FileOutputStream(file)) { |
||||||
|
fos.write(data); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
file.delete(); |
||||||
|
deleteEmptyDir(parent); |
||||||
|
throw new CoreException("图片保存失败"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void update(Picture picture) { |
||||||
|
pictureMapper.update(picture); |
||||||
|
} |
||||||
|
|
||||||
|
public void delete(Picture picture) { |
||||||
|
deleteFile(picture.getPath()); |
||||||
|
pictureMapper.delete(picture.getId()); |
||||||
|
} |
||||||
|
|
||||||
|
private void deleteFile(String path) { |
||||||
|
File file = new File(rootPath + path); |
||||||
|
file.deleteOnExit(); |
||||||
|
deleteEmptyDir(file.getParentFile()); |
||||||
|
} |
||||||
|
|
||||||
|
private void deleteEmptyDir(File dir) { |
||||||
|
if (!dir.exists() || !dir.isDirectory()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (dir.list().length == 0) { |
||||||
|
dir.delete(); |
||||||
|
deleteEmptyDir(dir.getParentFile()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void deleteAll(String user) { |
||||||
|
pictureMapper.deleteAll(user); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
[*.{js,jsx,ts,tsx,vue}] |
||||||
|
indent_style = space |
||||||
|
indent_size = 2 |
||||||
|
trim_trailing_whitespace = true |
||||||
|
insert_final_newline = true |
@ -0,0 +1,2 @@ |
|||||||
|
NODE_ENV="development" |
||||||
|
VUE_APP_BASE_URL="localhost" |
@ -0,0 +1,22 @@ |
|||||||
|
.DS_Store |
||||||
|
node_modules |
||||||
|
/dist |
||||||
|
|
||||||
|
# local env files |
||||||
|
.env.local |
||||||
|
.env.*.local |
||||||
|
|
||||||
|
# Log files |
||||||
|
npm-debug.log* |
||||||
|
yarn-debug.log* |
||||||
|
yarn-error.log* |
||||||
|
pnpm-debug.log* |
||||||
|
|
||||||
|
# Editor directories and files |
||||||
|
.idea |
||||||
|
.vscode |
||||||
|
*.suo |
||||||
|
*.ntvs* |
||||||
|
*.njsproj |
||||||
|
*.sln |
||||||
|
*.sw? |
@ -0,0 +1,24 @@ |
|||||||
|
# monitor-vue |
||||||
|
|
||||||
|
## Project setup |
||||||
|
``` |
||||||
|
yarn install |
||||||
|
``` |
||||||
|
|
||||||
|
### Compiles and hot-reloads for development |
||||||
|
``` |
||||||
|
yarn serve |
||||||
|
``` |
||||||
|
|
||||||
|
### Compiles and minifies for production |
||||||
|
``` |
||||||
|
yarn build |
||||||
|
``` |
||||||
|
|
||||||
|
### Lints and fixes files |
||||||
|
``` |
||||||
|
yarn lint |
||||||
|
``` |
||||||
|
|
||||||
|
### Customize configuration |
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/). |
@ -0,0 +1,5 @@ |
|||||||
|
module.exports = { |
||||||
|
presets: [ |
||||||
|
'@vue/cli-plugin-babel/preset' |
||||||
|
] |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
[1105/164547.236:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3) |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,70 @@ |
|||||||
|
{ |
||||||
|
"name": "picture", |
||||||
|
"version": "0.1.0", |
||||||
|
"private": true, |
||||||
|
"scripts": { |
||||||
|
"dev": "vue-cli-service serve", |
||||||
|
"build": "vue-cli-service build --mode production", |
||||||
|
"lint": "vue-cli-service lint", |
||||||
|
"preview": "vue-cli-service build --mode preview", |
||||||
|
"test": "vue-cli-service build --mode test" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"core-js": "^3.6.5", |
||||||
|
"vue": "^2.6.11", |
||||||
|
"vue-class-component": "^7.2.3", |
||||||
|
"vue-property-decorator": "^8.4.2", |
||||||
|
"vue-router": "^3.2.0", |
||||||
|
"vuex": "^3.4.0" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@babel/core": "^7.10.5", |
||||||
|
"@typescript-eslint/eslint-plugin": "^2.33.0", |
||||||
|
"@typescript-eslint/parser": "^2.33.0", |
||||||
|
"@vue/cli-plugin-babel": "^4.4.0", |
||||||
|
"@vue/cli-plugin-eslint": "^4.4.0", |
||||||
|
"@vue/cli-plugin-router": "^4.4.6", |
||||||
|
"@vue/cli-plugin-typescript": "^4.4.0", |
||||||
|
"@vue/cli-plugin-vuex": "^4.4.6", |
||||||
|
"@vue/cli-service": "^4.4.0", |
||||||
|
"@vue/eslint-config-standard": "^5.1.2", |
||||||
|
"@vue/eslint-config-typescript": "^5.0.2", |
||||||
|
"axios": "^0.19.2", |
||||||
|
"babel-loader": "^8.1.0", |
||||||
|
"cache-loader": "^4.1.0", |
||||||
|
"element-ui": "^2.15.6", |
||||||
|
"eslint": "^6.7.2", |
||||||
|
"eslint-plugin-import": "^2.20.2", |
||||||
|
"eslint-plugin-node": "^11.1.0", |
||||||
|
"eslint-plugin-promise": "^4.2.1", |
||||||
|
"eslint-plugin-standard": "^4.0.0", |
||||||
|
"eslint-plugin-vue": "^6.2.2", |
||||||
|
"js-md5": "^0.7.3", |
||||||
|
"node-sass": "^4.14.1", |
||||||
|
"sass-loader": "^9.0.2", |
||||||
|
"typescript": "~3.9.3", |
||||||
|
"vue-cli-plugin-axios": "^0.0.4", |
||||||
|
"vue-cli-plugin-element": "^1.0.1", |
||||||
|
"vue-clipboard2": "^0.3.1", |
||||||
|
"vue-template-compiler": "^2.6.11" |
||||||
|
}, |
||||||
|
"eslintConfig": { |
||||||
|
"root": true, |
||||||
|
"env": { |
||||||
|
"node": true |
||||||
|
}, |
||||||
|
"extends": [ |
||||||
|
"plugin:vue/recommended", |
||||||
|
"@vue/standard", |
||||||
|
"@vue/typescript/recommended" |
||||||
|
], |
||||||
|
"parserOptions": { |
||||||
|
"ecmaVersion": 2020 |
||||||
|
} |
||||||
|
}, |
||||||
|
"browserslist": [ |
||||||
|
"> 1%", |
||||||
|
"last 2 versions", |
||||||
|
"not dead" |
||||||
|
] |
||||||
|
} |
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,18 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0"> |
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
||||||
|
<title>图床卅</title> |
||||||
|
</head> |
||||||
|
<body style="margin: 0px;"> |
||||||
|
<noscript> |
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript |
||||||
|
enabled. Please enable it to continue.</strong> |
||||||
|
</noscript> |
||||||
|
<div id="app"></div> |
||||||
|
<!-- built files will be auto injected --> |
||||||
|
</body> |
||||||
|
</html> |
After Width: | Height: | Size: 8.6 KiB |
@ -0,0 +1,23 @@ |
|||||||
|
@charset "UTF-8"; |
||||||
|
body{ |
||||||
|
background-color: cadetblue; |
||||||
|
} |
||||||
|
|
||||||
|
.app-head{ |
||||||
|
background-color: #00ffff; |
||||||
|
} |
||||||
|
|
||||||
|
.app-main{ |
||||||
|
// background-color: #5500ff; |
||||||
|
} |
||||||
|
|
||||||
|
.main-table{ |
||||||
|
background-color: #409EFF; |
||||||
|
} |
||||||
|
|
||||||
|
.el-empty__description p{ |
||||||
|
color: black !important; |
||||||
|
} |
||||||
|
.el-table__empty-text{ |
||||||
|
color: black !important; |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
@charset "UTF-8"; |
||||||
|
.app-head{ |
||||||
|
background-color: #E4E7ED; |
||||||
|
} |
||||||
|
|
||||||
|
.app-main{ |
||||||
|
background-color: #EBEEF5; |
||||||
|
} |
||||||
|
|
||||||
|
.main-table{ |
||||||
|
background-color: #F2F6FC; |
||||||
|
} |
@ -0,0 +1,166 @@ |
|||||||
|
@charset "UTF-8"; |
||||||
|
* { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
html, |
||||||
|
body { |
||||||
|
font-size: 14px; |
||||||
|
font-family: "Microsoft YaHei"; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.el-header, .main-head, .main-table{ |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
// 公共样式文件 |
||||||
|
// 带阴影的表格外的div |
||||||
|
div.table-warpper { |
||||||
|
margin: 0 2.5%; |
||||||
|
padding: 0 0.5%; |
||||||
|
border: 1px solid #20A0FF; |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.tabs-header { |
||||||
|
margin-left: 1em; |
||||||
|
} |
||||||
|
|
||||||
|
.cur-table-warpper { |
||||||
|
margin-left: -1em; |
||||||
|
} |
||||||
|
|
||||||
|
// input[type=number]在ff和chrome中会出现上下的小三角箭头 |
||||||
|
input::-webkit-outer-spin-button, |
||||||
|
input::-webkit-inner-spin-button { |
||||||
|
-webkit-appearance: none !important; |
||||||
|
} |
||||||
|
|
||||||
|
input[type="number"] { |
||||||
|
-moz-appearance: textfield; |
||||||
|
} |
||||||
|
|
||||||
|
// 修改element |
||||||
|
.el-picker-panel__link-btn { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
.el-pagination__editor { |
||||||
|
width: 55px !important; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
.query-mini { |
||||||
|
width: 100px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.query-smart { |
||||||
|
width: 120px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.query-short { |
||||||
|
width: 150px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.query-medium { |
||||||
|
width: 200px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.query-long { |
||||||
|
width: 250px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.query-tree { |
||||||
|
width: 300px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.query-longest { |
||||||
|
width: 350px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.query-400 { |
||||||
|
width: 400px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.query-450 { |
||||||
|
width: 450px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.query-500 { |
||||||
|
width: 500px !important; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.modify-dialog .el-dialog { |
||||||
|
background-color: #edf2f7; |
||||||
|
} |
||||||
|
|
||||||
|
.form-title { |
||||||
|
font-size: 18px; |
||||||
|
background-color: cadetblue; |
||||||
|
padding: 10px; |
||||||
|
height: 25px; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 20px; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
.full-item-form .el-select, |
||||||
|
.full-item-form .el-date-editor, |
||||||
|
.full-item-form .el-autocomplete { |
||||||
|
width: 100% !important; |
||||||
|
} |
||||||
|
|
||||||
|
.dialog-footer { |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
.infomation-form .el-form-item { |
||||||
|
margin-top: 20px; |
||||||
|
font-size: 1.5rem; |
||||||
|
} |
||||||
|
|
||||||
|
.infomation-form .el-input { |
||||||
|
width: 350px; |
||||||
|
margin-right: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.infomation-form .el-input__inner { |
||||||
|
background-color: #4472c4 !important; |
||||||
|
color: #FFFFFF; |
||||||
|
} |
||||||
|
|
||||||
|
// 表格背景透明, 便于定制整体背景样式 |
||||||
|
.main-table .el-table, |
||||||
|
.el-table__expanded-cell { |
||||||
|
background-color: transparent; |
||||||
|
border: none; |
||||||
|
} |
||||||
|
|
||||||
|
.main-table .el-table tr { |
||||||
|
background-color: transparent !important; |
||||||
|
border: none; |
||||||
|
} |
||||||
|
|
||||||
|
.main-table .el-table--enable-row-transition .el-table__header td, |
||||||
|
.el-table .cell { |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
|
||||||
|
.main-table .el-table--enable-row-transition .el-table__body td, |
||||||
|
.el-table .cell { |
||||||
|
background-color: transparent; |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
@charset "UTF-8"; |
||||||
|
.main-table .el-table td, .main-table .el-table th{ |
||||||
|
padding: 9px 0px; |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
@charset "UTF-8"; |
||||||
|
.main-table .el-table td, .main-table .el-table th{ |
||||||
|
padding: 3px 0px; |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
@charset "UTF-8"; |
||||||
|
.main-table .el-table td, .main-table .el-table th{ |
||||||
|
padding: 5px 0px; |
||||||
|
} |
@ -0,0 +1,182 @@ |
|||||||
|
<template> |
||||||
|
<div id="header"> |
||||||
|
<el-row> |
||||||
|
<el-col :span="12"> |
||||||
|
<el-row class="menu-row"> |
||||||
|
<el-menu class="el-menu-demo" :default-active="activeGroup" mode="horizontal" text-color="#000" |
||||||
|
active-text-color="#4669e7"> |
||||||
|
<el-menu-item v-for="item in $store.state.menuGroups" :key="item.id" :index="item.id" |
||||||
|
@click="clickGroup(item)"> |
||||||
|
{{ item.name }} |
||||||
|
</el-menu-item> |
||||||
|
</el-menu> |
||||||
|
<el-radio-group :size="$store.state.size" v-model="active"> |
||||||
|
<el-radio-button v-for="item in menus" :label="item.id"> |
||||||
|
{{ item.name }} |
||||||
|
</el-radio-button> |
||||||
|
</el-radio-group> |
||||||
|
</el-row> |
||||||
|
</el-col> |
||||||
|
<el-col :span="12"> |
||||||
|
<el-row class="info" type="flex" justify="end" align="middle"> |
||||||
|
<el-button class="info-btn" icon="el-icon-user-solid" type="text"> |
||||||
|
{{ $store.state.userInfo.userId }} |
||||||
|
</el-button> |
||||||
|
<el-button :size="$store.state.size" icon="el-icon-setting" type="info" @click="update = true"> |
||||||
|
修改密码 |
||||||
|
</el-button> |
||||||
|
<el-button :size="$store.state.size" icon="el-icon-switch-button" type="info" |
||||||
|
@click="$store.commit('logout')"> |
||||||
|
注销登录 |
||||||
|
</el-button> |
||||||
|
</el-row> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
|
||||||
|
<el-dialog title="修改密码" :visible.sync="update" width="40%" top="15vh" :close-on-click-modal="false" |
||||||
|
@keydown.enter.native="confirm()"> |
||||||
|
<el-form ref="update" :model="user" :rules="rules" label-width="180px"> |
||||||
|
<el-form-item label="旧密码" prop="password"> |
||||||
|
<el-input type="password" v-model="user.password"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="新密码" prop="newPwd"> |
||||||
|
<el-input type="password" v-model="user.newPwd"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="重复新密码" prop="rePwd"> |
||||||
|
<el-input type="password" v-model="user.rePwd" autocomplete="off"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="update = false;"> 取 消 </el-button> |
||||||
|
<el-button type="primary" @click="confrim"> 确 定 </el-button> |
||||||
|
</div> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { |
||||||
|
Vue, |
||||||
|
Component, |
||||||
|
Prop, |
||||||
|
Watch |
||||||
|
} from 'vue-property-decorator'; |
||||||
|
import md5 from 'js-md5'; |
||||||
|
import { |
||||||
|
password |
||||||
|
} from '@/static/tool/validate.js'; |
||||||
|
|
||||||
|
@Component |
||||||
|
export default class NavHeader extends Vue { |
||||||
|
menus = []; |
||||||
|
active = 'home'; |
||||||
|
activeGroup = 'home'; |
||||||
|
|
||||||
|
update = false; |
||||||
|
user = {}; |
||||||
|
rules = { |
||||||
|
password: [{ |
||||||
|
required: true, |
||||||
|
message: '请输入密码', |
||||||
|
trigger: 'blur' |
||||||
|
}], |
||||||
|
newPwd: [{ |
||||||
|
validator: password, |
||||||
|
trigger: 'blur' |
||||||
|
}], |
||||||
|
rePwd: [{ |
||||||
|
validator: this.reKey, |
||||||
|
trigger: 'blur' |
||||||
|
}] |
||||||
|
}; |
||||||
|
|
||||||
|
clickGroup(group) { |
||||||
|
this.activeGroup = group.id |
||||||
|
this.menus = group.child |
||||||
|
const child = group.child |
||||||
|
if (child.length == 0) { |
||||||
|
this.active = group.id |
||||||
|
} else { |
||||||
|
this.active = child[0].id |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
clickMenu(id) { |
||||||
|
this.active = id |
||||||
|
} |
||||||
|
|
||||||
|
toHome() { |
||||||
|
this.clickGroup(this.$store.state.menuGroups[0]); |
||||||
|
} |
||||||
|
|
||||||
|
confrim() { |
||||||
|
const that = this |
||||||
|
this.$refs.update.validate((valid) => { |
||||||
|
if (valid) { |
||||||
|
const param = JSON.parse(JSON.stringify(that.user)); |
||||||
|
param.userId = that.$store.state.userInfo.userId; |
||||||
|
param.password = md5(param.password) |
||||||
|
param.newPwd = md5(param.newPwd) |
||||||
|
delete param.rePwd; |
||||||
|
that.$post('public/update/password', param).then(rsp => { |
||||||
|
if (rsp) { |
||||||
|
that.update = false; |
||||||
|
that.user = {}; |
||||||
|
that.$store.commit('logout') |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
return false |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
reKey(rule, value, callback) { |
||||||
|
if (!value) { |
||||||
|
callback(new Error('请重复输入新密码')); |
||||||
|
} else if (value != this.user.newPwd) { |
||||||
|
callback(new Error('两次输入的新密码不一致')); |
||||||
|
} else { |
||||||
|
callback(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Watch('active') |
||||||
|
activeChang(n, o) { |
||||||
|
this.$router.push('/' + n) |
||||||
|
} |
||||||
|
|
||||||
|
created() {} |
||||||
|
mounted() {} // 生命周期 - 挂载完成(可以访问DOM元素 |
||||||
|
beforeCreate() {} // 生命周期 - 创建之前 |
||||||
|
beforeMount() {} // 生命周期 - 挂载之前 |
||||||
|
beforeUpdate() {} // 生命周期 - 更新之前 |
||||||
|
updated() {} // 生命周期 - 更新之后 |
||||||
|
beforeDestroy() {} // 生命周期 - 销毁之前 |
||||||
|
destroyed() {} // 生命周期 - 销毁完成 |
||||||
|
activated() {} // 如果页面有keep-alive缓存功能,这个函数会触发 |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style scoped> |
||||||
|
.info { |
||||||
|
/* background-color: cadetblue; */ |
||||||
|
height: 80px; |
||||||
|
padding-right: 100px; |
||||||
|
} |
||||||
|
|
||||||
|
.el-menu.el-menu--horizontal { |
||||||
|
border-bottom: none; |
||||||
|
} |
||||||
|
|
||||||
|
.info-btn { |
||||||
|
font-size: 17px; |
||||||
|
color: #2D3748; |
||||||
|
margin-left: 30px !important; |
||||||
|
} |
||||||
|
|
||||||
|
.menu-row { |
||||||
|
background-color: #FFFFFF; |
||||||
|
padding-left: 30px; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,72 @@ |
|||||||
|
<template> |
||||||
|
<div id="mainHeader" class="main-head" :style="{ height: $store.state.sizes.mainHead }"> |
||||||
|
<el-row> |
||||||
|
<el-col :span="8" v-if="flag.title"> |
||||||
|
<slot name="title"></slot> |
||||||
|
</el-col> |
||||||
|
<el-col :span="flag.title ? 16 : 24"> |
||||||
|
<el-row type="flex" justify="end"> |
||||||
|
<span v-for="term in terms"> |
||||||
|
<el-date-picker :size="$store.state.size" v-if="term.datePicker" v-model="example[term.code]" |
||||||
|
:value-format="term.valueFormat" :type="term.type" :class="term.claze ? term.claze : 'query-medium'" |
||||||
|
:placeholder="term.desc"></el-date-picker> |
||||||
|
<el-select :size="$store.state.size" v-if="term.dict" v-model="example[term.code]" |
||||||
|
:class="term.claze ? term.claze : 'query-medium'" :placeholder="term.desc" :filterable="term.filterable" |
||||||
|
clearable> |
||||||
|
<el-option v-for="(val, key, i) in $store.state.dict[term.dict]" :key="key" :value="key" :label="val" /> |
||||||
|
</el-select> |
||||||
|
<el-input :size="$store.state.size" v-if="!term.datePicker && !term.dict" v-model="example[term.code]" |
||||||
|
:class="term.claze ? term.claze : 'query-medium'" :placeholder="term.desc" clearable /> |
||||||
|
</span> |
||||||
|
<el-button :size="$store.state.size" type="primary" icon="el-icon-search" @click="$emit('query')" |
||||||
|
v-if="flag.list"> 查询 |
||||||
|
</el-button> |
||||||
|
<el-button :size="$store.state.size" type="success" icon="el-icon-plus" @click="add()" v-if="flag.save"> |
||||||
|
添加{{name}} |
||||||
|
</el-button> |
||||||
|
<slot name="header"></slot> |
||||||
|
</el-row> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { |
||||||
|
Vue, |
||||||
|
Component, |
||||||
|
Prop |
||||||
|
} from "vue-property-decorator"; |
||||||
|
|
||||||
|
@Component |
||||||
|
export default class MainHeader extends Vue { |
||||||
|
@Prop({ |
||||||
|
type: String |
||||||
|
}) name; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Object |
||||||
|
}) flag; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Array |
||||||
|
}) terms; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Object |
||||||
|
}) example; |
||||||
|
|
||||||
|
created() {} //生命周期 - 创建完成(可以访问当前this实例) |
||||||
|
mounted() {} //生命周期 - 挂载完成(可以访问DOM元素) |
||||||
|
beforeCreate() {} //生命周期 - 创建之前 |
||||||
|
beforeMount() {} //生命周期 - 挂载之前 |
||||||
|
beforeUpdate() {} //生命周期 - 更新之前 |
||||||
|
updated() {} //生命周期 - 更新之后 |
||||||
|
beforeDestroy() {} //生命周期 - 销毁之前 |
||||||
|
destroyed() {} //生命周期 - 销毁完成 |
||||||
|
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发 |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,267 @@ |
|||||||
|
<template> |
||||||
|
<div id="mamageTemp"> |
||||||
|
<MainHead :name="name" :flag="flag" :terms="terms" :example="example" @query="query(1)"></MainHead> |
||||||
|
<!-- <el-row class="main-head" :style="{ height: $store.state.sizes.mainHead }"> |
||||||
|
<el-row type="flex" justify="end"> |
||||||
|
<span v-for="term in terms"> |
||||||
|
<el-date-picker :size="$store.state.size" v-if="term.datePicker" v-model="example[term.code]" |
||||||
|
:value-format="term.valueFormat" :type="term.type" :class="term.claze ? term.claze : 'query-medium'" |
||||||
|
:placeholder="term.desc"></el-date-picker> |
||||||
|
<el-select :size="$store.state.size" v-if="term.dict" v-model="example[term.code]" |
||||||
|
:class="term.claze ? term.claze : 'query-medium'" :placeholder="term.desc" :filterable="term.filterable" |
||||||
|
clearable> |
||||||
|
<el-option v-for="(val, key, i) in $store.state.dict[term.dict]" :key="key" :value="key" :label="val" /> |
||||||
|
</el-select> |
||||||
|
<el-input :size="$store.state.size" v-if="!term.datePicker && !term.dict" v-model="example[term.code]" |
||||||
|
:class="term.claze ? term.claze : 'query-medium'" :placeholder="term.desc" clearable /> |
||||||
|
</span> |
||||||
|
<el-button :size="$store.state.size" type="primary" icon="el-icon-search" @click="query(1)" v-if="flag.list"> 查询 |
||||||
|
</el-button> |
||||||
|
<el-button :size="$store.state.size" type="success" icon="el-icon-plus" @click="add()" v-if="flag.save"> |
||||||
|
添加{{name}} |
||||||
|
</el-button> |
||||||
|
<slot name="header"></slot> |
||||||
|
</el-row> |
||||||
|
</el-row> --> |
||||||
|
<el-row class="main-table"> |
||||||
|
<el-table :data="result.rows" :height="tableHeight ? tableHeight : $store.state.sizes.pTableHei" border> |
||||||
|
<el-table-column v-for="prop in props" v-if="!prop.tableHide" :prop="prop.code" :label="prop.name" |
||||||
|
:min-width="prop.width" :width="prop.type ? prop.width : ''" :type="prop.type" |
||||||
|
:formatter="(row,column,value) => getValue(prop.dict,value)" show-overflow-tooltip> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column v-if="flag.update || flag.del || actions" label="操作" :width="actionWidth" fixed="right"> |
||||||
|
<template slot-scope="scope" v-if="!stateProp || scope.row[stateProp] != 'R'"> |
||||||
|
<el-button v-if="flag.update" size="mini" type="primary" @click="modify(scope.row)"> 修改 </el-button> |
||||||
|
<el-button v-if="flag.del" size="mini" type="danger" @click="delate(scope.row)"> 删除 </el-button> |
||||||
|
<el-button v-for="action in actions" size="mini" :type="action.type" @click="$emit(action.emit,scope.row)"> |
||||||
|
{{action.name}} |
||||||
|
</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<el-pagination :current-page="example.page" :page-sizes="[10, 20, 50, 100]" :page-size="example.size" |
||||||
|
layout="total, sizes, prev, pager, next, jumper" :total="result.total" @size-change="handleSizeChange" |
||||||
|
@current-change="handleCurrentChange" /> |
||||||
|
</el-row> |
||||||
|
|
||||||
|
<el-dialog append-to-body :title="(flag.add ? '添加':'修改') + name" :visible.sync="flag.modify" |
||||||
|
:close-on-click-modal="false" top="15vh" :width="props.length > 8 ? '60%' : '40%'" |
||||||
|
@keydown.enter.native="confirm()"> |
||||||
|
<el-form ref="update" class="full-item-form" label-width="180px" :rules="rules" :model="param"> |
||||||
|
<el-row v-if="props.length > 8"> |
||||||
|
<el-col :span="12" v-for="prop in props"> |
||||||
|
<ModifyItem :prop="prop" :flag="flag" :param="param"></ModifyItem> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
<el-row v-else> |
||||||
|
<span v-for="prop in props"> |
||||||
|
<ModifyItem :prop="prop" :flag="flag" :param="param"></ModifyItem> |
||||||
|
</span> |
||||||
|
</el-row> |
||||||
|
</el-form> |
||||||
|
<div slot="footer" class="dialog-footer"> |
||||||
|
<el-button @click="flag.modify = false"> 取消 </el-button> |
||||||
|
<el-button type="primary" @click="confirm"> 确认 </el-button> |
||||||
|
</div> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { |
||||||
|
Vue, |
||||||
|
Component, |
||||||
|
Prop, |
||||||
|
Watch |
||||||
|
} from 'vue-property-decorator'; |
||||||
|
import ModifyItem from './modifyItem.vue'; |
||||||
|
import MainHead from './mainHeader.vue'; |
||||||
|
|
||||||
|
@Component({ |
||||||
|
components: { |
||||||
|
ModifyItem, |
||||||
|
MainHead |
||||||
|
} |
||||||
|
}) |
||||||
|
export default class MamageTemp extends Vue { |
||||||
|
@Prop({ |
||||||
|
type: String |
||||||
|
}) name; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: String |
||||||
|
}) url; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Object, |
||||||
|
}) flag; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Array |
||||||
|
}) terms; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Array |
||||||
|
}) props; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Array |
||||||
|
}) actions; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Object |
||||||
|
}) rules; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: String |
||||||
|
}) stateProp; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: String |
||||||
|
}) size; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Number |
||||||
|
}) tableHeight; |
||||||
|
|
||||||
|
actionWidth = 30; |
||||||
|
example = { |
||||||
|
page: 1, |
||||||
|
size: 20 |
||||||
|
}; |
||||||
|
result = { |
||||||
|
rows: [], |
||||||
|
total: 0 |
||||||
|
}; |
||||||
|
param = {}; |
||||||
|
|
||||||
|
handleSizeChange(val) { |
||||||
|
this.example.size = val |
||||||
|
this.query() |
||||||
|
} |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.example.page = val |
||||||
|
this.query() |
||||||
|
} |
||||||
|
query(page) { |
||||||
|
const that = this |
||||||
|
if (page != null) { |
||||||
|
this.example.page = page |
||||||
|
} |
||||||
|
this.$get(that.url, that.example).then(function(response) { |
||||||
|
if (response) { |
||||||
|
that.result = response |
||||||
|
} else { |
||||||
|
that.result = { |
||||||
|
rows: [], |
||||||
|
total: 0 |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
add() { |
||||||
|
if (this.$refs.update != null) { |
||||||
|
this.$refs.update.clearValidate() |
||||||
|
} |
||||||
|
this.param = {}; |
||||||
|
this.flag.add = true |
||||||
|
this.flag.modify = true |
||||||
|
} |
||||||
|
modify(row) { |
||||||
|
if (this.$refs.update != null) { |
||||||
|
this.$refs.update.clearValidate() |
||||||
|
} |
||||||
|
this.flag.add = false |
||||||
|
this.param = JSON.parse(JSON.stringify(row)) |
||||||
|
this.flag.modify = true |
||||||
|
} |
||||||
|
|
||||||
|
delate(row) { |
||||||
|
const that = this |
||||||
|
const msg = this.name ? this.name : "记录" |
||||||
|
this.$confirm('确定要删除该' + msg + '吗?', '提示', { |
||||||
|
confirmButtonText: '确定', |
||||||
|
cancelButtonText: '取消', |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$delete(that.url, row).then(function(response) { |
||||||
|
if (response) { |
||||||
|
that.query() |
||||||
|
that.$emit('change'); |
||||||
|
} |
||||||
|
}) |
||||||
|
}).catch(() => { |
||||||
|
that.showMessage('info', '已取消删除') |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
confirm() { |
||||||
|
const that = this |
||||||
|
this.$refs.update.validate((valid) => { |
||||||
|
if (valid) { |
||||||
|
const method = that.flag.add ? that.$post : that.$put; |
||||||
|
method(that.url, that.param).then(function(response) { |
||||||
|
if (response) { |
||||||
|
that.query() |
||||||
|
that.flag.modify = false |
||||||
|
that.$emit('change'); |
||||||
|
} |
||||||
|
}) |
||||||
|
} else { |
||||||
|
return false |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
getValue(dictKey, value) { |
||||||
|
if (!dictKey) { |
||||||
|
return value; |
||||||
|
} |
||||||
|
const dict = this.$store.state.dict[dictKey] |
||||||
|
if (dict == null) { |
||||||
|
return value; |
||||||
|
} |
||||||
|
return dict[value] == null ? value : dict[value] |
||||||
|
} |
||||||
|
|
||||||
|
created() { |
||||||
|
this.$set(this.flag, 'add', false); |
||||||
|
this.$set(this.flag, 'modify', false); |
||||||
|
this.query(); |
||||||
|
if (this.flag.update) { |
||||||
|
this.actionWidth += 60; |
||||||
|
} |
||||||
|
if (this.flag.del) { |
||||||
|
this.actionWidth += 60; |
||||||
|
} |
||||||
|
const that = this; |
||||||
|
if (this.actions) { |
||||||
|
this.actions.forEach(i => { |
||||||
|
that.actionWidth += i.width; |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Watch('flag.modify') |
||||||
|
modifyChang(n, o) { |
||||||
|
if (!n) { |
||||||
|
this.param = {}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
mounted() {} // 生命周期 - 挂载完成(可以访问DOM元素) |
||||||
|
beforeCreate() {} // 生命周期 - 创建之前 |
||||||
|
beforeMount() {} // 生命周期 - 挂载之前 |
||||||
|
beforeUpdate() {} // 生命周期 - 更新之前 |
||||||
|
updated() {} // 生命周期 - 更新之后 |
||||||
|
beforeDestroy() {} // 生命周期 - 销毁之前 |
||||||
|
destroyed() {} // 生命周期 - 销毁完成 |
||||||
|
activated() {} // 如果页面有keep-alive缓存功能,这个函数会触发 |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style scoped> |
||||||
|
/* #mamageTemp { |
||||||
|
padding: 20px 20px 0px 20px; |
||||||
|
} */ |
||||||
|
</style> |
@ -0,0 +1,62 @@ |
|||||||
|
<template> |
||||||
|
<div id="modifyItem"> |
||||||
|
<!-- <el-form-item :label="prop.name" :prop="prop.code" v-if="!prop.hide && (!prop.addHide || !flag.add)"> --> |
||||||
|
<el-form-item :label="prop.name" :prop="prop.code" |
||||||
|
v-if="!(prop.hide || (flag.add && prop.addHide) || (!flag.add && prop.modifyHide))"> |
||||||
|
<el-select v-if="prop.dict" v-model="param[prop.code]" :disabled="!flag.add && prop.readOnly" filterable |
||||||
|
:placeholder="'请选择'+prop.name" clearable> |
||||||
|
<el-option v-if="prop.dict == 'order'" v-for="index in 99" :key="index" :value="index+''" :label="index" /> |
||||||
|
<el-option v-if="prop.dict != 'order'" v-for="(val, key, i) in $store.state.dict[prop.dict]" :key="key" |
||||||
|
:value="prop.int ? parseInt(key):key+''" :label="val" /> |
||||||
|
</el-select> |
||||||
|
<el-select v-if="prop.state" :multiple="prop.multiple" v-model="param[prop.code]" |
||||||
|
:disabled="!flag.add && prop.readOnly" :placeholder="'请选择'+prop.name" filterable clearable> |
||||||
|
<el-option v-for="item in $store.state[prop.state]" :key="item.key" :value="item.key" :label="item.value" /> |
||||||
|
</el-select> |
||||||
|
<el-autocomplete v-if="prop.autocomplete" v-model="param[prop.code]" :fetch-suggestions="prop.getData" onKeypress="return(event.keyCode != 32)" |
||||||
|
:placeholder="'请输入'+prop.name" clearable> |
||||||
|
<template slot-scope="{ item }"> |
||||||
|
<div>{{ item.value + '--' + item[prop.labelKey] }}</div> |
||||||
|
</template> |
||||||
|
</el-autocomplete> |
||||||
|
<el-input v-if="!prop.dict && !prop.state && !prop.autocomplete" v-model="param[prop.code]" onKeypress="return(event.keyCode != 32)" |
||||||
|
:disabled="!flag.add && prop.readOnly" :placeholder="prop.desc ? prop.desc : '请输入'+prop.name" clearable /> |
||||||
|
</el-form-item> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { |
||||||
|
Vue, |
||||||
|
Component, |
||||||
|
Prop |
||||||
|
} from "vue-property-decorator"; |
||||||
|
|
||||||
|
@Component |
||||||
|
export default class ModifyItem extends Vue { |
||||||
|
@Prop({ |
||||||
|
type: Object |
||||||
|
}) prop; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Object |
||||||
|
}) flag; |
||||||
|
|
||||||
|
@Prop({ |
||||||
|
type: Object |
||||||
|
}) param; |
||||||
|
|
||||||
|
created() {} //生命周期 - 创建完成(可以访问当前this实例) |
||||||
|
mounted() {} //生命周期 - 挂载完成(可以访问DOM元素) |
||||||
|
beforeCreate() {} //生命周期 - 创建之前 |
||||||
|
beforeMount() {} //生命周期 - 挂载之前 |
||||||
|
beforeUpdate() {} //生命周期 - 更新之前 |
||||||
|
updated() {} //生命周期 - 更新之后 |
||||||
|
beforeDestroy() {} //生命周期 - 销毁之前 |
||||||
|
destroyed() {} //生命周期 - 销毁完成 |
||||||
|
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发 |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,17 @@ |
|||||||
|
import Vue from 'vue' |
||||||
|
import './static/plugins/axios' |
||||||
|
import App from './views/main/App.vue' |
||||||
|
import './static/plugins/element' |
||||||
|
import router from './router' |
||||||
|
import store from './store' |
||||||
|
import VueClipboard from 'vue-clipboard2' |
||||||
|
|
||||||
|
Vue.config.productionTip = false |
||||||
|
Vue.use(VueClipboard) |
||||||
|
|
||||||
|
const vue = new Vue({ |
||||||
|
router, |
||||||
|
store, |
||||||
|
render: h => h(App) |
||||||
|
}).$mount('#app') |
||||||
|
export default vue |
@ -0,0 +1,37 @@ |
|||||||
|
import Vue from 'vue' |
||||||
|
import VueRouter, { RouteConfig } from 'vue-router' |
||||||
|
|
||||||
|
Vue.use(VueRouter) |
||||||
|
|
||||||
|
const routes: Array<RouteConfig> = [ |
||||||
|
{ |
||||||
|
path: '/', |
||||||
|
redirect: '/home' |
||||||
|
},{ |
||||||
|
path: '/home', |
||||||
|
name: 'home', |
||||||
|
component: () => import('../views/biz/picture.vue') |
||||||
|
},{ |
||||||
|
path: '/login', |
||||||
|
name: 'Login', |
||||||
|
component: () => import('../views/main/login.vue') |
||||||
|
},{ |
||||||
|
path: '/config', |
||||||
|
name: 'Config', |
||||||
|
component: () => import('../views/sys/config.vue') |
||||||
|
} |
||||||
|
] |
||||||
|
|
||||||
|
const originalPush = VueRouter.prototype.push |
||||||
|
VueRouter.prototype.push = function push (location) { |
||||||
|
return originalPush.call(this, location).catch(err => err) |
||||||
|
} |
||||||
|
|
||||||
|
const router = new VueRouter({ |
||||||
|
routes |
||||||
|
}) |
||||||
|
|
||||||
|
router.afterEach((to, from) => { |
||||||
|
// ...
|
||||||
|
}) |
||||||
|
export default router |
@ -0,0 +1,13 @@ |
|||||||
|
import Vue, { VNode } from 'vue' |
||||||
|
|
||||||
|
declare global { |
||||||
|
namespace JSX { |
||||||
|
// tslint:disable no-empty-interface
|
||||||
|
interface Element extends VNode {} |
||||||
|
// tslint:disable no-empty-interface
|
||||||
|
interface ElementClass extends Vue {} |
||||||
|
interface IntrinsicElements { |
||||||
|
[elem: string]: any; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
declare module '*.vue' { |
||||||
|
import Vue from 'vue' |
||||||
|
export default Vue |
||||||
|
} |
@ -0,0 +1,289 @@ |
|||||||
|
/* eslint-disable */ |
||||||
|
import Vue from "vue"; |
||||||
|
import { Message } from "element-ui"; |
||||||
|
import axios from "axios"; |
||||||
|
import store from "@/store"; |
||||||
|
import loading from "./element" |
||||||
|
|
||||||
|
const config = { |
||||||
|
// baseURL: process.env.VUE_APP_BASE_URL || process.env.apiUrl || "",
|
||||||
|
baseURL: process.env.VUE_APP_BASE_URL ? "/api" : "", |
||||||
|
timeout: 60 * 1000, |
||||||
|
withCredentials: true // Check cross-site Access-Control
|
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
const _axios = axios.create(config); |
||||||
|
let curMsg: any; |
||||||
|
|
||||||
|
// Add a request interceptor
|
||||||
|
_axios.interceptors.request.use( |
||||||
|
function(config) { |
||||||
|
const time = new Date().getTime().toString(); |
||||||
|
if(config.params){ |
||||||
|
delEmpty(config.params); |
||||||
|
config.params.t = time; |
||||||
|
} |
||||||
|
if (config.data && typeof config.data === Object) { |
||||||
|
delEmpty(config.params); |
||||||
|
config.data.t = time; |
||||||
|
} |
||||||
|
return config; |
||||||
|
}, |
||||||
|
function(error) { |
||||||
|
return Promise.reject(error); |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
function delEmpty(data){ |
||||||
|
if(data){ |
||||||
|
for (const item in data) { |
||||||
|
if (data.hasOwnProperty(item)) { |
||||||
|
const val = data[item]; |
||||||
|
if ((val == null || val == "null" || val == "") && val !== 0) { |
||||||
|
delete data[item]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Add a response interceptor
|
||||||
|
_axios.interceptors.response.use( |
||||||
|
function(response) { |
||||||
|
if (!response.data.message) { |
||||||
|
return { success: true, data: response.data }; |
||||||
|
} |
||||||
|
return response.data; |
||||||
|
}, |
||||||
|
function(error) { |
||||||
|
return Promise.reject(error); |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
function post(url, data = {}, noMsg, noLoading) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
if(!noLoading){ |
||||||
|
loading.start(); |
||||||
|
} |
||||||
|
_axios.post(url, data).then( |
||||||
|
(response: any) => { |
||||||
|
handResponse(response, resolve, noMsg, noLoading); |
||||||
|
}, |
||||||
|
err => { |
||||||
|
handError(err, reject, noMsg, noLoading); |
||||||
|
} |
||||||
|
); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function get(url, data = {}, noMsg, noLoading) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
if(!noLoading){ |
||||||
|
loading.start(); |
||||||
|
} |
||||||
|
_axios.get(url, {params:data}).then( |
||||||
|
(response: any) => { |
||||||
|
handResponse(response, resolve, noMsg, noLoading); |
||||||
|
}, |
||||||
|
err => { |
||||||
|
handError(err, reject, noMsg, noLoading); |
||||||
|
} |
||||||
|
); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function put(url, data = {}, noMsg, noLoading) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
if(!noLoading){ |
||||||
|
loading.start(); |
||||||
|
} |
||||||
|
console.log(url); |
||||||
|
_axios.put(url, data).then( |
||||||
|
(response: any) => { |
||||||
|
handResponse(response, resolve, noMsg, noLoading); |
||||||
|
}, |
||||||
|
err => { |
||||||
|
handError(err, reject, noMsg, noLoading); |
||||||
|
} |
||||||
|
); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function delate(url, data = {}, noMsg, noLoading) { |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
if(!noLoading){ |
||||||
|
loading.start(); |
||||||
|
} |
||||||
|
_axios({ |
||||||
|
method: 'delete', |
||||||
|
url: url, |
||||||
|
data: data |
||||||
|
}).then( |
||||||
|
(response: any) => { |
||||||
|
handResponse(response, resolve, noMsg, noLoading); |
||||||
|
}, |
||||||
|
err => { |
||||||
|
handError(err, reject, noMsg, noLoading); |
||||||
|
} |
||||||
|
); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function handResponse(response, resolve, noMsg, noLoading){ |
||||||
|
if(!noLoading){ |
||||||
|
loading.stop(); |
||||||
|
} |
||||||
|
if (response.success) { |
||||||
|
if (response.message) { |
||||||
|
showMessage("success", response.message, false, noMsg); |
||||||
|
resolve(true); |
||||||
|
} else { |
||||||
|
resolve(response.data); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (response.message == "session timeout") { |
||||||
|
store.commit("logout"); |
||||||
|
} |
||||||
|
if (response.message == "no permission") { |
||||||
|
response.message = "您暂无权访问,请联系管理员添加"; |
||||||
|
} |
||||||
|
if (response.message.indexOf("no permission for ") == 0) { |
||||||
|
response.message = "此权限尚未开放,请勿越权访问"; |
||||||
|
} |
||||||
|
showMessage("error", response.message, false, noMsg); |
||||||
|
console.log(response.error); |
||||||
|
resolve(false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function handError(err, reject, noMsg, noLoading){ |
||||||
|
if(!noLoading){ |
||||||
|
loading.stop(); |
||||||
|
} |
||||||
|
showMessage("error", "后台连接失败,网络异常!", false, noMsg); |
||||||
|
reject(err); |
||||||
|
} |
||||||
|
|
||||||
|
function upload(file, url){ |
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
let param = new FormData() // 创建form对象
|
||||||
|
param.append('file', file) // 通过append向form对象添加数据
|
||||||
|
param.append('chunk', '0') // 添加form表单中其他数据
|
||||||
|
let config = { |
||||||
|
headers: {'Content-Type': 'multipart/form-data'} |
||||||
|
} |
||||||
|
_axios.post(url, param, config).then( |
||||||
|
response => { |
||||||
|
handResponse(response, resolve, false, false); |
||||||
|
}, |
||||||
|
err => { |
||||||
|
handError(err, reject, false, false); |
||||||
|
} |
||||||
|
); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function download(fileName, url, data = {}, callBack) { |
||||||
|
loading.start(); |
||||||
|
_axios({ |
||||||
|
method: "post", |
||||||
|
url: url, // 请求地址
|
||||||
|
data: data, // 参数
|
||||||
|
responseType: "blob" // 表明返回服务器返回的数据类型
|
||||||
|
}).then( |
||||||
|
response => { |
||||||
|
loading.stop(); |
||||||
|
const data = response.data; |
||||||
|
const reader = new FileReader() as any; |
||||||
|
reader.readAsText(data); |
||||||
|
reader.onload = function() { |
||||||
|
try { |
||||||
|
const result = JSON.parse(reader.result); |
||||||
|
if (typeof result === "object") { |
||||||
|
showMessage("error", result.message, false, false); |
||||||
|
if (callBack != null) { |
||||||
|
callBack(false); |
||||||
|
} |
||||||
|
return; |
||||||
|
} |
||||||
|
} catch (err) {} |
||||||
|
const blob = new Blob([data], { |
||||||
|
type: "application/vnd.ms-excel" |
||||||
|
}); |
||||||
|
if (window.navigator.msSaveOrOpenBlob) { |
||||||
|
navigator.msSaveBlob(blob, fileName); |
||||||
|
} else { |
||||||
|
const link = document.createElement("a"); |
||||||
|
link.href = window.URL.createObjectURL(blob); |
||||||
|
link.download = fileName; |
||||||
|
link.click(); |
||||||
|
window.URL.revokeObjectURL(link.href); |
||||||
|
} |
||||||
|
if (callBack != null) { |
||||||
|
callBack(true); |
||||||
|
} |
||||||
|
}; |
||||||
|
}, |
||||||
|
err => { |
||||||
|
loading.stop(); |
||||||
|
showMessage("error", "下载失败,网络异常!", false, false); |
||||||
|
if (callBack != null) { |
||||||
|
callBack(false); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
function showMessage(type, info, unClose, noMsg) { |
||||||
|
const vue = Vue as any; |
||||||
|
if (noMsg) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (curMsg != null) { |
||||||
|
curMsg.close(); |
||||||
|
} |
||||||
|
const tmp = Message({ |
||||||
|
type: type, |
||||||
|
showClose: true, |
||||||
|
message: info, |
||||||
|
duration: 3000 |
||||||
|
}); |
||||||
|
if (!unClose) { |
||||||
|
curMsg = tmp; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function showNotify(type, title, message, position) { |
||||||
|
const vue = Vue as any; |
||||||
|
if (position == null) { |
||||||
|
position = "top-right"; |
||||||
|
} |
||||||
|
vue.$notify({ |
||||||
|
title: title, |
||||||
|
type: type, |
||||||
|
message: message, |
||||||
|
position: position, |
||||||
|
duration: 0 |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
Vue.prototype.$post = post; |
||||||
|
Vue.prototype.$get = get; |
||||||
|
Vue.prototype.$put = put; |
||||||
|
Vue.prototype.$delete = delate; |
||||||
|
Vue.prototype.$upload = upload; |
||||||
|
Vue.prototype.$download = download; |
||||||
|
Vue.prototype.$showMessage = showMessage; |
||||||
|
Vue.prototype.$showNotify = showNotify; |
||||||
|
|
||||||
|
export default { |
||||||
|
post, |
||||||
|
get, |
||||||
|
put, |
||||||
|
delate, |
||||||
|
upload, |
||||||
|
download, |
||||||
|
showMessage, |
||||||
|
showNotify |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
import Vue from 'vue' |
||||||
|
import Element from 'element-ui' |
||||||
|
import 'element-ui/lib/theme-chalk/index.css' |
||||||
|
|
||||||
|
let count = 0 |
||||||
|
let ld = null |
||||||
|
|
||||||
|
const start = () => { |
||||||
|
if (count === 0) { |
||||||
|
ld = Element.Loading.service({ |
||||||
|
lock: true, |
||||||
|
text: 'Loading', |
||||||
|
spinner: 'el-icon-loading', |
||||||
|
background: 'rgba(0, 0, 0, 0.3)' |
||||||
|
}) |
||||||
|
} |
||||||
|
count++ |
||||||
|
} |
||||||
|
|
||||||
|
const stop = () => { |
||||||
|
if (count <= 0) { |
||||||
|
return |
||||||
|
} |
||||||
|
count-- |
||||||
|
if (count === 0) { |
||||||
|
ld.close() |
||||||
|
} |
||||||
|
} |
||||||
|
Vue.prototype.$start = start |
||||||
|
Vue.prototype.$stop = stop |
||||||
|
Vue.use(Element) |
||||||
|
|
||||||
|
const icons = [ |
||||||
|
'el-icon-s-platform', 'el-icon-user-solid', 'el-icon-user', 'el-icon-unlock', 'el-icon-notebook-2', 'el-icon-school', |
||||||
|
'el-icon-check', 'el-icon-video-play', 'el-icon-s-tools', 'el-icon-setting', 'el-icon-message-solid', 'el-icon-bell', |
||||||
|
'el-icon-mobile-phone', 'el-icon-map-location', 'el-icon-location', 'el-icon-document', 'el-icon-s-check', 'el-icon-data-analysis', |
||||||
|
'el-icon-view', 'el-icon-s-home', 'el-icon-office-building', 'el-icon-picture', 'el-icon-odometer', 'el-icon-s-data', |
||||||
|
'el-icon-tickets', 'el-icon-delete-solid', 'el-icon-phone-outline', 'el-icon-phone', 'el-icon-star-on', 'el-icon-star-off', |
||||||
|
'el-icon-warning', 'el-icon-upload', 'el-icon-download', 'el-icon-s-custom', 'el-icon-house', 'el-icon-message', 'el-icon-thumb', |
||||||
|
'el-icon-search', 'el-icon-collection' |
||||||
|
] |
||||||
|
|
||||||
|
export default { |
||||||
|
start, |
||||||
|
stop, |
||||||
|
icons |
||||||
|
} |
@ -0,0 +1,56 @@ |
|||||||
|
import store from "@/store"; |
||||||
|
import {showMessage} from "./axios"; |
||||||
|
let websock = null; |
||||||
|
let onMessage = ""; |
||||||
|
let connect = false; |
||||||
|
|
||||||
|
function init(url, cb) { |
||||||
|
if (typeof(WebSocket) === "undefined") { |
||||||
|
showMessage("error", "您的浏览器不支持socket"); |
||||||
|
return; |
||||||
|
} |
||||||
|
onMessage = cb; |
||||||
|
websock = new WebSocket(url); |
||||||
|
websock.onopen = websockOpen; |
||||||
|
websock.onclose = websockClose; |
||||||
|
websock.onerror = websockError; |
||||||
|
websock.onmessage = websockMessage; |
||||||
|
} |
||||||
|
|
||||||
|
function send(msg) { |
||||||
|
if (websock == null || !connect) { |
||||||
|
setTimeout(() => send(msg), 500) |
||||||
|
}else{ |
||||||
|
websock.send(JSON.stringify(msg)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function close(){ |
||||||
|
if(websock){ |
||||||
|
websock.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function websockOpen() { |
||||||
|
connect = true; |
||||||
|
} |
||||||
|
|
||||||
|
function websockClose() { |
||||||
|
connect = false; |
||||||
|
store.commit("logout"); |
||||||
|
} |
||||||
|
|
||||||
|
function websockError() { |
||||||
|
showMessage("error", "后台通讯失败,请联系相关人员处理"); |
||||||
|
} |
||||||
|
|
||||||
|
function websockMessage(e) { |
||||||
|
const data = JSON.parse(e.data); |
||||||
|
store.commit(onMessage, data); |
||||||
|
} |
||||||
|
|
||||||
|
export default { |
||||||
|
init, |
||||||
|
send, |
||||||
|
close |
||||||
|
} |
@ -0,0 +1,139 @@ |
|||||||
|
import http from "../plugins/axios"; |
||||||
|
|
||||||
|
const fakePath = require("@/assets/image/fake.png"); |
||||||
|
const fakeIcon = new BMap.Icon(fakePath, new BMap.Size(21, 31), { |
||||||
|
offset: new BMap.Size(10, 25) |
||||||
|
}); |
||||||
|
const locatePath = require("@/assets/image/locate.png"); |
||||||
|
const locateIcon = new BMap.Icon(locatePath, new BMap.Size(21, 31), { |
||||||
|
offset: new BMap.Size(10, 25) |
||||||
|
}); |
||||||
|
const dronePath = require("@/assets/drone/drone.gif"); |
||||||
|
const droneIcon = new BMap.Icon(dronePath, new BMap.Size(80, 80), { |
||||||
|
offset: new BMap.Size(10, 25) |
||||||
|
}); |
||||||
|
const circleOptions = { |
||||||
|
strokeColor: 'yellow', |
||||||
|
strokeWeight: 1, |
||||||
|
strokeOpacity: 0.5, |
||||||
|
fillColor: 'yellow', |
||||||
|
fillOpacity: 0.1 |
||||||
|
}; |
||||||
|
//圆的半径,单位为米
|
||||||
|
let radius = 100; |
||||||
|
http.get("public/get/circle/conf").then(rsp => { |
||||||
|
if (rsp) { |
||||||
|
radius = rsp[0]; |
||||||
|
circleOptions.fillOpacity = rsp[1]; |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
function paintLocation(map, data) { |
||||||
|
for (let i = 0; i < data.length; i++) { |
||||||
|
const loc = data[i]; |
||||||
|
if (loc.lng == 0 || loc.lat == 0) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
const point = new BMap.Point(loc.lng, loc.lat); |
||||||
|
const marker = createMarker(loc); |
||||||
|
const text = "手机号码:--<br\>采集时间:" + loc.time + "<br\>经纬度:" + loc.lng + ", " + loc.lat + "<br\>场强:" + loc.rssi; |
||||||
|
marker.addEventListener("click", function() { |
||||||
|
map.closeInfoWindow(); |
||||||
|
openInfo(map, loc, text) |
||||||
|
}); |
||||||
|
map.addOverlay(marker); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
function paintTrack(map, data) { |
||||||
|
for (let i = 0; i < data.length; i++) { |
||||||
|
const track = data[i]; |
||||||
|
const point = new BMap.Point(track.lng, track.lat); |
||||||
|
const marker = createMarker(track, i); |
||||||
|
const text = "手机号码:--<br\>采集时间:" + track.time + "<br\>经度:" + track.lng + "<br\>纬度:" + track.lat; |
||||||
|
marker.addEventListener("click", function() { |
||||||
|
map.closeInfoWindow(); |
||||||
|
openInfo(map, track, text) |
||||||
|
}); |
||||||
|
if (marker.label) { |
||||||
|
marker.label.addEventListener("click", function() { |
||||||
|
map.closeInfoWindow(); |
||||||
|
openInfo(map, track, text) |
||||||
|
}); |
||||||
|
map.addOverlay(marker.label); |
||||||
|
} |
||||||
|
map.addOverlay(marker); |
||||||
|
if (i == data.length - 1) { |
||||||
|
map.centerAndZoom(point, 18); |
||||||
|
openInfo(map, track, text) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function createMarker(row, i) { |
||||||
|
const point = new BMap.Point(row.lng, row.lat); |
||||||
|
let marker; |
||||||
|
if (row.rssi) { |
||||||
|
marker = new BMap.Marker(point, { |
||||||
|
icon: locateIcon |
||||||
|
}); |
||||||
|
setLabel(marker, row.rssi - 1); |
||||||
|
} else if (row.trust == 0) { |
||||||
|
// marker = new BMap.Circle(point, radius, circleOptions);
|
||||||
|
// marker.label = new BMap.Marker(marker.getCenter(), {
|
||||||
|
// icon: fakeIcon
|
||||||
|
// });
|
||||||
|
marker = new BMap.Marker(point, { |
||||||
|
icon: fakeIcon |
||||||
|
}); |
||||||
|
marker.label = new BMap.Circle(marker.getPosition(), radius, circleOptions); |
||||||
|
setLabel(marker, i); |
||||||
|
} else { |
||||||
|
marker = new BMap.Marker(point); |
||||||
|
setLabel(marker, i); |
||||||
|
} |
||||||
|
return marker; |
||||||
|
} |
||||||
|
|
||||||
|
function addLable(marker, i) { |
||||||
|
setLabel(marker.label, i); |
||||||
|
} |
||||||
|
|
||||||
|
function setLabel(marker, i) { |
||||||
|
const label = new BMap.Label(i + 1, { |
||||||
|
offset: new BMap.Size(2, 5) |
||||||
|
}); |
||||||
|
label.setStyle({ |
||||||
|
backgroundColor: "none", |
||||||
|
color: "black", |
||||||
|
border: '0px', |
||||||
|
borderRadius: "50%", |
||||||
|
height: "13px", |
||||||
|
width: "13px" |
||||||
|
}); |
||||||
|
marker.setLabel(label); |
||||||
|
} |
||||||
|
|
||||||
|
function openInfo(map, row, text) { |
||||||
|
const center = new BMap.Point(row.lng, row.lat) |
||||||
|
map.setCenter(center); |
||||||
|
const opts = { |
||||||
|
width: 250, |
||||||
|
height: 100, |
||||||
|
title: 'IMSI:' + row.imsi |
||||||
|
} |
||||||
|
if (!text) { |
||||||
|
text = "手机号码:--<br\>初次上报时间:" + row.firstTime + "<br\>最近上报时间:" + row.time + "<br\>经纬度:" + row.lng + "," + row.lat; |
||||||
|
} |
||||||
|
const infoWindow = new BMap.InfoWindow(text, opts); |
||||||
|
map.openInfoWindow(infoWindow, center); |
||||||
|
} |
||||||
|
|
||||||
|
export { |
||||||
|
createMarker, |
||||||
|
paintTrack, |
||||||
|
openInfo, |
||||||
|
droneIcon, |
||||||
|
paintLocation |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
const weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'] |
||||||
|
|
||||||
|
const formatterDateTime = function (date, type) { |
||||||
|
if (date == null) { |
||||||
|
date = new Date() |
||||||
|
} |
||||||
|
const month = date.getMonth() < 9 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 |
||||||
|
const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() |
||||||
|
const hour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() |
||||||
|
const minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() |
||||||
|
const second = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() |
||||||
|
switch (type) { |
||||||
|
case 0: |
||||||
|
return date.getFullYear() + '年' + month + '月' + day + '日' + hour + '⑩' + minute + '分' + second + '秒' |
||||||
|
} |
||||||
|
return date.getFullYear() + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second |
||||||
|
} |
||||||
|
|
||||||
|
const formatterDate = function (date, type) { |
||||||
|
if (date == null) { |
||||||
|
date = new Date() |
||||||
|
} |
||||||
|
const month = date.getMonth() < 9 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 |
||||||
|
const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() |
||||||
|
switch (type) { |
||||||
|
case 0: |
||||||
|
return date.getFullYear() + '年' + month + '月' + day + '日' |
||||||
|
} |
||||||
|
return date.getFullYear() + '-' + month + '-' + day |
||||||
|
} |
||||||
|
|
||||||
|
const formatterTime = function (date, type) { |
||||||
|
if (date == null) { |
||||||
|
date = new Date() |
||||||
|
} |
||||||
|
const month = date.getMonth() < 9 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 |
||||||
|
switch (type) { |
||||||
|
case 0: |
||||||
|
return hour + '⑩' + minute + '分' + second + '秒' |
||||||
|
} |
||||||
|
return date.getFullYear() + '-' + month |
||||||
|
} |
||||||
|
|
||||||
|
const formatterWeekDay = function (date, type) { |
||||||
|
if (date == null) { |
||||||
|
date = new Date() |
||||||
|
} |
||||||
|
return weeks[date.getDay()] |
||||||
|
} |
||||||
|
export { |
||||||
|
formatterDateTime, |
||||||
|
formatterDate, |
||||||
|
formatterTime, |
||||||
|
formatterWeekDay |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
import * as validate from './validate' |
||||||
|
|
||||||
|
function getValidator(required, validateName, number) { |
||||||
|
const arr = [] |
||||||
|
if (required != null) { |
||||||
|
arr.push({ |
||||||
|
required: true, |
||||||
|
message: required, |
||||||
|
trigger: 'blur' |
||||||
|
}) |
||||||
|
} |
||||||
|
if (validateName != null) { |
||||||
|
arr.push({ |
||||||
|
validator: validate[validateName], |
||||||
|
trigger: 'blur' |
||||||
|
}) |
||||||
|
} |
||||||
|
if (number) { |
||||||
|
arr.push({ |
||||||
|
type: 'number', |
||||||
|
min: 0, |
||||||
|
message: '请输入正确的数字', |
||||||
|
trigger: 'blur' |
||||||
|
}) |
||||||
|
} |
||||||
|
return arr |
||||||
|
} |
||||||
|
|
||||||
|
const login = { |
||||||
|
userId: getValidator('请输入用户名'), |
||||||
|
password: getValidator('请输入密码') |
||||||
|
} |
||||||
|
|
||||||
|
const dictionary = { |
||||||
|
code: getValidator('请输入字典编号'), |
||||||
|
name: getValidator('请输入字典名称'), |
||||||
|
visitedNetworkAddress: getValidator('请选择字典状态') |
||||||
|
} |
||||||
|
|
||||||
|
const app = { |
||||||
|
name : getValidator('请输入APP名称'), |
||||||
|
itemId : getValidator('请输入授权项编号'), |
||||||
|
type : getValidator('请选择授权项类型') |
||||||
|
} |
||||||
|
|
||||||
|
const customer = { |
||||||
|
code : getValidator('请输入客户编号'), |
||||||
|
name : getValidator('请输入客户名称'), |
||||||
|
contacter : getValidator('请输入联系人'), |
||||||
|
phone : getValidator('请输入联系人号码') |
||||||
|
} |
||||||
|
|
||||||
|
const author = { |
||||||
|
custCode : getValidator('请选择客户'), |
||||||
|
fingerprint : getValidator('请输入指纹信息'), |
||||||
|
key1 : getValidator('请选择Code1'), |
||||||
|
key1 : getValidator('请选择Code2') |
||||||
|
} |
||||||
|
|
||||||
|
const client = { |
||||||
|
authorize : getValidator('请选择授权中心'), |
||||||
|
appId : getValidator('请选择授权APP'), |
||||||
|
num : getValidator('请输入授权数量'), |
||||||
|
keyId : getValidator('请选择户端秘钥') |
||||||
|
} |
||||||
|
|
||||||
|
const key = { |
||||||
|
type : getValidator('请选择秘钥类型'), |
||||||
|
remark : getValidator('请输入秘钥名称') |
||||||
|
} |
||||||
|
|
||||||
|
export { |
||||||
|
login, |
||||||
|
dictionary, |
||||||
|
app, |
||||||
|
customer, |
||||||
|
author, |
||||||
|
client, |
||||||
|
key |
||||||
|
} |
@ -0,0 +1,233 @@ |
|||||||
|
function password (rule, value, callback) { |
||||||
|
if (value == null || value === '') { |
||||||
|
callback(new Error('请输入密码')) |
||||||
|
} else if (value.length < 8 || value.length > 16) { |
||||||
|
callback(new Error('密码长度为:8~16位')) |
||||||
|
} else if (!new RegExp('^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).*$').test(value)) { |
||||||
|
callback(new Error('密码至少包含大小写字母和数字')) |
||||||
|
} else if (!new RegExp('^[^ ]+$').test(value)) { |
||||||
|
callback(new Error('密码不能包含空格')) |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function code (rule, value, callback) { |
||||||
|
if (value == null || value == '') { |
||||||
|
callback(new Error('验证码不能为空')) |
||||||
|
} else if (!new RegExp('^[0-9]+$').test(value)) { |
||||||
|
callback(new Error('验证码只能为数字')) |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function email (rule, value, callback) { |
||||||
|
if (value != null && value.length != 0) { |
||||||
|
if ( |
||||||
|
!new RegExp( |
||||||
|
/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/ |
||||||
|
).test(value) |
||||||
|
) { |
||||||
|
callback(new Error('请输入正确的电子邮箱')) |
||||||
|
} |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function phone (rule, value, callback) { |
||||||
|
if (value != null && value.length != 0) { |
||||||
|
if ( |
||||||
|
!new RegExp( |
||||||
|
'^(0|86|17951)?(13[0-9]|15[012356789]|17[0135678]|18[0-9]|14[57])[0-9]{8}$' |
||||||
|
).test(value) |
||||||
|
) { |
||||||
|
callback(new Error('请输入正确的手机号码')) |
||||||
|
} |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function imsi (rule, value, callback) { |
||||||
|
// if(value != null && value.length != 0){
|
||||||
|
// }
|
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function userName (rule, value, callback) { |
||||||
|
if (value != null && value.length != 0) { |
||||||
|
if (!new RegExp('^[a-zA-Z0-9]{6,16}$').test(value)) { |
||||||
|
callback(new Error('用户名由字母,数字组成,长度6-16之间')) |
||||||
|
} |
||||||
|
if (/(^\_)|(\__)|(\_+$)/.test(value)) { |
||||||
|
callback(new Error("用户名首尾不能出现下划线'_'")) |
||||||
|
} |
||||||
|
if (!new RegExp('^[^ ]+$').test(value)) { |
||||||
|
callback(new Error('用户名不能包含空格')) |
||||||
|
} |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function name (rule, value, callback) { |
||||||
|
if (value != null && value.length != 0) { |
||||||
|
if (!new RegExp('^[a-zA-Z\u4e00-\u9fa5]{1,10}$').test(value)) { |
||||||
|
callback(new Error('姓名由汉字或字母组成,且长度不超过10')) |
||||||
|
} |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function idCard (rule, value, callback) { |
||||||
|
if (value != null && value.length != 0) { |
||||||
|
let iSum = 0 |
||||||
|
const aCity = { |
||||||
|
11: '北京', |
||||||
|
12: '天津', |
||||||
|
13: '河北', |
||||||
|
14: '山西', |
||||||
|
15: '内蒙古', |
||||||
|
21: '辽宁', |
||||||
|
22: '吉林', |
||||||
|
23: '黑龙江', |
||||||
|
31: '上海', |
||||||
|
32: '江苏', |
||||||
|
33: '浙江', |
||||||
|
34: '安徽', |
||||||
|
35: '福建', |
||||||
|
36: '江西', |
||||||
|
37: '山东', |
||||||
|
41: '河南', |
||||||
|
42: '湖北', |
||||||
|
43: '湖南', |
||||||
|
44: '广东', |
||||||
|
45: '广西', |
||||||
|
46: '海南', |
||||||
|
50: '重庆', |
||||||
|
51: '四川', |
||||||
|
52: '贵州', |
||||||
|
53: '云南', |
||||||
|
54: '西藏', |
||||||
|
61: '陕西', |
||||||
|
62: '甘肃', |
||||||
|
63: '青海', |
||||||
|
64: '宁夏', |
||||||
|
65: '新疆', |
||||||
|
71: '台湾', |
||||||
|
81: '香港', |
||||||
|
82: '澳门', |
||||||
|
91: '国外' |
||||||
|
} |
||||||
|
if (!/^\d{17}(\d|x)$/i.test(value)) { |
||||||
|
callback(new Error('你输入的身份证长度或格式错误')) |
||||||
|
} |
||||||
|
value = value.replace(/x$/i, 'a') |
||||||
|
if (aCity[parseInt(value.substr(0, 2))] == null) { |
||||||
|
callback(new Error('你的身份证地区非法')) |
||||||
|
} |
||||||
|
|
||||||
|
const sBirthday = |
||||||
|
value.substr(6, 4) + |
||||||
|
'-' + |
||||||
|
Number(value.substr(10, 2)) + |
||||||
|
'-' + |
||||||
|
Number(value.substr(12, 2)) |
||||||
|
const d = new Date(sBirthday.replace(/-/g, '/')) |
||||||
|
if ( |
||||||
|
sBirthday != |
||||||
|
d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() |
||||||
|
) { |
||||||
|
callback(new Error('身份证上的出生日期非法')) |
||||||
|
} |
||||||
|
for (let i = 17; i >= 0; i--) { iSum += (Math.pow(2, i) % 11) * parseInt(value.charAt(17 - i), 11) } |
||||||
|
if (iSum % 11 != 1) { |
||||||
|
callback(new Error('你输入的身份证号非法')) |
||||||
|
} |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function devName (rule, value, callback) { |
||||||
|
console.log(rule) |
||||||
|
if (value == null || value.length == 0 || value == '') { |
||||||
|
callback(new Error('请输入设备名称')) |
||||||
|
} |
||||||
|
if (!new RegExp('^[a-zA-Z0-9\u4e00-\u9fa5]{1,10}$').test(value)) { |
||||||
|
callback(new Error('设备名称由汉字,字母,数字组成,且长度不能超过10')) |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function devId (rule, value, callback) { |
||||||
|
if (value == null || value.length == 0 || value == '') { |
||||||
|
callback(new Error('请输入设备编号')) |
||||||
|
} |
||||||
|
if (!new RegExp(/^[1-9]\d{0,8}$/).test(value)) { |
||||||
|
callback(new Error('设备编号由数字组成,且长度不能超过9,首位不能为0')) |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function ipv4 (rule, value, callback) { |
||||||
|
if (value != null && value.length != 0) { |
||||||
|
if ( |
||||||
|
!new RegExp(/^((25[0-5]|2[0-4]\d|[01]?\d\d?)($|(?!\.$)\.)){4}$/).test( |
||||||
|
value |
||||||
|
) |
||||||
|
) { |
||||||
|
callback(new Error('错误的IPV4地址格式')) |
||||||
|
} |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function lon (rule, value, callback) { |
||||||
|
if ( |
||||||
|
!new RegExp( |
||||||
|
/^-?((0|1?[0-7]?[0-9]?)(([.][0-9]{1,6})?)|180(([.][0]{1,6})?))$/ |
||||||
|
).test(value) |
||||||
|
) { |
||||||
|
callback(new Error('请输入正确的经度')) |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function lat (rule, value, callback) { |
||||||
|
if ( |
||||||
|
!new RegExp( |
||||||
|
/^-?((0|[1-8]?[0-9]?)(([.][0-9]{1,6})?)|90(([.][0]{1,6})?))$/ |
||||||
|
).test(value) |
||||||
|
) { |
||||||
|
callback(new Error('请输入正确的纬度')) |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
function number (rule, value, callback) { |
||||||
|
if (!new RegExp(/^[1-9][0-9]*$/).test(value)) { |
||||||
|
callback(new Error('请输入正整数')) |
||||||
|
} |
||||||
|
const num = parseInt(value) |
||||||
|
if (rule.min != null && num < rule.min) { |
||||||
|
callback(new Error('输入最小值为' + rule.min)) |
||||||
|
} |
||||||
|
if (rule.max != null && num > rule.max) { |
||||||
|
callback(new Error('输入最大值为' + rule.max)) |
||||||
|
} |
||||||
|
callback() |
||||||
|
} |
||||||
|
|
||||||
|
export { |
||||||
|
password, |
||||||
|
code, |
||||||
|
email, |
||||||
|
phone, |
||||||
|
imsi, |
||||||
|
userName, |
||||||
|
name, |
||||||
|
idCard, |
||||||
|
devName, |
||||||
|
devId, |
||||||
|
ipv4, |
||||||
|
lon, |
||||||
|
lat, |
||||||
|
number |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
export default { |
||||||
|
|
||||||
|
init(context){ |
||||||
|
context.commit('getUserInfo'); |
||||||
|
context.commit('getCfg'); |
||||||
|
context.commit('updateState', { |
||||||
|
prop: 'showHeader', |
||||||
|
value: true |
||||||
|
}) |
||||||
|
context.commit('initSizes') |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
import Vue from 'vue' |
||||||
|
import Vuex from 'vuex' |
||||||
|
import state from './state' |
||||||
|
import mutations from './mutations.js' |
||||||
|
import actions from './actions.js' |
||||||
|
import modules from './modules.js' |
||||||
|
|
||||||
|
Vue.use(Vuex) |
||||||
|
|
||||||
|
export default new Vuex.Store({ |
||||||
|
state, |
||||||
|
mutations, |
||||||
|
actions, |
||||||
|
modules |
||||||
|
}) |
@ -0,0 +1,175 @@ |
|||||||
|
import http from '../static/plugins/axios' |
||||||
|
import websocket from '../static/plugins/websocket' |
||||||
|
import vue from '../main' |
||||||
|
import Vue from 'vue' |
||||||
|
|
||||||
|
let interval = null; |
||||||
|
const urls = { |
||||||
|
info: 'public/info', |
||||||
|
dict: 'public/get/dict', |
||||||
|
logout: 'public/logout', |
||||||
|
host: 'public/host' |
||||||
|
} |
||||||
|
|
||||||
|
function stop() { |
||||||
|
if (interval == null) { |
||||||
|
return |
||||||
|
} |
||||||
|
clearInterval(interval) |
||||||
|
interval = null |
||||||
|
} |
||||||
|
|
||||||
|
function start() { |
||||||
|
stop() |
||||||
|
interval = setInterval(() => { |
||||||
|
http.get(urls.info, null, true, true).then(rsp => { |
||||||
|
if (!rsp) { |
||||||
|
stop() |
||||||
|
vue.$router.push('/login') |
||||||
|
} |
||||||
|
}) |
||||||
|
}, 5000) |
||||||
|
} |
||||||
|
|
||||||
|
function open(userName) { |
||||||
|
let url = "ws://"; |
||||||
|
if (process.env.VUE_APP_BASE_URL) { |
||||||
|
url += process.env.VUE_APP_BASE_URL; |
||||||
|
} else { |
||||||
|
url += window.location.hostname; |
||||||
|
const port = window.location.port; |
||||||
|
if (port != null && port != '') { |
||||||
|
url += (":" + port); |
||||||
|
} |
||||||
|
} |
||||||
|
url = url + "/webSocket/" + userName; |
||||||
|
websocket.init(url, "websockMessage"); |
||||||
|
} |
||||||
|
|
||||||
|
export default { |
||||||
|
updateState(state, param) { |
||||||
|
state[param.prop] = param.value; |
||||||
|
}, |
||||||
|
|
||||||
|
initSizes(state) { |
||||||
|
const height = window.innerHeight; |
||||||
|
const width = window.innerWidth; |
||||||
|
const loginHeight = 350; |
||||||
|
const loginWidth = 450; |
||||||
|
const navHead = state.showHeader ? 80 : 0; |
||||||
|
const map = { |
||||||
|
medium: 50, |
||||||
|
small: 42, |
||||||
|
mini: 35 |
||||||
|
}; |
||||||
|
const head = map[state.size] ? map[state.size] : 60; |
||||||
|
const pd = 0; |
||||||
|
const page = 37; |
||||||
|
Vue.set(state.sizes, 'fullHeight', height + 'px'); |
||||||
|
Vue.set(state.sizes, 'loginHeight', loginHeight + 'px'); |
||||||
|
Vue.set(state.sizes, 'loginWidth', loginWidth + 'px'); |
||||||
|
Vue.set(state.sizes, 'loginTop', (height - loginHeight) * 0.4 + 'px'); |
||||||
|
Vue.set(state.sizes, 'loginLeft', (width - loginWidth) * 0.49 + 'px'); |
||||||
|
Vue.set(state.sizes, 'headHeight', navHead + 'px'); |
||||||
|
Vue.set(state.sizes, 'mainHead', head + 'px'); |
||||||
|
Vue.set(state.sizes, 'mainHeight', height - navHead + 'px'); |
||||||
|
Vue.set(state.sizes, 'tableHei', height - navHead - head - pd); |
||||||
|
Vue.set(state.sizes, 'pTableHei', state.sizes.tableHei - page); |
||||||
|
}, |
||||||
|
|
||||||
|
getUserInfo(state) { |
||||||
|
http.get(urls.info).then(response => { |
||||||
|
if (response) { |
||||||
|
state.userInfo = response; |
||||||
|
state.menuGroups = [{ |
||||||
|
name: '主页', |
||||||
|
id: 'home', |
||||||
|
child: [] |
||||||
|
}]; |
||||||
|
if (response.permission == '1') { |
||||||
|
state.menuGroups.push({ |
||||||
|
name: '系统管理', |
||||||
|
id: 'sys', |
||||||
|
child: [{ |
||||||
|
name: '配置管理', |
||||||
|
id: 'config' |
||||||
|
}, { |
||||||
|
name: '用户管理', |
||||||
|
id: 'user' |
||||||
|
}] |
||||||
|
}) |
||||||
|
} |
||||||
|
start() |
||||||
|
// open(response.userId);
|
||||||
|
} else { |
||||||
|
vue.$router.push('/login') |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
vue.$router.push('/login') |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
websockMessage(state, data) { |
||||||
|
const handler = state.handlers[data.type]; |
||||||
|
if (handler != null) { |
||||||
|
handler(data.data); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
getCfg(state) { |
||||||
|
http.get(urls.host).then(rsp => { |
||||||
|
state.host = rsp; |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
getDictMap(state, codes, callBack) { |
||||||
|
if (codes == null) { |
||||||
|
return |
||||||
|
} |
||||||
|
const arr = [] |
||||||
|
for (let i = 0; i < codes.length; i++) { |
||||||
|
if (Object.keys(state.dict).indexOf(codes[i]) == -1) { |
||||||
|
arr.push(codes[i]) |
||||||
|
} |
||||||
|
} |
||||||
|
if (arr.length == 0) { |
||||||
|
return |
||||||
|
} |
||||||
|
http.post(urls.dict, arr).then(function(response) { |
||||||
|
if (response) { |
||||||
|
for (let i = 0; i < arr.length; i++) { |
||||||
|
const key = arr[i] |
||||||
|
state.dict[key] = {} |
||||||
|
const dicts = response[key] |
||||||
|
if (dicts == null) { |
||||||
|
continue |
||||||
|
} |
||||||
|
for (let j = 0; j < dicts.length; j++) { |
||||||
|
const tmp = dicts[j] |
||||||
|
const num = parseInt(tmp.code) |
||||||
|
if (!isNaN(num)) { |
||||||
|
state.dict[key][num] = tmp.name |
||||||
|
} else { |
||||||
|
state.dict[key][tmp.code] = tmp.name |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (callBack != null) { |
||||||
|
callBack() |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
logout(state) { |
||||||
|
http.get(urls.logout).then(response => { |
||||||
|
if (response) { |
||||||
|
vue.$router.push('/login') |
||||||
|
state.userInfo = {} |
||||||
|
} |
||||||
|
}); |
||||||
|
websocket.close(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
export default { |
||||||
|
menuGroups: [], |
||||||
|
sizes: {}, |
||||||
|
userInfo: {}, |
||||||
|
showHeader: true, |
||||||
|
size: 'small', |
||||||
|
dict: {}, |
||||||
|
handlers: {}, |
||||||
|
host: {}, |
||||||
|
network: "traHost" |
||||||
|
} |
@ -0,0 +1,243 @@ |
|||||||
|
<template> |
||||||
|
<div id="picture"> |
||||||
|
<MainHead name="图片" :flag="flag" :terms="terms" :example="example" @query="query(1)"> |
||||||
|
<template slot="title"> |
||||||
|
<span class="network-switch"> |
||||||
|
<div class="switch-label">网络环境:</div> |
||||||
|
<el-switch v-model="$store.state.network" active-value="tertHost" inactive-value="traHost" :width="60" active-text="外网" |
||||||
|
inactive-text="内网"></el-switch> |
||||||
|
</span> |
||||||
|
</template> |
||||||
|
<template slot="header"> |
||||||
|
<el-upload class="upload-btn" :action="uploadUrl" :on-error="onError" :on-success="onSuccess" :multiple="false" |
||||||
|
:show-file-list="false"> |
||||||
|
<el-button :size="$store.state.size" type="success" icon="el-icon-upload"> |
||||||
|
上传图片 |
||||||
|
</el-button> |
||||||
|
</el-upload> |
||||||
|
</template> |
||||||
|
</MainHead> |
||||||
|
<el-row class="image-list" :style="{ height: $store.state.sizes.pTableHei + 'px' }"> |
||||||
|
<el-col v-for="(item, index) in result.rows" :xs="8" :sm="7" :md="6" :xl="4"> |
||||||
|
<el-result icon="success" :title="item.remark ? item.remark : (index + 1).toString()" |
||||||
|
:subTitle="item.time + ' ' + item.space + ' ' + item.remark"> |
||||||
|
<template slot="icon"> |
||||||
|
<el-image :src="'http//'+ $store.state.host[$store.state.network] + '/' + item.path"> |
||||||
|
</el-image> |
||||||
|
</template> |
||||||
|
<template slot="extra"> |
||||||
|
<el-button type="primary" size="mini" @click="copy(item)">复制</el-button> |
||||||
|
<el-button type="info" size="mini" @click="remark(item)">备注</el-button> |
||||||
|
<el-button type="danger" size="mini" @click="delate(item)">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-result> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
<el-pagination :current-page="example.page" :page-sizes="[10, 20, 50, 100]" :page-size="example.size" |
||||||
|
layout="total, sizes, prev, pager, next, jumper" :total="result.total" @size-change="handleSizeChange" |
||||||
|
@current-change="handleCurrentChange" /> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { |
||||||
|
Vue, |
||||||
|
Component, |
||||||
|
Prop |
||||||
|
} from "vue-property-decorator"; |
||||||
|
import Template from '@/components/template/manage.vue'; |
||||||
|
import MainHead from '@/components/template/mainHeader.vue'; |
||||||
|
|
||||||
|
@Component({ |
||||||
|
components: { |
||||||
|
Template, |
||||||
|
MainHead |
||||||
|
} |
||||||
|
}) |
||||||
|
export default class Picture extends Vue { |
||||||
|
url = 'picture'; |
||||||
|
uploadUrl = (process.env.VUE_APP_BASE_URL ? "/api/" : "/") + this.url; |
||||||
|
flag = { |
||||||
|
list: true, |
||||||
|
save: false, |
||||||
|
update: false, |
||||||
|
del: true, |
||||||
|
title: true |
||||||
|
} |
||||||
|
terms = [{ |
||||||
|
code: 'remark', |
||||||
|
desc: '备注' |
||||||
|
}, { |
||||||
|
code: 'startTime', |
||||||
|
datePicker: true, |
||||||
|
valueFormat: 'yyyy-MM-dd HH:mm:ss', |
||||||
|
type: 'datetime', |
||||||
|
desc: '开始时间' |
||||||
|
}, { |
||||||
|
code: 'endTime', |
||||||
|
datePicker: true, |
||||||
|
valueFormat: 'yyyy-MM-dd HH:mm:ss', |
||||||
|
type: 'datetime', |
||||||
|
desc: '结束时间' |
||||||
|
}] |
||||||
|
|
||||||
|
example = { |
||||||
|
page: 1, |
||||||
|
size: 20 |
||||||
|
}; |
||||||
|
result = { |
||||||
|
rows: [], |
||||||
|
total: 0 |
||||||
|
}; |
||||||
|
handleSizeChange(val) { |
||||||
|
this.example.size = val |
||||||
|
this.query() |
||||||
|
} |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.example.page = val |
||||||
|
this.query() |
||||||
|
} |
||||||
|
query(page) { |
||||||
|
const that = this |
||||||
|
if (page != null) { |
||||||
|
this.example.page = page |
||||||
|
} |
||||||
|
this.$get(that.url, that.example).then(function(response) { |
||||||
|
if (response) { |
||||||
|
that.result = response |
||||||
|
} else { |
||||||
|
that.result = { |
||||||
|
rows: [], |
||||||
|
total: 0 |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
copy(row) { |
||||||
|
const that = this; |
||||||
|
const host = this.$store.state.host[this.$store.state.network]; |
||||||
|
const path = 'http://' + host + "/" + row.path; |
||||||
|
this.$copyText(path).then(e => { |
||||||
|
that.$showMessage("success", "复制成功"); |
||||||
|
}, e => { |
||||||
|
that.$showMessage("success", "复制失败"); |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
remark(row) { |
||||||
|
const that = this |
||||||
|
this.$prompt('请输入备注信息', '备注', { |
||||||
|
confirmButtonText: '确定', |
||||||
|
cancelButtonText: '取消', |
||||||
|
inputPattern: /^[\S]{1,64}$/, |
||||||
|
inputErrorMessage: '备注不能输入空格,且长度不超过64位', |
||||||
|
distinguishCancelAndClose: true, |
||||||
|
showClose: false, |
||||||
|
beforeClose: (action, instance, done) => { |
||||||
|
if (action === 'close') { |
||||||
|
return |
||||||
|
} |
||||||
|
done() |
||||||
|
} |
||||||
|
}).then(({ |
||||||
|
value |
||||||
|
}) => { |
||||||
|
console.log(value); |
||||||
|
const param = JSON.parse(JSON.stringify(row)); |
||||||
|
param.remark = value; |
||||||
|
that.$put(that.url, param).then(rsp => { |
||||||
|
if (rsp) { |
||||||
|
row.remark = value; |
||||||
|
} |
||||||
|
}); |
||||||
|
}).catch(() => {}) |
||||||
|
} |
||||||
|
|
||||||
|
delate(row) { |
||||||
|
const that = this |
||||||
|
this.$confirm('确定要删除该图片吗?', '提示', { |
||||||
|
confirmButtonText: '确定', |
||||||
|
cancelButtonText: '取消', |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$delete(that.url, row).then(function(response) { |
||||||
|
if (response) { |
||||||
|
that.query() |
||||||
|
} |
||||||
|
}) |
||||||
|
}).catch(() => { |
||||||
|
that.showMessage('info', '已取消删除') |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
onError(err, file, fileList) { |
||||||
|
that.$showMessage('error', file.name + "上传失败", true) |
||||||
|
console.log(err); |
||||||
|
} |
||||||
|
onSuccess(response, file, fileList) { |
||||||
|
const that = this; |
||||||
|
if (response.success == false) { |
||||||
|
that.$showMessage('error', response.message, true); |
||||||
|
} else { |
||||||
|
that.$showMessage('success', response.message, true) |
||||||
|
} |
||||||
|
this.$refs.upload.clearFiles(); |
||||||
|
} |
||||||
|
|
||||||
|
getClipboardFiles(event) { |
||||||
|
let items = event.clipboardData && event.clipboardData.items; |
||||||
|
let file = null |
||||||
|
if (items && items.length) { |
||||||
|
// 检索剪切板items |
||||||
|
for (var i = 0; i < items.length; i++) { |
||||||
|
if (items[i].type.indexOf('image') !== -1) { |
||||||
|
file = items[i].getAsFile() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (file) { |
||||||
|
this.$confirm('是否要上传剪切板中复制的图片?', '提示', { |
||||||
|
confirmButtonText: '是的', |
||||||
|
cancelButtonText: '不用', |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$upload(file, this.url); |
||||||
|
}).catch(() => {}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
created() { |
||||||
|
this.query(1); |
||||||
|
document.addEventListener('paste', this.getClipboardFiles); |
||||||
|
} //生命周期 - 创建完成(可以访问当前this实例) |
||||||
|
mounted() {} //生命周期 - 挂载完成(可以访问DOM元素) |
||||||
|
beforeCreate() {} //生命周期 - 创建之前 |
||||||
|
beforeMount() {} //生命周期 - 挂载之前 |
||||||
|
beforeUpdate() {} //生命周期 - 更新之前 |
||||||
|
updated() {} //生命周期 - 更新之后 |
||||||
|
beforeDestroy() { |
||||||
|
document.removeEventListener('paste', this.getClipboardFiles); |
||||||
|
} //生命周期 - 销毁之前 |
||||||
|
destroyed() {} //生命周期 - 销毁完成 |
||||||
|
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发 |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style scoped> |
||||||
|
.upload-btn { |
||||||
|
padding-left: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.network-switch { |
||||||
|
padding-left: 20px; |
||||||
|
} |
||||||
|
.switch-label { |
||||||
|
float: left; |
||||||
|
font-size: 16px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.image-list { |
||||||
|
overflow-y: auto; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,66 @@ |
|||||||
|
<template> |
||||||
|
<div id="app" :style="{ height: $store.state.sizes.height }"> |
||||||
|
<NavHeader v-show="$store.state.showHeader" class="app-head" :style="{ height: $store.state.sizes.headHeight+'px' }" |
||||||
|
ref="header" /> |
||||||
|
<router-view class="app-main" :style="{ height: $store.state.sizes.mainHeight }" @init="init" /> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { |
||||||
|
Component, |
||||||
|
Prop, |
||||||
|
Vue, |
||||||
|
Watch |
||||||
|
} from 'vue-property-decorator' |
||||||
|
import NavHeader from '@/components/main/NavHeader'; |
||||||
|
import websoct from '@/static/plugins/websocket'; |
||||||
|
|
||||||
|
@Component({ |
||||||
|
components: { |
||||||
|
NavHeader |
||||||
|
} |
||||||
|
}) |
||||||
|
export default class App extends Vue { |
||||||
|
initSize() { |
||||||
|
this.$store.commit('initSizes') |
||||||
|
} |
||||||
|
|
||||||
|
init() { |
||||||
|
this.$store.dispatch('init'); |
||||||
|
this.$router.push('/home') |
||||||
|
if (this.$refs.header) { |
||||||
|
this.$refs.header.toHome() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
created() { |
||||||
|
this.init() |
||||||
|
this.initSize() |
||||||
|
window.onresize = this.initSize |
||||||
|
} |
||||||
|
|
||||||
|
mounted() {} // 生命周期 - 挂载完成(可以访问DOM元素) |
||||||
|
beforeCreate() {} // 生命周期 - 创建之前 |
||||||
|
beforeMount() {} // 生命周期 - 挂载之前 |
||||||
|
beforeUpdate() {} // 生命周期 - 更新之前 |
||||||
|
updated() {} // 生命周期 - 更新之后 |
||||||
|
beforeDestroy() {} // 生命周期 - 销毁之前 |
||||||
|
destroyed() {} // 生命周期 - 销毁完成 |
||||||
|
activated() {} // 如果页面有keep-alive缓存功能,这个函数会触发 |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style lang="scss"> |
||||||
|
@import '~@/assets/styles/base.scss'; |
||||||
|
@import '~@/assets/styles/size_small.scss'; |
||||||
|
// @import '~@/assets/styles/back_blue.scss'; |
||||||
|
|
||||||
|
.app-head { |
||||||
|
padding: 0px !important; |
||||||
|
} |
||||||
|
|
||||||
|
.app-main { |
||||||
|
padding: 0px 20px !important; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,124 @@ |
|||||||
|
<template> |
||||||
|
<div id="login"> |
||||||
|
<div class="loginForm" :style="{ height:$store.state.sizes.loginHeight,width:$store.state.sizes.loginWidth, |
||||||
|
'margin-top': $store.state.sizes.loginTop,'margin-left':$store.state.sizes.loginLeft}"> |
||||||
|
<el-form ref="login" class="login-form" :model="user" :rules="rules" hide-required-asterisk label-width="30px"> |
||||||
|
<div class="login-title"> |
||||||
|
图床卅 |
||||||
|
</div> |
||||||
|
<br><br> |
||||||
|
<el-form-item prop="userId"> |
||||||
|
<el-input v-model="user.userId" placeholder="用户名"> |
||||||
|
<el-button slot="prepend" icon="el-icon-user" /> |
||||||
|
</el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="password"> |
||||||
|
<el-input v-model="user.password" type="password" placeholder="密码"> |
||||||
|
<el-button slot="prepend" icon="el-icon-key" /> |
||||||
|
</el-input> |
||||||
|
</el-form-item> |
||||||
|
<br> |
||||||
|
<el-form-item> |
||||||
|
<el-button class="login-btn" type="primary" @click="loginSubmit">登录</el-button> |
||||||
|
<el-button style="float: right;" class="login-btn" type="primary" @click="reset">重置</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script lang="ts"> |
||||||
|
import { |
||||||
|
Component, |
||||||
|
Prop, |
||||||
|
Vue |
||||||
|
} from 'vue-property-decorator' |
||||||
|
import md5 from 'js-md5' |
||||||
|
import { |
||||||
|
login |
||||||
|
} from '@/static/tool/ruleControl.js' |
||||||
|
|
||||||
|
@Component |
||||||
|
export default class Login extends Vue { |
||||||
|
marginTop = (window.innerHeight - 350) * 0.4 + 'px'; |
||||||
|
user = { |
||||||
|
userId: null, |
||||||
|
password: null |
||||||
|
}; |
||||||
|
|
||||||
|
rules = login; |
||||||
|
|
||||||
|
loginSubmit() { |
||||||
|
const that = this |
||||||
|
this.$refs.login.validate((valid) => { |
||||||
|
if (valid) { |
||||||
|
const param = JSON.parse(JSON.stringify(that.user)) |
||||||
|
param.password = md5(param.password) |
||||||
|
that.$post('public/login', param).then(function(response) { |
||||||
|
if (response == true) { |
||||||
|
setTimeout(() => { |
||||||
|
that.$emit("init"); |
||||||
|
}, 300) |
||||||
|
} |
||||||
|
}) |
||||||
|
} else { |
||||||
|
return false |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
reset() { |
||||||
|
this.user = { |
||||||
|
userId: null, |
||||||
|
password: null |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
init(b) { |
||||||
|
this.$store.commit('updateState', { |
||||||
|
prop: 'showHeader', |
||||||
|
value: b |
||||||
|
}) |
||||||
|
this.$store.commit('initSizes') |
||||||
|
} |
||||||
|
|
||||||
|
created() { |
||||||
|
this.init(false); |
||||||
|
const that = this; |
||||||
|
document.onkeydown = function(e) { |
||||||
|
let ev = e || event; |
||||||
|
let key = ev.keyCode; |
||||||
|
if (key == 13) { |
||||||
|
that.loginSubmit(); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
#login { |
||||||
|
align-items: center; |
||||||
|
background: none; |
||||||
|
} |
||||||
|
|
||||||
|
.loginForm { |
||||||
|
background: none; |
||||||
|
height: 350px; |
||||||
|
width: 500px; |
||||||
|
box-shadow: 0 0 25px #cac6c6 !important; |
||||||
|
padding: 30px 30px 20px 0px; |
||||||
|
} |
||||||
|
|
||||||
|
.login-title { |
||||||
|
margin: 0px 70px 20px; |
||||||
|
font-size: 1.8rem; |
||||||
|
text-align: center; |
||||||
|
color: #2d3748; |
||||||
|
} |
||||||
|
|
||||||
|
.login-btn { |
||||||
|
margin: 0px 30px; |
||||||
|
width: 100px; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,88 @@ |
|||||||
|
<template> |
||||||
|
<div id="config"> |
||||||
|
<Template ref="template" name="配置" :url="url" :flag="flag" :terms="terms" :props="props" :rules="rules" |
||||||
|
:actions="actions"></template> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { |
||||||
|
Vue, |
||||||
|
Component, |
||||||
|
Prop |
||||||
|
} from "vue-property-decorator"; |
||||||
|
import Template from '@/components/template/manage.vue'; |
||||||
|
|
||||||
|
@Component({ |
||||||
|
components: { |
||||||
|
Template |
||||||
|
} |
||||||
|
}) |
||||||
|
export default class Config extends Vue { |
||||||
|
url = "sys/config"; |
||||||
|
flag = { |
||||||
|
list: true, |
||||||
|
save: false, |
||||||
|
update: true, |
||||||
|
del: false |
||||||
|
} |
||||||
|
rules = {}; |
||||||
|
terms = [{ |
||||||
|
code: 'cfgName', |
||||||
|
desc: '配置名称' |
||||||
|
}]; |
||||||
|
props = [{ |
||||||
|
code: 'cfgKey', |
||||||
|
name: '配置key', |
||||||
|
width: 150, |
||||||
|
readOnly: true |
||||||
|
}, { |
||||||
|
code: 'cfgName', |
||||||
|
name: '配置名称', |
||||||
|
width: 150 |
||||||
|
}, { |
||||||
|
code: 'cfgValue', |
||||||
|
name: '配置值', |
||||||
|
width: 150 |
||||||
|
}, { |
||||||
|
code: 'cfgType', |
||||||
|
name: '配置类型', |
||||||
|
width: 150, |
||||||
|
readOnly: true |
||||||
|
}, { |
||||||
|
code: 'cfgDesc', |
||||||
|
name: '配置描述', |
||||||
|
width: 200 |
||||||
|
}, { |
||||||
|
code: 'updateTime', |
||||||
|
name: '最近更新时间', |
||||||
|
width: 170, |
||||||
|
hide: true |
||||||
|
}, { |
||||||
|
code: 'updateUser', |
||||||
|
name: '最近更新用户', |
||||||
|
width: 160, |
||||||
|
hide: true |
||||||
|
// }, { |
||||||
|
// code: 'cfgStatus', |
||||||
|
// name: '配置状态', |
||||||
|
// dict: 'active_status', |
||||||
|
// width: 120 |
||||||
|
}]; |
||||||
|
actions = []; |
||||||
|
created() { |
||||||
|
// this.$store.commit('getDictMap', ['active_status']); |
||||||
|
} //生命周期 - 创建完成(可以访问当前this实例) |
||||||
|
mounted() {} //生命周期 - 挂载完成(可以访问DOM元素) |
||||||
|
beforeCreate() {} //生命周期 - 创建之前 |
||||||
|
beforeMount() {} //生命周期 - 挂载之前 |
||||||
|
beforeUpdate() {} //生命周期 - 更新之前 |
||||||
|
updated() {} //生命周期 - 更新之后 |
||||||
|
beforeDestroy() {} //生命周期 - 销毁之前 |
||||||
|
destroyed() {} //生命周期 - 销毁完成 |
||||||
|
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发 |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,39 @@ |
|||||||
|
{ |
||||||
|
"compilerOptions": { |
||||||
|
"target": "esnext", |
||||||
|
"module": "esnext", |
||||||
|
"strict": false, |
||||||
|
"jsx": "preserve", |
||||||
|
"importHelpers": true, |
||||||
|
"moduleResolution": "node", |
||||||
|
"experimentalDecorators": true, |
||||||
|
"esModuleInterop": true, |
||||||
|
"allowSyntheticDefaultImports": true, |
||||||
|
"sourceMap": true, |
||||||
|
"baseUrl": ".", |
||||||
|
"types": [ |
||||||
|
"webpack-env" |
||||||
|
], |
||||||
|
"paths": { |
||||||
|
"@/*": [ |
||||||
|
"src/*" |
||||||
|
] |
||||||
|
}, |
||||||
|
"lib": [ |
||||||
|
"esnext", |
||||||
|
"dom", |
||||||
|
"dom.iterable", |
||||||
|
"scripthost" |
||||||
|
] |
||||||
|
}, |
||||||
|
"include": [ |
||||||
|
"src/**/*.ts", |
||||||
|
"src/**/*.tsx", |
||||||
|
"src/**/*.vue", |
||||||
|
"tests/**/*.ts", |
||||||
|
"tests/**/*.tsx" |
||||||
|
], |
||||||
|
"exclude": [ |
||||||
|
"node_modules" |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
module.exports = { |
||||||
|
lintOnSave: false, |
||||||
|
publicPath: '/', |
||||||
|
chainWebpack: config => { |
||||||
|
config.module |
||||||
|
.rule('images') |
||||||
|
.use('url-loader') |
||||||
|
.loader('url-loader') |
||||||
|
.tap(options => Object.assign(options, { limit: 1 })) |
||||||
|
}, |
||||||
|
configureWebpack: { |
||||||
|
externals: { |
||||||
|
'BMap': "BMap" |
||||||
|
}, |
||||||
|
resolve: { |
||||||
|
alias: { |
||||||
|
'assets': '@/assets', |
||||||
|
'common': '@/common', |
||||||
|
'components': '@/components', |
||||||
|
'network': '@/network', |
||||||
|
'views': '@/views', |
||||||
|
'plugins': '@/plugins', |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
devServer: { |
||||||
|
proxy: { |
||||||
|
'/api': { |
||||||
|
target: 'http://'+process.env.VUE_APP_BASE_URL, |
||||||
|
// 允许跨域
|
||||||
|
changeOrigin: true, |
||||||
|
ws: true, |
||||||
|
pathRewrite: { |
||||||
|
'^/api': '' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue