提交者
Gitee
!426 修正单词拼写错误
Merge pull request !426 from 稚屿/master
正在显示
22 个修改的文件
包含
1699 行增加
和
1719 行删除
| @@ -41,8 +41,7 @@ public class DictUtils | @@ -41,8 +41,7 @@ public class DictUtils | ||
| 41 | Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key)); | 41 | Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key)); |
| 42 | if (StringUtils.isNotNull(cacheObj)) | 42 | if (StringUtils.isNotNull(cacheObj)) |
| 43 | { | 43 | { |
| 44 | - List<SysDictData> dictDatas = StringUtils.cast(cacheObj); | ||
| 45 | - return dictDatas; | 44 | + return StringUtils.cast(cacheObj); |
| 46 | } | 45 | } |
| 47 | return null; | 46 | return null; |
| 48 | } | 47 | } |
| @@ -18,8 +18,7 @@ public class ExceptionUtil | @@ -18,8 +18,7 @@ public class ExceptionUtil | ||
| 18 | { | 18 | { |
| 19 | StringWriter sw = new StringWriter(); | 19 | StringWriter sw = new StringWriter(); |
| 20 | e.printStackTrace(new PrintWriter(sw, true)); | 20 | e.printStackTrace(new PrintWriter(sw, true)); |
| 21 | - String str = sw.toString(); | ||
| 22 | - return str; | 21 | + return sw.toString(); |
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | public static String getRootErrorMessage(Exception e) | 24 | public static String getRootErrorMessage(Exception e) |
| @@ -99,9 +99,8 @@ public class ServletUtils | @@ -99,9 +99,8 @@ public class ServletUtils | ||
| 99 | * | 99 | * |
| 100 | * @param response 渲染对象 | 100 | * @param response 渲染对象 |
| 101 | * @param string 待渲染的字符串 | 101 | * @param string 待渲染的字符串 |
| 102 | - * @return null | ||
| 103 | */ | 102 | */ |
| 104 | - public static String renderString(HttpServletResponse response, String string) | 103 | + public static void renderString(HttpServletResponse response, String string) |
| 105 | { | 104 | { |
| 106 | try | 105 | try |
| 107 | { | 106 | { |
| @@ -114,7 +113,6 @@ public class ServletUtils | @@ -114,7 +113,6 @@ public class ServletUtils | ||
| 114 | { | 113 | { |
| 115 | e.printStackTrace(); | 114 | e.printStackTrace(); |
| 116 | } | 115 | } |
| 117 | - return null; | ||
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | /** | 118 | /** |
| @@ -125,13 +123,13 @@ public class ServletUtils | @@ -125,13 +123,13 @@ public class ServletUtils | ||
| 125 | public static boolean isAjaxRequest(HttpServletRequest request) | 123 | public static boolean isAjaxRequest(HttpServletRequest request) |
| 126 | { | 124 | { |
| 127 | String accept = request.getHeader("accept"); | 125 | String accept = request.getHeader("accept"); |
| 128 | - if (accept != null && accept.indexOf("application/json") != -1) | 126 | + if (accept != null && accept.contains("application/json")) |
| 129 | { | 127 | { |
| 130 | return true; | 128 | return true; |
| 131 | } | 129 | } |
| 132 | 130 | ||
| 133 | String xRequestedWith = request.getHeader("X-Requested-With"); | 131 | String xRequestedWith = request.getHeader("X-Requested-With"); |
| 134 | - if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) | 132 | + if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) |
| 135 | { | 133 | { |
| 136 | return true; | 134 | return true; |
| 137 | } | 135 | } |
| @@ -143,10 +141,6 @@ public class ServletUtils | @@ -143,10 +141,6 @@ public class ServletUtils | ||
| 143 | } | 141 | } |
| 144 | 142 | ||
| 145 | String ajax = request.getParameter("__ajax"); | 143 | String ajax = request.getParameter("__ajax"); |
| 146 | - if (StringUtils.inStringIgnoreCase(ajax, "json", "xml")) | ||
| 147 | - { | ||
| 148 | - return true; | ||
| 149 | - } | ||
| 150 | - return false; | 144 | + return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); |
| 151 | } | 145 | } |
| 152 | } | 146 | } |
| @@ -208,7 +208,6 @@ public class VerifyCodeUtils | @@ -208,7 +208,6 @@ public class VerifyCodeUtils | ||
| 208 | 208 | ||
| 209 | int period = random.nextInt(40) + 10; // 50; | 209 | int period = random.nextInt(40) + 10; // 50; |
| 210 | 210 | ||
| 211 | - boolean borderGap = true; | ||
| 212 | int frames = 20; | 211 | int frames = 20; |
| 213 | int phase = 7; | 212 | int phase = 7; |
| 214 | for (int i = 0; i < w1; i++) | 213 | for (int i = 0; i < w1; i++) |
| @@ -216,13 +215,9 @@ public class VerifyCodeUtils | @@ -216,13 +215,9 @@ public class VerifyCodeUtils | ||
| 216 | double d = (double) (period >> 1) | 215 | double d = (double) (period >> 1) |
| 217 | * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); | 216 | * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); |
| 218 | g.copyArea(i, 0, 1, h1, 0, (int) d); | 217 | g.copyArea(i, 0, 1, h1, 0, (int) d); |
| 219 | - if (borderGap) | ||
| 220 | - { | ||
| 221 | - g.setColor(color); | ||
| 222 | - g.drawLine(i, (int) d, i, 0); | ||
| 223 | - g.drawLine(i, (int) d + h1, i, h1); | ||
| 224 | - } | ||
| 225 | - | 218 | + g.setColor(color); |
| 219 | + g.drawLine(i, (int) d, i, 0); | ||
| 220 | + g.drawLine(i, (int) d + h1, i, h1); | ||
| 226 | } | 221 | } |
| 227 | } | 222 | } |
| 228 | } | 223 | } |
| @@ -2,6 +2,8 @@ package com.ruoyi.common.utils.file; | @@ -2,6 +2,8 @@ package com.ruoyi.common.utils.file; | ||
| 2 | 2 | ||
| 3 | import java.io.File; | 3 | import java.io.File; |
| 4 | import java.io.IOException; | 4 | import java.io.IOException; |
| 5 | +import java.util.Objects; | ||
| 6 | + | ||
| 5 | import org.apache.commons.io.FilenameUtils; | 7 | import org.apache.commons.io.FilenameUtils; |
| 6 | import org.springframework.web.multipart.MultipartFile; | 8 | import org.springframework.web.multipart.MultipartFile; |
| 7 | import com.ruoyi.common.config.RuoYiConfig; | 9 | import com.ruoyi.common.config.RuoYiConfig; |
| @@ -100,7 +102,7 @@ public class FileUploadUtils | @@ -100,7 +102,7 @@ public class FileUploadUtils | ||
| 100 | throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, | 102 | throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, |
| 101 | InvalidExtensionException | 103 | InvalidExtensionException |
| 102 | { | 104 | { |
| 103 | - int fileNamelength = file.getOriginalFilename().length(); | 105 | + int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length(); |
| 104 | if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) | 106 | if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) |
| 105 | { | 107 | { |
| 106 | throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); | 108 | throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); |
| @@ -112,8 +114,7 @@ public class FileUploadUtils | @@ -112,8 +114,7 @@ public class FileUploadUtils | ||
| 112 | 114 | ||
| 113 | File desc = getAbsoluteFile(baseDir, fileName); | 115 | File desc = getAbsoluteFile(baseDir, fileName); |
| 114 | file.transferTo(desc); | 116 | file.transferTo(desc); |
| 115 | - String pathFileName = getPathFileName(baseDir, fileName); | ||
| 116 | - return pathFileName; | 117 | + return getPathFileName(baseDir, fileName); |
| 117 | } | 118 | } |
| 118 | 119 | ||
| 119 | /** | 120 | /** |
| @@ -145,8 +146,7 @@ public class FileUploadUtils | @@ -145,8 +146,7 @@ public class FileUploadUtils | ||
| 145 | { | 146 | { |
| 146 | int dirLastIndex = RuoYiConfig.getProfile().length() + 1; | 147 | int dirLastIndex = RuoYiConfig.getProfile().length() + 1; |
| 147 | String currentDir = StringUtils.substring(uploadDir, dirLastIndex); | 148 | String currentDir = StringUtils.substring(uploadDir, dirLastIndex); |
| 148 | - String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName; | ||
| 149 | - return pathFileName; | 149 | + return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | /** | 152 | /** |
| @@ -161,7 +161,7 @@ public class FileUploadUtils | @@ -161,7 +161,7 @@ public class FileUploadUtils | ||
| 161 | throws FileSizeLimitExceededException, InvalidExtensionException | 161 | throws FileSizeLimitExceededException, InvalidExtensionException |
| 162 | { | 162 | { |
| 163 | long size = file.getSize(); | 163 | long size = file.getSize(); |
| 164 | - if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE) | 164 | + if (size > DEFAULT_MAX_SIZE) |
| 165 | { | 165 | { |
| 166 | throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); | 166 | throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); |
| 167 | } | 167 | } |
| @@ -228,7 +228,7 @@ public class FileUploadUtils | @@ -228,7 +228,7 @@ public class FileUploadUtils | ||
| 228 | String extension = FilenameUtils.getExtension(file.getOriginalFilename()); | 228 | String extension = FilenameUtils.getExtension(file.getOriginalFilename()); |
| 229 | if (StringUtils.isEmpty(extension)) | 229 | if (StringUtils.isEmpty(extension)) |
| 230 | { | 230 | { |
| 231 | - extension = MimeTypeUtils.getExtension(file.getContentType()); | 231 | + extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType())); |
| 232 | } | 232 | } |
| 233 | return extension; | 233 | return extension; |
| 234 | } | 234 | } |
| @@ -59,7 +59,7 @@ public class ImageUtils | @@ -59,7 +59,7 @@ public class ImageUtils | ||
| 59 | /** | 59 | /** |
| 60 | * 读取文件为字节数据 | 60 | * 读取文件为字节数据 |
| 61 | * | 61 | * |
| 62 | - * @param key 地址 | 62 | + * @param url 地址 |
| 63 | * @return 字节数据 | 63 | * @return 字节数据 |
| 64 | */ | 64 | */ |
| 65 | public static byte[] readFile(String url) | 65 | public static byte[] readFile(String url) |
| @@ -5,6 +5,7 @@ import java.io.IOException; | @@ -5,6 +5,7 @@ import java.io.IOException; | ||
| 5 | import java.io.InputStream; | 5 | import java.io.InputStream; |
| 6 | import java.io.InputStreamReader; | 6 | import java.io.InputStreamReader; |
| 7 | import java.nio.charset.Charset; | 7 | import java.nio.charset.Charset; |
| 8 | +import java.nio.charset.StandardCharsets; | ||
| 8 | import javax.servlet.ServletRequest; | 9 | import javax.servlet.ServletRequest; |
| 9 | import org.apache.commons.lang3.exception.ExceptionUtils; | 10 | import org.apache.commons.lang3.exception.ExceptionUtils; |
| 10 | import org.slf4j.Logger; | 11 | import org.slf4j.Logger; |
| @@ -25,7 +26,7 @@ public class HttpHelper | @@ -25,7 +26,7 @@ public class HttpHelper | ||
| 25 | BufferedReader reader = null; | 26 | BufferedReader reader = null; |
| 26 | try (InputStream inputStream = request.getInputStream()) | 27 | try (InputStream inputStream = request.getInputStream()) |
| 27 | { | 28 | { |
| 28 | - reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); | 29 | + reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); |
| 29 | String line = ""; | 30 | String line = ""; |
| 30 | while ((line = reader.readLine()) != null) | 31 | while ((line = reader.readLine()) != null) |
| 31 | { | 32 | { |
| @@ -9,6 +9,7 @@ import java.net.ConnectException; | @@ -9,6 +9,7 @@ import java.net.ConnectException; | ||
| 9 | import java.net.SocketTimeoutException; | 9 | import java.net.SocketTimeoutException; |
| 10 | import java.net.URL; | 10 | import java.net.URL; |
| 11 | import java.net.URLConnection; | 11 | import java.net.URLConnection; |
| 12 | +import java.nio.charset.StandardCharsets; | ||
| 12 | import java.security.cert.X509Certificate; | 13 | import java.security.cert.X509Certificate; |
| 13 | import javax.net.ssl.HostnameVerifier; | 14 | import javax.net.ssl.HostnameVerifier; |
| 14 | import javax.net.ssl.HttpsURLConnection; | 15 | import javax.net.ssl.HttpsURLConnection; |
| @@ -130,9 +131,8 @@ public class HttpUtils | @@ -130,9 +131,8 @@ public class HttpUtils | ||
| 130 | StringBuilder result = new StringBuilder(); | 131 | StringBuilder result = new StringBuilder(); |
| 131 | try | 132 | try |
| 132 | { | 133 | { |
| 133 | - String urlNameString = url; | ||
| 134 | - log.info("sendPost - {}", urlNameString); | ||
| 135 | - URL realUrl = new URL(urlNameString); | 134 | + log.info("sendPost - {}", url); |
| 135 | + URL realUrl = new URL(url); | ||
| 136 | URLConnection conn = realUrl.openConnection(); | 136 | URLConnection conn = realUrl.openConnection(); |
| 137 | conn.setRequestProperty("accept", "*/*"); | 137 | conn.setRequestProperty("accept", "*/*"); |
| 138 | conn.setRequestProperty("connection", "Keep-Alive"); | 138 | conn.setRequestProperty("connection", "Keep-Alive"); |
| @@ -144,7 +144,7 @@ public class HttpUtils | @@ -144,7 +144,7 @@ public class HttpUtils | ||
| 144 | out = new PrintWriter(conn.getOutputStream()); | 144 | out = new PrintWriter(conn.getOutputStream()); |
| 145 | out.print(param); | 145 | out.print(param); |
| 146 | out.flush(); | 146 | out.flush(); |
| 147 | - in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); | 147 | + in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); |
| 148 | String line; | 148 | String line; |
| 149 | while ((line = in.readLine()) != null) | 149 | while ((line = in.readLine()) != null) |
| 150 | { | 150 | { |
| @@ -218,7 +218,7 @@ public class HttpUtils | @@ -218,7 +218,7 @@ public class HttpUtils | ||
| 218 | { | 218 | { |
| 219 | if (ret != null && !"".equals(ret.trim())) | 219 | if (ret != null && !"".equals(ret.trim())) |
| 220 | { | 220 | { |
| 221 | - result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8")); | 221 | + result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8)); |
| 222 | } | 222 | } |
| 223 | } | 223 | } |
| 224 | log.info("recv - {}", result); | 224 | log.info("recv - {}", result); |
| @@ -25,7 +25,6 @@ public class AddressUtils | @@ -25,7 +25,6 @@ public class AddressUtils | ||
| 25 | 25 | ||
| 26 | public static String getRealAddressByIP(String ip) | 26 | public static String getRealAddressByIP(String ip) |
| 27 | { | 27 | { |
| 28 | - String address = UNKNOWN; | ||
| 29 | // 内网不查询 | 28 | // 内网不查询 |
| 30 | if (IpUtils.internalIp(ip)) | 29 | if (IpUtils.internalIp(ip)) |
| 31 | { | 30 | { |
| @@ -51,6 +50,6 @@ public class AddressUtils | @@ -51,6 +50,6 @@ public class AddressUtils | ||
| 51 | log.error("获取地理位置异常 {}", ip); | 50 | log.error("获取地理位置异常 {}", ip); |
| 52 | } | 51 | } |
| 53 | } | 52 | } |
| 54 | - return address; | 53 | + return UNKNOWN; |
| 55 | } | 54 | } |
| 56 | } | 55 | } |
| @@ -1121,7 +1121,7 @@ public class ExcelUtil<T> | @@ -1121,7 +1121,7 @@ public class ExcelUtil<T> | ||
| 1121 | if (StringUtils.isNotEmpty(excel.targetAttr())) | 1121 | if (StringUtils.isNotEmpty(excel.targetAttr())) |
| 1122 | { | 1122 | { |
| 1123 | String target = excel.targetAttr(); | 1123 | String target = excel.targetAttr(); |
| 1124 | - if (target.indexOf(".") > -1) | 1124 | + if (target.contains(".")) |
| 1125 | { | 1125 | { |
| 1126 | String[] targets = target.split("[.]"); | 1126 | String[] targets = target.split("[.]"); |
| 1127 | for (String name : targets) | 1127 | for (String name : targets) |
| @@ -1216,7 +1216,7 @@ public class ExcelUtil<T> | @@ -1216,7 +1216,7 @@ public class ExcelUtil<T> | ||
| 1216 | for (Object[] os : this.fields) | 1216 | for (Object[] os : this.fields) |
| 1217 | { | 1217 | { |
| 1218 | Excel excel = (Excel) os[1]; | 1218 | Excel excel = (Excel) os[1]; |
| 1219 | - maxHeight = maxHeight > excel.height() ? maxHeight : excel.height(); | 1219 | + maxHeight = Math.max(maxHeight, excel.height()); |
| 1220 | } | 1220 | } |
| 1221 | return (short) (maxHeight * 20); | 1221 | return (short) (maxHeight * 20); |
| 1222 | } | 1222 | } |
| 1 | package com.ruoyi.common.utils.sign; | 1 | package com.ruoyi.common.utils.sign; |
| 2 | 2 | ||
| 3 | +import java.nio.charset.StandardCharsets; | ||
| 3 | import java.security.MessageDigest; | 4 | import java.security.MessageDigest; |
| 4 | import org.slf4j.Logger; | 5 | import org.slf4j.Logger; |
| 5 | import org.slf4j.LoggerFactory; | 6 | import org.slf4j.LoggerFactory; |
| @@ -55,7 +56,7 @@ public class Md5Utils | @@ -55,7 +56,7 @@ public class Md5Utils | ||
| 55 | { | 56 | { |
| 56 | try | 57 | try |
| 57 | { | 58 | { |
| 58 | - return new String(toHex(md5(s)).getBytes("UTF-8"), "UTF-8"); | 59 | + return new String(toHex(md5(s)).getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8); |
| 59 | } | 60 | } |
| 60 | catch (Exception e) | 61 | catch (Exception e) |
| 61 | { | 62 | { |
| @@ -50,10 +50,8 @@ public class SqlUtil | @@ -50,10 +50,8 @@ public class SqlUtil | ||
| 50 | return; | 50 | return; |
| 51 | } | 51 | } |
| 52 | String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|"); | 52 | String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|"); |
| 53 | - for (int i = 0; i < sqlKeywords.length; i++) | ||
| 54 | - { | ||
| 55 | - if (StringUtils.indexOfIgnoreCase(value, sqlKeywords[i]) > -1) | ||
| 56 | - { | 53 | + for (String sqlKeyword : sqlKeywords) { |
| 54 | + if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) { | ||
| 57 | throw new UtilException("参数存在SQL注入风险"); | 55 | throw new UtilException("参数存在SQL注入风险"); |
| 58 | } | 56 | } |
| 59 | } | 57 | } |
| @@ -151,8 +151,7 @@ public class GenUtils | @@ -151,8 +151,7 @@ public class GenUtils | ||
| 151 | { | 151 | { |
| 152 | int lastIndex = packageName.lastIndexOf("."); | 152 | int lastIndex = packageName.lastIndexOf("."); |
| 153 | int nameLength = packageName.length(); | 153 | int nameLength = packageName.length(); |
| 154 | - String moduleName = StringUtils.substring(packageName, lastIndex + 1, nameLength); | ||
| 155 | - return moduleName; | 154 | + return StringUtils.substring(packageName, lastIndex + 1, nameLength); |
| 156 | } | 155 | } |
| 157 | 156 | ||
| 158 | /** | 157 | /** |
| @@ -165,8 +164,7 @@ public class GenUtils | @@ -165,8 +164,7 @@ public class GenUtils | ||
| 165 | { | 164 | { |
| 166 | int lastIndex = tableName.lastIndexOf("_"); | 165 | int lastIndex = tableName.lastIndexOf("_"); |
| 167 | int nameLength = tableName.length(); | 166 | int nameLength = tableName.length(); |
| 168 | - String businessName = StringUtils.substring(tableName, lastIndex + 1, nameLength); | ||
| 169 | - return businessName; | 167 | + return StringUtils.substring(tableName, lastIndex + 1, nameLength); |
| 170 | } | 168 | } |
| 171 | 169 | ||
| 172 | /** | 170 | /** |
| @@ -228,8 +228,7 @@ public class VelocityUtils | @@ -228,8 +228,7 @@ public class VelocityUtils | ||
| 228 | public static String getPackagePrefix(String packageName) | 228 | public static String getPackagePrefix(String packageName) |
| 229 | { | 229 | { |
| 230 | int lastIndex = packageName.lastIndexOf("."); | 230 | int lastIndex = packageName.lastIndexOf("."); |
| 231 | - String basePackage = StringUtils.substring(packageName, 0, lastIndex); | ||
| 232 | - return basePackage; | 231 | + return StringUtils.substring(packageName, 0, lastIndex); |
| 233 | } | 232 | } |
| 234 | 233 | ||
| 235 | /** | 234 | /** |
| @@ -63,12 +63,9 @@ public class SysDeptServiceImpl implements ISysDeptService | @@ -63,12 +63,9 @@ public class SysDeptServiceImpl implements ISysDeptService | ||
| 63 | { | 63 | { |
| 64 | tempList.add(dept.getDeptId()); | 64 | tempList.add(dept.getDeptId()); |
| 65 | } | 65 | } |
| 66 | - for (Iterator<SysDept> iterator = depts.iterator(); iterator.hasNext();) | ||
| 67 | - { | ||
| 68 | - SysDept dept = (SysDept) iterator.next(); | 66 | + for (SysDept dept : depts) { |
| 69 | // 如果是顶级节点, 遍历该父节点的所有子节点 | 67 | // 如果是顶级节点, 遍历该父节点的所有子节点 |
| 70 | - if (!tempList.contains(dept.getParentId())) | ||
| 71 | - { | 68 | + if (!tempList.contains(dept.getParentId())) { |
| 72 | recursionFn(depts, dept); | 69 | recursionFn(depts, dept); |
| 73 | returnList.add(dept); | 70 | returnList.add(dept); |
| 74 | } | 71 | } |
| @@ -498,7 +498,7 @@ public class SysMenuServiceImpl implements ISysMenuService | @@ -498,7 +498,7 @@ public class SysMenuServiceImpl implements ISysMenuService | ||
| 498 | */ | 498 | */ |
| 499 | private boolean hasChild(List<SysMenu> list, SysMenu t) | 499 | private boolean hasChild(List<SysMenu> list, SysMenu t) |
| 500 | { | 500 | { |
| 501 | - return getChildList(list, t).size() > 0 ? true : false; | 501 | + return getChildList(list, t).size() > 0; |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | /** | 504 | /** |
| 1 | -export default [ | ||
| 2 | - { | ||
| 3 | - layout: 'colFormItem', | ||
| 4 | - tagIcon: 'input', | ||
| 5 | - label: '手机号', | ||
| 6 | - vModel: 'mobile', | ||
| 7 | - formId: 6, | ||
| 8 | - tag: 'el-input', | ||
| 9 | - placeholder: '请输入手机号', | ||
| 10 | - defaultValue: '', | ||
| 11 | - span: 24, | ||
| 12 | - style: { width: '100%' }, | ||
| 13 | - clearable: true, | ||
| 14 | - prepend: '', | ||
| 15 | - append: '', | ||
| 16 | - 'prefix-icon': 'el-icon-mobile', | ||
| 17 | - 'suffix-icon': '', | ||
| 18 | - maxlength: 11, | ||
| 19 | - 'show-word-limit': true, | ||
| 20 | - readonly: false, | ||
| 21 | - disabled: false, | ||
| 22 | - required: true, | ||
| 23 | - changeTag: true, | ||
| 24 | - regList: [{ | ||
| 25 | - pattern: '/^1(3|4|5|7|8|9)\\d{9}$/', | ||
| 26 | - message: '手机号格式错误' | ||
| 27 | - }] | ||
| 28 | - } | ||
| 29 | -] | 1 | +export default [ |
| 2 | + { | ||
| 3 | + layout: 'colFormItem', | ||
| 4 | + tagIcon: 'input', | ||
| 5 | + label: '手机号', | ||
| 6 | + vModel: 'mobile', | ||
| 7 | + formId: 6, | ||
| 8 | + tag: 'el-input', | ||
| 9 | + placeholder: '请输入手机号', | ||
| 10 | + defaultValue: '', | ||
| 11 | + span: 24, | ||
| 12 | + style: { width: '100%' }, | ||
| 13 | + clearable: true, | ||
| 14 | + prepend: '', | ||
| 15 | + append: '', | ||
| 16 | + 'prefix-icon': 'el-icon-mobile', | ||
| 17 | + 'suffix-icon': '', | ||
| 18 | + maxlength: 11, | ||
| 19 | + 'show-word-limit': true, | ||
| 20 | + readonly: false, | ||
| 21 | + disabled: false, | ||
| 22 | + required: true, | ||
| 23 | + changeTag: true, | ||
| 24 | + regList: [{ | ||
| 25 | + pattern: '/^1(3|4|5|7|8|9)\\d{9}$/', | ||
| 26 | + message: '手机号格式错误' | ||
| 27 | + }] | ||
| 28 | + } | ||
| 29 | +] |
| 1 | -/* eslint-disable max-len */ | ||
| 2 | -import { trigger } from './config' | ||
| 3 | - | ||
| 4 | -let confGlobal | ||
| 5 | -let someSpanIsNot24 | ||
| 6 | - | ||
| 7 | -export function dialogWrapper(str) { | ||
| 8 | - return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Titile"> | ||
| 9 | - ${str} | ||
| 10 | - <div slot="footer"> | ||
| 11 | - <el-button @click="close">取消</el-button> | ||
| 12 | - <el-button type="primary" @click="handelConfirm">确定</el-button> | ||
| 13 | - </div> | ||
| 14 | - </el-dialog>` | ||
| 15 | -} | ||
| 16 | - | ||
| 17 | -export function vueTemplate(str) { | ||
| 18 | - return `<template> | ||
| 19 | - <div> | ||
| 20 | - ${str} | ||
| 21 | - </div> | ||
| 22 | - </template>` | ||
| 23 | -} | ||
| 24 | - | ||
| 25 | -export function vueScript(str) { | ||
| 26 | - return `<script> | ||
| 27 | - ${str} | ||
| 28 | - </script>` | ||
| 29 | -} | ||
| 30 | - | ||
| 31 | -export function cssStyle(cssStr) { | ||
| 32 | - return `<style> | ||
| 33 | - ${cssStr} | ||
| 34 | - </style>` | ||
| 35 | -} | ||
| 36 | - | ||
| 37 | -function buildFormTemplate(conf, child, type) { | ||
| 38 | - let labelPosition = '' | ||
| 39 | - if (conf.labelPosition !== 'right') { | ||
| 40 | - labelPosition = `label-position="${conf.labelPosition}"` | ||
| 41 | - } | ||
| 42 | - const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : '' | ||
| 43 | - let str = `<el-form ref="${conf.formRef}" :model="${conf.formModel}" :rules="${conf.formRules}" size="${conf.size}" ${disabled} label-width="${conf.labelWidth}px" ${labelPosition}> | ||
| 44 | - ${child} | ||
| 45 | - ${buildFromBtns(conf, type)} | ||
| 46 | - </el-form>` | ||
| 47 | - if (someSpanIsNot24) { | ||
| 48 | - str = `<el-row :gutter="${conf.gutter}"> | ||
| 49 | - ${str} | ||
| 50 | - </el-row>` | ||
| 51 | - } | ||
| 52 | - return str | ||
| 53 | -} | ||
| 54 | - | ||
| 55 | -function buildFromBtns(conf, type) { | ||
| 56 | - let str = '' | ||
| 57 | - if (conf.formBtns && type === 'file') { | ||
| 58 | - str = `<el-form-item size="large"> | ||
| 59 | - <el-button type="primary" @click="submitForm">提交</el-button> | ||
| 60 | - <el-button @click="resetForm">重置</el-button> | ||
| 61 | - </el-form-item>` | ||
| 62 | - if (someSpanIsNot24) { | ||
| 63 | - str = `<el-col :span="24"> | ||
| 64 | - ${str} | ||
| 65 | - </el-col>` | ||
| 66 | - } | ||
| 67 | - } | ||
| 68 | - return str | ||
| 69 | -} | ||
| 70 | - | ||
| 71 | -// span不为24的用el-col包裹 | ||
| 72 | -function colWrapper(element, str) { | ||
| 73 | - if (someSpanIsNot24 || element.span !== 24) { | ||
| 74 | - return `<el-col :span="${element.span}"> | ||
| 75 | - ${str} | ||
| 76 | - </el-col>` | ||
| 77 | - } | ||
| 78 | - return str | ||
| 79 | -} | ||
| 80 | - | ||
| 81 | -const layouts = { | ||
| 82 | - colFormItem(element) { | ||
| 83 | - let labelWidth = '' | ||
| 84 | - if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) { | ||
| 85 | - labelWidth = `label-width="${element.labelWidth}px"` | ||
| 86 | - } | ||
| 87 | - const required = !trigger[element.tag] && element.required ? 'required' : '' | ||
| 88 | - const tagDom = tags[element.tag] ? tags[element.tag](element) : null | ||
| 89 | - let str = `<el-form-item ${labelWidth} label="${element.label}" prop="${element.vModel}" ${required}> | ||
| 90 | - ${tagDom} | ||
| 91 | - </el-form-item>` | ||
| 92 | - str = colWrapper(element, str) | ||
| 93 | - return str | ||
| 94 | - }, | ||
| 95 | - rowFormItem(element) { | ||
| 96 | - const type = element.type === 'default' ? '' : `type="${element.type}"` | ||
| 97 | - const justify = element.type === 'default' ? '' : `justify="${element.justify}"` | ||
| 98 | - const align = element.type === 'default' ? '' : `align="${element.align}"` | ||
| 99 | - const gutter = element.gutter ? `gutter="${element.gutter}"` : '' | ||
| 100 | - const children = element.children.map(el => layouts[el.layout](el)) | ||
| 101 | - let str = `<el-row ${type} ${justify} ${align} ${gutter}> | ||
| 102 | - ${children.join('\n')} | ||
| 103 | - </el-row>` | ||
| 104 | - str = colWrapper(element, str) | ||
| 105 | - return str | ||
| 106 | - } | ||
| 107 | -} | ||
| 108 | - | ||
| 109 | -const tags = { | ||
| 110 | - 'el-button': el => { | ||
| 111 | - const { | ||
| 112 | - tag, disabled | ||
| 113 | - } = attrBuilder(el) | ||
| 114 | - const type = el.type ? `type="${el.type}"` : '' | ||
| 115 | - const icon = el.icon ? `icon="${el.icon}"` : '' | ||
| 116 | - const size = el.size ? `size="${el.size}"` : '' | ||
| 117 | - let child = buildElButtonChild(el) | ||
| 118 | - | ||
| 119 | - if (child) child = `\n${child}\n` // 换行 | ||
| 120 | - return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}</${el.tag}>` | ||
| 121 | - }, | ||
| 122 | - 'el-input': el => { | ||
| 123 | - const { | ||
| 124 | - disabled, vModel, clearable, placeholder, width | ||
| 125 | - } = attrBuilder(el) | ||
| 126 | - const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : '' | ||
| 127 | - const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : '' | ||
| 128 | - const readonly = el.readonly ? 'readonly' : '' | ||
| 129 | - const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : '' | ||
| 130 | - const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : '' | ||
| 131 | - const showPassword = el['show-password'] ? 'show-password' : '' | ||
| 132 | - const type = el.type ? `type="${el.type}"` : '' | ||
| 133 | - const autosize = el.autosize && el.autosize.minRows | ||
| 134 | - ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"` | ||
| 135 | - : '' | ||
| 136 | - let child = buildElInputChild(el) | ||
| 137 | - | ||
| 138 | - if (child) child = `\n${child}\n` // 换行 | ||
| 139 | - return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${el.tag}>` | ||
| 140 | - }, | ||
| 141 | - 'el-input-number': el => { | ||
| 142 | - const { disabled, vModel, placeholder } = attrBuilder(el) | ||
| 143 | - const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : '' | ||
| 144 | - const min = el.min ? `:min='${el.min}'` : '' | ||
| 145 | - const max = el.max ? `:max='${el.max}'` : '' | ||
| 146 | - const step = el.step ? `:step='${el.step}'` : '' | ||
| 147 | - const stepStrictly = el['step-strictly'] ? 'step-strictly' : '' | ||
| 148 | - const precision = el.precision ? `:precision='${el.precision}'` : '' | ||
| 149 | - | ||
| 150 | - return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${el.tag}>` | ||
| 151 | - }, | ||
| 152 | - 'el-select': el => { | ||
| 153 | - const { | ||
| 154 | - disabled, vModel, clearable, placeholder, width | ||
| 155 | - } = attrBuilder(el) | ||
| 156 | - const filterable = el.filterable ? 'filterable' : '' | ||
| 157 | - const multiple = el.multiple ? 'multiple' : '' | ||
| 158 | - let child = buildElSelectChild(el) | ||
| 159 | - | ||
| 160 | - if (child) child = `\n${child}\n` // 换行 | ||
| 161 | - return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${el.tag}>` | ||
| 162 | - }, | ||
| 163 | - 'el-radio-group': el => { | ||
| 164 | - const { disabled, vModel } = attrBuilder(el) | ||
| 165 | - const size = `size="${el.size}"` | ||
| 166 | - let child = buildElRadioGroupChild(el) | ||
| 167 | - | ||
| 168 | - if (child) child = `\n${child}\n` // 换行 | ||
| 169 | - return `<${el.tag} ${vModel} ${size} ${disabled}>${child}</${el.tag}>` | ||
| 170 | - }, | ||
| 171 | - 'el-checkbox-group': el => { | ||
| 172 | - const { disabled, vModel } = attrBuilder(el) | ||
| 173 | - const size = `size="${el.size}"` | ||
| 174 | - const min = el.min ? `:min="${el.min}"` : '' | ||
| 175 | - const max = el.max ? `:max="${el.max}"` : '' | ||
| 176 | - let child = buildElCheckboxGroupChild(el) | ||
| 177 | - | ||
| 178 | - if (child) child = `\n${child}\n` // 换行 | ||
| 179 | - return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${el.tag}>` | ||
| 180 | - }, | ||
| 181 | - 'el-switch': el => { | ||
| 182 | - const { disabled, vModel } = attrBuilder(el) | ||
| 183 | - const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : '' | ||
| 184 | - const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : '' | ||
| 185 | - const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : '' | ||
| 186 | - const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : '' | ||
| 187 | - const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : '' | ||
| 188 | - const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : '' | ||
| 189 | - | ||
| 190 | - return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${el.tag}>` | ||
| 191 | - }, | ||
| 192 | - 'el-cascader': el => { | ||
| 193 | - const { | ||
| 194 | - disabled, vModel, clearable, placeholder, width | ||
| 195 | - } = attrBuilder(el) | ||
| 196 | - const options = el.options ? `:options="${el.vModel}Options"` : '' | ||
| 197 | - const props = el.props ? `:props="${el.vModel}Props"` : '' | ||
| 198 | - const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"' | ||
| 199 | - const filterable = el.filterable ? 'filterable' : '' | ||
| 200 | - const separator = el.separator === '/' ? '' : `separator="${el.separator}"` | ||
| 201 | - | ||
| 202 | - return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${el.tag}>` | ||
| 203 | - }, | ||
| 204 | - 'el-slider': el => { | ||
| 205 | - const { disabled, vModel } = attrBuilder(el) | ||
| 206 | - const min = el.min ? `:min='${el.min}'` : '' | ||
| 207 | - const max = el.max ? `:max='${el.max}'` : '' | ||
| 208 | - const step = el.step ? `:step='${el.step}'` : '' | ||
| 209 | - const range = el.range ? 'range' : '' | ||
| 210 | - const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : '' | ||
| 211 | - | ||
| 212 | - return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${el.tag}>` | ||
| 213 | - }, | ||
| 214 | - 'el-time-picker': el => { | ||
| 215 | - const { | ||
| 216 | - disabled, vModel, clearable, placeholder, width | ||
| 217 | - } = attrBuilder(el) | ||
| 218 | - const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' | ||
| 219 | - const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' | ||
| 220 | - const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' | ||
| 221 | - const isRange = el['is-range'] ? 'is-range' : '' | ||
| 222 | - const format = el.format ? `format="${el.format}"` : '' | ||
| 223 | - const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' | ||
| 224 | - const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : '' | ||
| 225 | - | ||
| 226 | - return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${el.tag}>` | ||
| 227 | - }, | ||
| 228 | - 'el-date-picker': el => { | ||
| 229 | - const { | ||
| 230 | - disabled, vModel, clearable, placeholder, width | ||
| 231 | - } = attrBuilder(el) | ||
| 232 | - const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' | ||
| 233 | - const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' | ||
| 234 | - const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' | ||
| 235 | - const format = el.format ? `format="${el.format}"` : '' | ||
| 236 | - const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' | ||
| 237 | - const type = el.type === 'date' ? '' : `type="${el.type}"` | ||
| 238 | - const readonly = el.readonly ? 'readonly' : '' | ||
| 239 | - | ||
| 240 | - return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${el.tag}>` | ||
| 241 | - }, | ||
| 242 | - 'el-rate': el => { | ||
| 243 | - const { disabled, vModel } = attrBuilder(el) | ||
| 244 | - const max = el.max ? `:max='${el.max}'` : '' | ||
| 245 | - const allowHalf = el['allow-half'] ? 'allow-half' : '' | ||
| 246 | - const showText = el['show-text'] ? 'show-text' : '' | ||
| 247 | - const showScore = el['show-score'] ? 'show-score' : '' | ||
| 248 | - | ||
| 249 | - return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}></${el.tag}>` | ||
| 250 | - }, | ||
| 251 | - 'el-color-picker': el => { | ||
| 252 | - const { disabled, vModel } = attrBuilder(el) | ||
| 253 | - const size = `size="${el.size}"` | ||
| 254 | - const showAlpha = el['show-alpha'] ? 'show-alpha' : '' | ||
| 255 | - const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : '' | ||
| 256 | - | ||
| 257 | - return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${el.tag}>` | ||
| 258 | - }, | ||
| 259 | - 'el-upload': el => { | ||
| 260 | - const disabled = el.disabled ? ':disabled=\'true\'' : '' | ||
| 261 | - const action = el.action ? `:action="${el.vModel}Action"` : '' | ||
| 262 | - const multiple = el.multiple ? 'multiple' : '' | ||
| 263 | - const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : '' | ||
| 264 | - const accept = el.accept ? `accept="${el.accept}"` : '' | ||
| 265 | - const name = el.name !== 'file' ? `name="${el.name}"` : '' | ||
| 266 | - const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : '' | ||
| 267 | - const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"` | ||
| 268 | - const fileList = `:file-list="${el.vModel}fileList"` | ||
| 269 | - const ref = `ref="${el.vModel}"` | ||
| 270 | - let child = buildElUploadChild(el) | ||
| 271 | - | ||
| 272 | - if (child) child = `\n${child}\n` // 换行 | ||
| 273 | - return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${el.tag}>` | ||
| 274 | - } | ||
| 275 | -} | ||
| 276 | - | ||
| 277 | -function attrBuilder(el) { | ||
| 278 | - return { | ||
| 279 | - vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`, | ||
| 280 | - clearable: el.clearable ? 'clearable' : '', | ||
| 281 | - placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '', | ||
| 282 | - width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '', | ||
| 283 | - disabled: el.disabled ? ':disabled=\'true\'' : '' | ||
| 284 | - } | ||
| 285 | -} | ||
| 286 | - | ||
| 287 | -// el-buttin 子级 | ||
| 288 | -function buildElButtonChild(conf) { | ||
| 289 | - const children = [] | ||
| 290 | - if (conf.default) { | ||
| 291 | - children.push(conf.default) | ||
| 292 | - } | ||
| 293 | - return children.join('\n') | ||
| 294 | -} | ||
| 295 | - | ||
| 296 | -// el-input innerHTML | ||
| 297 | -function buildElInputChild(conf) { | ||
| 298 | - const children = [] | ||
| 299 | - if (conf.prepend) { | ||
| 300 | - children.push(`<template slot="prepend">${conf.prepend}</template>`) | ||
| 301 | - } | ||
| 302 | - if (conf.append) { | ||
| 303 | - children.push(`<template slot="append">${conf.append}</template>`) | ||
| 304 | - } | ||
| 305 | - return children.join('\n') | ||
| 306 | -} | ||
| 307 | - | ||
| 308 | -function buildElSelectChild(conf) { | ||
| 309 | - const children = [] | ||
| 310 | - if (conf.options && conf.options.length) { | ||
| 311 | - children.push(`<el-option v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`) | ||
| 312 | - } | ||
| 313 | - return children.join('\n') | ||
| 314 | -} | ||
| 315 | - | ||
| 316 | -function buildElRadioGroupChild(conf) { | ||
| 317 | - const children = [] | ||
| 318 | - if (conf.options && conf.options.length) { | ||
| 319 | - const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio' | ||
| 320 | - const border = conf.border ? 'border' : '' | ||
| 321 | - children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`) | ||
| 322 | - } | ||
| 323 | - return children.join('\n') | ||
| 324 | -} | ||
| 325 | - | ||
| 326 | -function buildElCheckboxGroupChild(conf) { | ||
| 327 | - const children = [] | ||
| 328 | - if (conf.options && conf.options.length) { | ||
| 329 | - const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox' | ||
| 330 | - const border = conf.border ? 'border' : '' | ||
| 331 | - children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`) | ||
| 332 | - } | ||
| 333 | - return children.join('\n') | ||
| 334 | -} | ||
| 335 | - | ||
| 336 | -function buildElUploadChild(conf) { | ||
| 337 | - const list = [] | ||
| 338 | - if (conf['list-type'] === 'picture-card') list.push('<i class="el-icon-plus"></i>') | ||
| 339 | - else list.push(`<el-button size="small" type="primary" icon="el-icon-upload">${conf.buttonText}</el-button>`) | ||
| 340 | - if (conf.showTip) list.push(`<div slot="tip" class="el-upload__tip">只能上传不超过 ${conf.fileSize}${conf.sizeUnit} 的${conf.accept}文件</div>`) | ||
| 341 | - return list.join('\n') | ||
| 342 | -} | ||
| 343 | - | ||
| 344 | -export function makeUpHtml(conf, type) { | ||
| 345 | - const htmlList = [] | ||
| 346 | - confGlobal = conf | ||
| 347 | - someSpanIsNot24 = conf.fields.some(item => item.span !== 24) | ||
| 348 | - conf.fields.forEach(el => { | ||
| 349 | - htmlList.push(layouts[el.layout](el)) | ||
| 350 | - }) | ||
| 351 | - const htmlStr = htmlList.join('\n') | ||
| 352 | - | ||
| 353 | - let temp = buildFormTemplate(conf, htmlStr, type) | ||
| 354 | - if (type === 'dialog') { | ||
| 355 | - temp = dialogWrapper(temp) | ||
| 356 | - } | ||
| 357 | - confGlobal = null | ||
| 358 | - return temp | ||
| 359 | -} | 1 | +/* eslint-disable max-len */ |
| 2 | +import { trigger } from './config' | ||
| 3 | + | ||
| 4 | +let confGlobal | ||
| 5 | +let someSpanIsNot24 | ||
| 6 | + | ||
| 7 | +export function dialogWrapper(str) { | ||
| 8 | + return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Title"> | ||
| 9 | + ${str} | ||
| 10 | + <div slot="footer"> | ||
| 11 | + <el-button @click="close">取消</el-button> | ||
| 12 | + <el-button type="primary" @click="handleConfirm">确定</el-button> | ||
| 13 | + </div> | ||
| 14 | + </el-dialog>` | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +export function vueTemplate(str) { | ||
| 18 | + return `<template> | ||
| 19 | + <div> | ||
| 20 | + ${str} | ||
| 21 | + </div> | ||
| 22 | + </template>` | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +export function vueScript(str) { | ||
| 26 | + return `<script> | ||
| 27 | + ${str} | ||
| 28 | + </script>` | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | +export function cssStyle(cssStr) { | ||
| 32 | + return `<style> | ||
| 33 | + ${cssStr} | ||
| 34 | + </style>` | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +function buildFormTemplate(conf, child, type) { | ||
| 38 | + let labelPosition = '' | ||
| 39 | + if (conf.labelPosition !== 'right') { | ||
| 40 | + labelPosition = `label-position="${conf.labelPosition}"` | ||
| 41 | + } | ||
| 42 | + const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : '' | ||
| 43 | + let str = `<el-form ref="${conf.formRef}" :model="${conf.formModel}" :rules="${conf.formRules}" size="${conf.size}" ${disabled} label-width="${conf.labelWidth}px" ${labelPosition}> | ||
| 44 | + ${child} | ||
| 45 | + ${buildFromBtns(conf, type)} | ||
| 46 | + </el-form>` | ||
| 47 | + if (someSpanIsNot24) { | ||
| 48 | + str = `<el-row :gutter="${conf.gutter}"> | ||
| 49 | + ${str} | ||
| 50 | + </el-row>` | ||
| 51 | + } | ||
| 52 | + return str | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +function buildFromBtns(conf, type) { | ||
| 56 | + let str = '' | ||
| 57 | + if (conf.formBtns && type === 'file') { | ||
| 58 | + str = `<el-form-item size="large"> | ||
| 59 | + <el-button type="primary" @click="submitForm">提交</el-button> | ||
| 60 | + <el-button @click="resetForm">重置</el-button> | ||
| 61 | + </el-form-item>` | ||
| 62 | + if (someSpanIsNot24) { | ||
| 63 | + str = `<el-col :span="24"> | ||
| 64 | + ${str} | ||
| 65 | + </el-col>` | ||
| 66 | + } | ||
| 67 | + } | ||
| 68 | + return str | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +// span不为24的用el-col包裹 | ||
| 72 | +function colWrapper(element, str) { | ||
| 73 | + if (someSpanIsNot24 || element.span !== 24) { | ||
| 74 | + return `<el-col :span="${element.span}"> | ||
| 75 | + ${str} | ||
| 76 | + </el-col>` | ||
| 77 | + } | ||
| 78 | + return str | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +const layouts = { | ||
| 82 | + colFormItem(element) { | ||
| 83 | + let labelWidth = '' | ||
| 84 | + if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) { | ||
| 85 | + labelWidth = `label-width="${element.labelWidth}px"` | ||
| 86 | + } | ||
| 87 | + const required = !trigger[element.tag] && element.required ? 'required' : '' | ||
| 88 | + const tagDom = tags[element.tag] ? tags[element.tag](element) : null | ||
| 89 | + let str = `<el-form-item ${labelWidth} label="${element.label}" prop="${element.vModel}" ${required}> | ||
| 90 | + ${tagDom} | ||
| 91 | + </el-form-item>` | ||
| 92 | + str = colWrapper(element, str) | ||
| 93 | + return str | ||
| 94 | + }, | ||
| 95 | + rowFormItem(element) { | ||
| 96 | + const type = element.type === 'default' ? '' : `type="${element.type}"` | ||
| 97 | + const justify = element.type === 'default' ? '' : `justify="${element.justify}"` | ||
| 98 | + const align = element.type === 'default' ? '' : `align="${element.align}"` | ||
| 99 | + const gutter = element.gutter ? `gutter="${element.gutter}"` : '' | ||
| 100 | + const children = element.children.map(el => layouts[el.layout](el)) | ||
| 101 | + let str = `<el-row ${type} ${justify} ${align} ${gutter}> | ||
| 102 | + ${children.join('\n')} | ||
| 103 | + </el-row>` | ||
| 104 | + str = colWrapper(element, str) | ||
| 105 | + return str | ||
| 106 | + } | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +const tags = { | ||
| 110 | + 'el-button': el => { | ||
| 111 | + const { | ||
| 112 | + tag, disabled | ||
| 113 | + } = attrBuilder(el) | ||
| 114 | + const type = el.type ? `type="${el.type}"` : '' | ||
| 115 | + const icon = el.icon ? `icon="${el.icon}"` : '' | ||
| 116 | + const size = el.size ? `size="${el.size}"` : '' | ||
| 117 | + let child = buildElButtonChild(el) | ||
| 118 | + | ||
| 119 | + if (child) child = `\n${child}\n` // 换行 | ||
| 120 | + return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}</${el.tag}>` | ||
| 121 | + }, | ||
| 122 | + 'el-input': el => { | ||
| 123 | + const { | ||
| 124 | + disabled, vModel, clearable, placeholder, width | ||
| 125 | + } = attrBuilder(el) | ||
| 126 | + const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : '' | ||
| 127 | + const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : '' | ||
| 128 | + const readonly = el.readonly ? 'readonly' : '' | ||
| 129 | + const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : '' | ||
| 130 | + const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : '' | ||
| 131 | + const showPassword = el['show-password'] ? 'show-password' : '' | ||
| 132 | + const type = el.type ? `type="${el.type}"` : '' | ||
| 133 | + const autosize = el.autosize && el.autosize.minRows | ||
| 134 | + ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"` | ||
| 135 | + : '' | ||
| 136 | + let child = buildElInputChild(el) | ||
| 137 | + | ||
| 138 | + if (child) child = `\n${child}\n` // 换行 | ||
| 139 | + return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${el.tag}>` | ||
| 140 | + }, | ||
| 141 | + 'el-input-number': el => { | ||
| 142 | + const { disabled, vModel, placeholder } = attrBuilder(el) | ||
| 143 | + const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : '' | ||
| 144 | + const min = el.min ? `:min='${el.min}'` : '' | ||
| 145 | + const max = el.max ? `:max='${el.max}'` : '' | ||
| 146 | + const step = el.step ? `:step='${el.step}'` : '' | ||
| 147 | + const stepStrictly = el['step-strictly'] ? 'step-strictly' : '' | ||
| 148 | + const precision = el.precision ? `:precision='${el.precision}'` : '' | ||
| 149 | + | ||
| 150 | + return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${el.tag}>` | ||
| 151 | + }, | ||
| 152 | + 'el-select': el => { | ||
| 153 | + const { | ||
| 154 | + disabled, vModel, clearable, placeholder, width | ||
| 155 | + } = attrBuilder(el) | ||
| 156 | + const filterable = el.filterable ? 'filterable' : '' | ||
| 157 | + const multiple = el.multiple ? 'multiple' : '' | ||
| 158 | + let child = buildElSelectChild(el) | ||
| 159 | + | ||
| 160 | + if (child) child = `\n${child}\n` // 换行 | ||
| 161 | + return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${el.tag}>` | ||
| 162 | + }, | ||
| 163 | + 'el-radio-group': el => { | ||
| 164 | + const { disabled, vModel } = attrBuilder(el) | ||
| 165 | + const size = `size="${el.size}"` | ||
| 166 | + let child = buildElRadioGroupChild(el) | ||
| 167 | + | ||
| 168 | + if (child) child = `\n${child}\n` // 换行 | ||
| 169 | + return `<${el.tag} ${vModel} ${size} ${disabled}>${child}</${el.tag}>` | ||
| 170 | + }, | ||
| 171 | + 'el-checkbox-group': el => { | ||
| 172 | + const { disabled, vModel } = attrBuilder(el) | ||
| 173 | + const size = `size="${el.size}"` | ||
| 174 | + const min = el.min ? `:min="${el.min}"` : '' | ||
| 175 | + const max = el.max ? `:max="${el.max}"` : '' | ||
| 176 | + let child = buildElCheckboxGroupChild(el) | ||
| 177 | + | ||
| 178 | + if (child) child = `\n${child}\n` // 换行 | ||
| 179 | + return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${el.tag}>` | ||
| 180 | + }, | ||
| 181 | + 'el-switch': el => { | ||
| 182 | + const { disabled, vModel } = attrBuilder(el) | ||
| 183 | + const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : '' | ||
| 184 | + const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : '' | ||
| 185 | + const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : '' | ||
| 186 | + const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : '' | ||
| 187 | + const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : '' | ||
| 188 | + const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : '' | ||
| 189 | + | ||
| 190 | + return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${el.tag}>` | ||
| 191 | + }, | ||
| 192 | + 'el-cascader': el => { | ||
| 193 | + const { | ||
| 194 | + disabled, vModel, clearable, placeholder, width | ||
| 195 | + } = attrBuilder(el) | ||
| 196 | + const options = el.options ? `:options="${el.vModel}Options"` : '' | ||
| 197 | + const props = el.props ? `:props="${el.vModel}Props"` : '' | ||
| 198 | + const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"' | ||
| 199 | + const filterable = el.filterable ? 'filterable' : '' | ||
| 200 | + const separator = el.separator === '/' ? '' : `separator="${el.separator}"` | ||
| 201 | + | ||
| 202 | + return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${el.tag}>` | ||
| 203 | + }, | ||
| 204 | + 'el-slider': el => { | ||
| 205 | + const { disabled, vModel } = attrBuilder(el) | ||
| 206 | + const min = el.min ? `:min='${el.min}'` : '' | ||
| 207 | + const max = el.max ? `:max='${el.max}'` : '' | ||
| 208 | + const step = el.step ? `:step='${el.step}'` : '' | ||
| 209 | + const range = el.range ? 'range' : '' | ||
| 210 | + const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : '' | ||
| 211 | + | ||
| 212 | + return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${el.tag}>` | ||
| 213 | + }, | ||
| 214 | + 'el-time-picker': el => { | ||
| 215 | + const { | ||
| 216 | + disabled, vModel, clearable, placeholder, width | ||
| 217 | + } = attrBuilder(el) | ||
| 218 | + const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' | ||
| 219 | + const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' | ||
| 220 | + const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' | ||
| 221 | + const isRange = el['is-range'] ? 'is-range' : '' | ||
| 222 | + const format = el.format ? `format="${el.format}"` : '' | ||
| 223 | + const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' | ||
| 224 | + const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : '' | ||
| 225 | + | ||
| 226 | + return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${el.tag}>` | ||
| 227 | + }, | ||
| 228 | + 'el-date-picker': el => { | ||
| 229 | + const { | ||
| 230 | + disabled, vModel, clearable, placeholder, width | ||
| 231 | + } = attrBuilder(el) | ||
| 232 | + const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' | ||
| 233 | + const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' | ||
| 234 | + const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' | ||
| 235 | + const format = el.format ? `format="${el.format}"` : '' | ||
| 236 | + const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' | ||
| 237 | + const type = el.type === 'date' ? '' : `type="${el.type}"` | ||
| 238 | + const readonly = el.readonly ? 'readonly' : '' | ||
| 239 | + | ||
| 240 | + return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${el.tag}>` | ||
| 241 | + }, | ||
| 242 | + 'el-rate': el => { | ||
| 243 | + const { disabled, vModel } = attrBuilder(el) | ||
| 244 | + const max = el.max ? `:max='${el.max}'` : '' | ||
| 245 | + const allowHalf = el['allow-half'] ? 'allow-half' : '' | ||
| 246 | + const showText = el['show-text'] ? 'show-text' : '' | ||
| 247 | + const showScore = el['show-score'] ? 'show-score' : '' | ||
| 248 | + | ||
| 249 | + return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}></${el.tag}>` | ||
| 250 | + }, | ||
| 251 | + 'el-color-picker': el => { | ||
| 252 | + const { disabled, vModel } = attrBuilder(el) | ||
| 253 | + const size = `size="${el.size}"` | ||
| 254 | + const showAlpha = el['show-alpha'] ? 'show-alpha' : '' | ||
| 255 | + const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : '' | ||
| 256 | + | ||
| 257 | + return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${el.tag}>` | ||
| 258 | + }, | ||
| 259 | + 'el-upload': el => { | ||
| 260 | + const disabled = el.disabled ? ':disabled=\'true\'' : '' | ||
| 261 | + const action = el.action ? `:action="${el.vModel}Action"` : '' | ||
| 262 | + const multiple = el.multiple ? 'multiple' : '' | ||
| 263 | + const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : '' | ||
| 264 | + const accept = el.accept ? `accept="${el.accept}"` : '' | ||
| 265 | + const name = el.name !== 'file' ? `name="${el.name}"` : '' | ||
| 266 | + const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : '' | ||
| 267 | + const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"` | ||
| 268 | + const fileList = `:file-list="${el.vModel}fileList"` | ||
| 269 | + const ref = `ref="${el.vModel}"` | ||
| 270 | + let child = buildElUploadChild(el) | ||
| 271 | + | ||
| 272 | + if (child) child = `\n${child}\n` // 换行 | ||
| 273 | + return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${el.tag}>` | ||
| 274 | + } | ||
| 275 | +} | ||
| 276 | + | ||
| 277 | +function attrBuilder(el) { | ||
| 278 | + return { | ||
| 279 | + vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`, | ||
| 280 | + clearable: el.clearable ? 'clearable' : '', | ||
| 281 | + placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '', | ||
| 282 | + width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '', | ||
| 283 | + disabled: el.disabled ? ':disabled=\'true\'' : '' | ||
| 284 | + } | ||
| 285 | +} | ||
| 286 | + | ||
| 287 | +// el-buttin 子级 | ||
| 288 | +function buildElButtonChild(conf) { | ||
| 289 | + const children = [] | ||
| 290 | + if (conf.default) { | ||
| 291 | + children.push(conf.default) | ||
| 292 | + } | ||
| 293 | + return children.join('\n') | ||
| 294 | +} | ||
| 295 | + | ||
| 296 | +// el-input innerHTML | ||
| 297 | +function buildElInputChild(conf) { | ||
| 298 | + const children = [] | ||
| 299 | + if (conf.prepend) { | ||
| 300 | + children.push(`<template slot="prepend">${conf.prepend}</template>`) | ||
| 301 | + } | ||
| 302 | + if (conf.append) { | ||
| 303 | + children.push(`<template slot="append">${conf.append}</template>`) | ||
| 304 | + } | ||
| 305 | + return children.join('\n') | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | +function buildElSelectChild(conf) { | ||
| 309 | + const children = [] | ||
| 310 | + if (conf.options && conf.options.length) { | ||
| 311 | + children.push(`<el-option v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`) | ||
| 312 | + } | ||
| 313 | + return children.join('\n') | ||
| 314 | +} | ||
| 315 | + | ||
| 316 | +function buildElRadioGroupChild(conf) { | ||
| 317 | + const children = [] | ||
| 318 | + if (conf.options && conf.options.length) { | ||
| 319 | + const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio' | ||
| 320 | + const border = conf.border ? 'border' : '' | ||
| 321 | + children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`) | ||
| 322 | + } | ||
| 323 | + return children.join('\n') | ||
| 324 | +} | ||
| 325 | + | ||
| 326 | +function buildElCheckboxGroupChild(conf) { | ||
| 327 | + const children = [] | ||
| 328 | + if (conf.options && conf.options.length) { | ||
| 329 | + const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox' | ||
| 330 | + const border = conf.border ? 'border' : '' | ||
| 331 | + children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`) | ||
| 332 | + } | ||
| 333 | + return children.join('\n') | ||
| 334 | +} | ||
| 335 | + | ||
| 336 | +function buildElUploadChild(conf) { | ||
| 337 | + const list = [] | ||
| 338 | + if (conf['list-type'] === 'picture-card') list.push('<i class="el-icon-plus"></i>') | ||
| 339 | + else list.push(`<el-button size="small" type="primary" icon="el-icon-upload">${conf.buttonText}</el-button>`) | ||
| 340 | + if (conf.showTip) list.push(`<div slot="tip" class="el-upload__tip">只能上传不超过 ${conf.fileSize}${conf.sizeUnit} 的${conf.accept}文件</div>`) | ||
| 341 | + return list.join('\n') | ||
| 342 | +} | ||
| 343 | + | ||
| 344 | +export function makeUpHtml(conf, type) { | ||
| 345 | + const htmlList = [] | ||
| 346 | + confGlobal = conf | ||
| 347 | + someSpanIsNot24 = conf.fields.some(item => item.span !== 24) | ||
| 348 | + conf.fields.forEach(el => { | ||
| 349 | + htmlList.push(layouts[el.layout](el)) | ||
| 350 | + }) | ||
| 351 | + const htmlStr = htmlList.join('\n') | ||
| 352 | + | ||
| 353 | + let temp = buildFormTemplate(conf, htmlStr, type) | ||
| 354 | + if (type === 'dialog') { | ||
| 355 | + temp = dialogWrapper(temp) | ||
| 356 | + } | ||
| 357 | + confGlobal = null | ||
| 358 | + return temp | ||
| 359 | +} |
| 1 | -import { isArray } from 'util' | ||
| 2 | -import { exportDefault, titleCase } from '@/utils/index' | ||
| 3 | -import { trigger } from './config' | ||
| 4 | - | ||
| 5 | -const units = { | ||
| 6 | - KB: '1024', | ||
| 7 | - MB: '1024 / 1024', | ||
| 8 | - GB: '1024 / 1024 / 1024' | ||
| 9 | -} | ||
| 10 | -let confGlobal | ||
| 11 | -const inheritAttrs = { | ||
| 12 | - file: '', | ||
| 13 | - dialog: 'inheritAttrs: false,' | ||
| 14 | -} | ||
| 15 | - | ||
| 16 | - | ||
| 17 | -export function makeUpJs(conf, type) { | ||
| 18 | - confGlobal = conf = JSON.parse(JSON.stringify(conf)) | ||
| 19 | - const dataList = [] | ||
| 20 | - const ruleList = [] | ||
| 21 | - const optionsList = [] | ||
| 22 | - const propsList = [] | ||
| 23 | - const methodList = mixinMethod(type) | ||
| 24 | - const uploadVarList = [] | ||
| 25 | - | ||
| 26 | - conf.fields.forEach(el => { | ||
| 27 | - buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) | ||
| 28 | - }) | ||
| 29 | - | ||
| 30 | - const script = buildexport( | ||
| 31 | - conf, | ||
| 32 | - type, | ||
| 33 | - dataList.join('\n'), | ||
| 34 | - ruleList.join('\n'), | ||
| 35 | - optionsList.join('\n'), | ||
| 36 | - uploadVarList.join('\n'), | ||
| 37 | - propsList.join('\n'), | ||
| 38 | - methodList.join('\n') | ||
| 39 | - ) | ||
| 40 | - confGlobal = null | ||
| 41 | - return script | ||
| 42 | -} | ||
| 43 | - | ||
| 44 | -function buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) { | ||
| 45 | - buildData(el, dataList) | ||
| 46 | - buildRules(el, ruleList) | ||
| 47 | - | ||
| 48 | - if (el.options && el.options.length) { | ||
| 49 | - buildOptions(el, optionsList) | ||
| 50 | - if (el.dataType === 'dynamic') { | ||
| 51 | - const model = `${el.vModel}Options` | ||
| 52 | - const options = titleCase(model) | ||
| 53 | - buildOptionMethod(`get${options}`, model, methodList) | ||
| 54 | - } | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - if (el.props && el.props.props) { | ||
| 58 | - buildProps(el, propsList) | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - if (el.action && el.tag === 'el-upload') { | ||
| 62 | - uploadVarList.push( | ||
| 63 | - `${el.vModel}Action: '${el.action}', | ||
| 64 | - ${el.vModel}fileList: [],` | ||
| 65 | - ) | ||
| 66 | - methodList.push(buildBeforeUpload(el)) | ||
| 67 | - if (!el['auto-upload']) { | ||
| 68 | - methodList.push(buildSubmitUpload(el)) | ||
| 69 | - } | ||
| 70 | - } | ||
| 71 | - | ||
| 72 | - if (el.children) { | ||
| 73 | - el.children.forEach(el2 => { | ||
| 74 | - buildAttributes(el2, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) | ||
| 75 | - }) | ||
| 76 | - } | ||
| 77 | -} | ||
| 78 | - | ||
| 79 | -function mixinMethod(type) { | ||
| 80 | - const list = []; const | ||
| 81 | - minxins = { | ||
| 82 | - file: confGlobal.formBtns ? { | ||
| 83 | - submitForm: `submitForm() { | ||
| 84 | - this.$refs['${confGlobal.formRef}'].validate(valid => { | ||
| 85 | - if(!valid) return | ||
| 86 | - // TODO 提交表单 | ||
| 87 | - }) | ||
| 88 | - },`, | ||
| 89 | - resetForm: `resetForm() { | ||
| 90 | - this.$refs['${confGlobal.formRef}'].resetFields() | ||
| 91 | - },` | ||
| 92 | - } : null, | ||
| 93 | - dialog: { | ||
| 94 | - onOpen: 'onOpen() {},', | ||
| 95 | - onClose: `onClose() { | ||
| 96 | - this.$refs['${confGlobal.formRef}'].resetFields() | ||
| 97 | - },`, | ||
| 98 | - close: `close() { | ||
| 99 | - this.$emit('update:visible', false) | ||
| 100 | - },`, | ||
| 101 | - handelConfirm: `handelConfirm() { | ||
| 102 | - this.$refs['${confGlobal.formRef}'].validate(valid => { | ||
| 103 | - if(!valid) return | ||
| 104 | - this.close() | ||
| 105 | - }) | ||
| 106 | - },` | ||
| 107 | - } | ||
| 108 | - } | ||
| 109 | - | ||
| 110 | - const methods = minxins[type] | ||
| 111 | - if (methods) { | ||
| 112 | - Object.keys(methods).forEach(key => { | ||
| 113 | - list.push(methods[key]) | ||
| 114 | - }) | ||
| 115 | - } | ||
| 116 | - | ||
| 117 | - return list | ||
| 118 | -} | ||
| 119 | - | ||
| 120 | -function buildData(conf, dataList) { | ||
| 121 | - if (conf.vModel === undefined) return | ||
| 122 | - let defaultValue | ||
| 123 | - if (typeof (conf.defaultValue) === 'string' && !conf.multiple) { | ||
| 124 | - defaultValue = `'${conf.defaultValue}'` | ||
| 125 | - } else { | ||
| 126 | - defaultValue = `${JSON.stringify(conf.defaultValue)}` | ||
| 127 | - } | ||
| 128 | - dataList.push(`${conf.vModel}: ${defaultValue},`) | ||
| 129 | -} | ||
| 130 | - | ||
| 131 | -function buildRules(conf, ruleList) { | ||
| 132 | - if (conf.vModel === undefined) return | ||
| 133 | - const rules = [] | ||
| 134 | - if (trigger[conf.tag]) { | ||
| 135 | - if (conf.required) { | ||
| 136 | - const type = isArray(conf.defaultValue) ? 'type: \'array\',' : '' | ||
| 137 | - let message = isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder | ||
| 138 | - if (message === undefined) message = `${conf.label}不能为空` | ||
| 139 | - rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`) | ||
| 140 | - } | ||
| 141 | - if (conf.regList && isArray(conf.regList)) { | ||
| 142 | - conf.regList.forEach(item => { | ||
| 143 | - if (item.pattern) { | ||
| 144 | - rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`) | ||
| 145 | - } | ||
| 146 | - }) | ||
| 147 | - } | ||
| 148 | - ruleList.push(`${conf.vModel}: [${rules.join(',')}],`) | ||
| 149 | - } | ||
| 150 | -} | ||
| 151 | - | ||
| 152 | -function buildOptions(conf, optionsList) { | ||
| 153 | - if (conf.vModel === undefined) return | ||
| 154 | - if (conf.dataType === 'dynamic') { conf.options = [] } | ||
| 155 | - const str = `${conf.vModel}Options: ${JSON.stringify(conf.options)},` | ||
| 156 | - optionsList.push(str) | ||
| 157 | -} | ||
| 158 | - | ||
| 159 | -function buildProps(conf, propsList) { | ||
| 160 | - if (conf.dataType === 'dynamic') { | ||
| 161 | - conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey) | ||
| 162 | - conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey) | ||
| 163 | - conf.childrenKey !== 'children' && (conf.props.props.children = conf.childrenKey) | ||
| 164 | - } | ||
| 165 | - const str = `${conf.vModel}Props: ${JSON.stringify(conf.props.props)},` | ||
| 166 | - propsList.push(str) | ||
| 167 | -} | ||
| 168 | - | ||
| 169 | -function buildBeforeUpload(conf) { | ||
| 170 | - const unitNum = units[conf.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const | ||
| 171 | - returnList = [] | ||
| 172 | - if (conf.fileSize) { | ||
| 173 | - rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize} | ||
| 174 | - if(!isRightSize){ | ||
| 175 | - this.$message.error('文件大小超过 ${conf.fileSize}${conf.sizeUnit}') | ||
| 176 | - }` | ||
| 177 | - returnList.push('isRightSize') | ||
| 178 | - } | ||
| 179 | - if (conf.accept) { | ||
| 180 | - acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type) | ||
| 181 | - if(!isAccept){ | ||
| 182 | - this.$message.error('应该选择${conf.accept}类型的文件') | ||
| 183 | - }` | ||
| 184 | - returnList.push('isAccept') | ||
| 185 | - } | ||
| 186 | - const str = `${conf.vModel}BeforeUpload(file) { | ||
| 187 | - ${rightSizeCode} | ||
| 188 | - ${acceptCode} | ||
| 189 | - return ${returnList.join('&&')} | ||
| 190 | - },` | ||
| 191 | - return returnList.length ? str : '' | ||
| 192 | -} | ||
| 193 | - | ||
| 194 | -function buildSubmitUpload(conf) { | ||
| 195 | - const str = `submitUpload() { | ||
| 196 | - this.$refs['${conf.vModel}'].submit() | ||
| 197 | - },` | ||
| 198 | - return str | ||
| 199 | -} | ||
| 200 | - | ||
| 201 | -function buildOptionMethod(methodName, model, methodList) { | ||
| 202 | - const str = `${methodName}() { | ||
| 203 | - // TODO 发起请求获取数据 | ||
| 204 | - this.${model} | ||
| 205 | - },` | ||
| 206 | - methodList.push(str) | ||
| 207 | -} | ||
| 208 | - | ||
| 209 | -function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) { | ||
| 210 | - const str = `${exportDefault}{ | ||
| 211 | - ${inheritAttrs[type]} | ||
| 212 | - components: {}, | ||
| 213 | - props: [], | ||
| 214 | - data () { | ||
| 215 | - return { | ||
| 216 | - ${conf.formModel}: { | ||
| 217 | - ${data} | ||
| 218 | - }, | ||
| 219 | - ${conf.formRules}: { | ||
| 220 | - ${rules} | ||
| 221 | - }, | ||
| 222 | - ${uploadVar} | ||
| 223 | - ${selectOptions} | ||
| 224 | - ${props} | ||
| 225 | - } | ||
| 226 | - }, | ||
| 227 | - computed: {}, | ||
| 228 | - watch: {}, | ||
| 229 | - created () {}, | ||
| 230 | - mounted () {}, | ||
| 231 | - methods: { | ||
| 232 | - ${methods} | ||
| 233 | - } | ||
| 234 | -}` | ||
| 235 | - return str | ||
| 236 | -} | 1 | +import { isArray } from 'util' |
| 2 | +import { exportDefault, titleCase } from '@/utils/index' | ||
| 3 | +import { trigger } from './config' | ||
| 4 | + | ||
| 5 | +const units = { | ||
| 6 | + KB: '1024', | ||
| 7 | + MB: '1024 / 1024', | ||
| 8 | + GB: '1024 / 1024 / 1024' | ||
| 9 | +} | ||
| 10 | +let confGlobal | ||
| 11 | +const inheritAttrs = { | ||
| 12 | + file: '', | ||
| 13 | + dialog: 'inheritAttrs: false,' | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +export function makeUpJs(conf, type) { | ||
| 18 | + confGlobal = conf = JSON.parse(JSON.stringify(conf)) | ||
| 19 | + const dataList = [] | ||
| 20 | + const ruleList = [] | ||
| 21 | + const optionsList = [] | ||
| 22 | + const propsList = [] | ||
| 23 | + const methodList = mixinMethod(type) | ||
| 24 | + const uploadVarList = [] | ||
| 25 | + | ||
| 26 | + conf.fields.forEach(el => { | ||
| 27 | + buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) | ||
| 28 | + }) | ||
| 29 | + | ||
| 30 | + const script = buildexport( | ||
| 31 | + conf, | ||
| 32 | + type, | ||
| 33 | + dataList.join('\n'), | ||
| 34 | + ruleList.join('\n'), | ||
| 35 | + optionsList.join('\n'), | ||
| 36 | + uploadVarList.join('\n'), | ||
| 37 | + propsList.join('\n'), | ||
| 38 | + methodList.join('\n') | ||
| 39 | + ) | ||
| 40 | + confGlobal = null | ||
| 41 | + return script | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +function buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) { | ||
| 45 | + buildData(el, dataList) | ||
| 46 | + buildRules(el, ruleList) | ||
| 47 | + | ||
| 48 | + if (el.options && el.options.length) { | ||
| 49 | + buildOptions(el, optionsList) | ||
| 50 | + if (el.dataType === 'dynamic') { | ||
| 51 | + const model = `${el.vModel}Options` | ||
| 52 | + const options = titleCase(model) | ||
| 53 | + buildOptionMethod(`get${options}`, model, methodList) | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + if (el.props && el.props.props) { | ||
| 58 | + buildProps(el, propsList) | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + if (el.action && el.tag === 'el-upload') { | ||
| 62 | + uploadVarList.push( | ||
| 63 | + `${el.vModel}Action: '${el.action}', | ||
| 64 | + ${el.vModel}fileList: [],` | ||
| 65 | + ) | ||
| 66 | + methodList.push(buildBeforeUpload(el)) | ||
| 67 | + if (!el['auto-upload']) { | ||
| 68 | + methodList.push(buildSubmitUpload(el)) | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + if (el.children) { | ||
| 73 | + el.children.forEach(el2 => { | ||
| 74 | + buildAttributes(el2, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) | ||
| 75 | + }) | ||
| 76 | + } | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +function mixinMethod(type) { | ||
| 80 | + const list = []; const | ||
| 81 | + minxins = { | ||
| 82 | + file: confGlobal.formBtns ? { | ||
| 83 | + submitForm: `submitForm() { | ||
| 84 | + this.$refs['${confGlobal.formRef}'].validate(valid => { | ||
| 85 | + if(!valid) return | ||
| 86 | + // TODO 提交表单 | ||
| 87 | + }) | ||
| 88 | + },`, | ||
| 89 | + resetForm: `resetForm() { | ||
| 90 | + this.$refs['${confGlobal.formRef}'].resetFields() | ||
| 91 | + },` | ||
| 92 | + } : null, | ||
| 93 | + dialog: { | ||
| 94 | + onOpen: 'onOpen() {},', | ||
| 95 | + onClose: `onClose() { | ||
| 96 | + this.$refs['${confGlobal.formRef}'].resetFields() | ||
| 97 | + },`, | ||
| 98 | + close: `close() { | ||
| 99 | + this.$emit('update:visible', false) | ||
| 100 | + },`, | ||
| 101 | + handleConfirm: `handleConfirm() { | ||
| 102 | + this.$refs['${confGlobal.formRef}'].validate(valid => { | ||
| 103 | + if(!valid) return | ||
| 104 | + this.close() | ||
| 105 | + }) | ||
| 106 | + },` | ||
| 107 | + } | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + const methods = minxins[type] | ||
| 111 | + if (methods) { | ||
| 112 | + Object.keys(methods).forEach(key => { | ||
| 113 | + list.push(methods[key]) | ||
| 114 | + }) | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + return list | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +function buildData(conf, dataList) { | ||
| 121 | + if (conf.vModel === undefined) return | ||
| 122 | + let defaultValue | ||
| 123 | + if (typeof (conf.defaultValue) === 'string' && !conf.multiple) { | ||
| 124 | + defaultValue = `'${conf.defaultValue}'` | ||
| 125 | + } else { | ||
| 126 | + defaultValue = `${JSON.stringify(conf.defaultValue)}` | ||
| 127 | + } | ||
| 128 | + dataList.push(`${conf.vModel}: ${defaultValue},`) | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +function buildRules(conf, ruleList) { | ||
| 132 | + if (conf.vModel === undefined) return | ||
| 133 | + const rules = [] | ||
| 134 | + if (trigger[conf.tag]) { | ||
| 135 | + if (conf.required) { | ||
| 136 | + const type = isArray(conf.defaultValue) ? 'type: \'array\',' : '' | ||
| 137 | + let message = isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder | ||
| 138 | + if (message === undefined) message = `${conf.label}不能为空` | ||
| 139 | + rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`) | ||
| 140 | + } | ||
| 141 | + if (conf.regList && isArray(conf.regList)) { | ||
| 142 | + conf.regList.forEach(item => { | ||
| 143 | + if (item.pattern) { | ||
| 144 | + rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`) | ||
| 145 | + } | ||
| 146 | + }) | ||
| 147 | + } | ||
| 148 | + ruleList.push(`${conf.vModel}: [${rules.join(',')}],`) | ||
| 149 | + } | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +function buildOptions(conf, optionsList) { | ||
| 153 | + if (conf.vModel === undefined) return | ||
| 154 | + if (conf.dataType === 'dynamic') { conf.options = [] } | ||
| 155 | + const str = `${conf.vModel}Options: ${JSON.stringify(conf.options)},` | ||
| 156 | + optionsList.push(str) | ||
| 157 | +} | ||
| 158 | + | ||
| 159 | +function buildProps(conf, propsList) { | ||
| 160 | + if (conf.dataType === 'dynamic') { | ||
| 161 | + conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey) | ||
| 162 | + conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey) | ||
| 163 | + conf.childrenKey !== 'children' && (conf.props.props.children = conf.childrenKey) | ||
| 164 | + } | ||
| 165 | + const str = `${conf.vModel}Props: ${JSON.stringify(conf.props.props)},` | ||
| 166 | + propsList.push(str) | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +function buildBeforeUpload(conf) { | ||
| 170 | + const unitNum = units[conf.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const | ||
| 171 | + returnList = [] | ||
| 172 | + if (conf.fileSize) { | ||
| 173 | + rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize} | ||
| 174 | + if(!isRightSize){ | ||
| 175 | + this.$message.error('文件大小超过 ${conf.fileSize}${conf.sizeUnit}') | ||
| 176 | + }` | ||
| 177 | + returnList.push('isRightSize') | ||
| 178 | + } | ||
| 179 | + if (conf.accept) { | ||
| 180 | + acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type) | ||
| 181 | + if(!isAccept){ | ||
| 182 | + this.$message.error('应该选择${conf.accept}类型的文件') | ||
| 183 | + }` | ||
| 184 | + returnList.push('isAccept') | ||
| 185 | + } | ||
| 186 | + const str = `${conf.vModel}BeforeUpload(file) { | ||
| 187 | + ${rightSizeCode} | ||
| 188 | + ${acceptCode} | ||
| 189 | + return ${returnList.join('&&')} | ||
| 190 | + },` | ||
| 191 | + return returnList.length ? str : '' | ||
| 192 | +} | ||
| 193 | + | ||
| 194 | +function buildSubmitUpload(conf) { | ||
| 195 | + const str = `submitUpload() { | ||
| 196 | + this.$refs['${conf.vModel}'].submit() | ||
| 197 | + },` | ||
| 198 | + return str | ||
| 199 | +} | ||
| 200 | + | ||
| 201 | +function buildOptionMethod(methodName, model, methodList) { | ||
| 202 | + const str = `${methodName}() { | ||
| 203 | + // TODO 发起请求获取数据 | ||
| 204 | + this.${model} | ||
| 205 | + },` | ||
| 206 | + methodList.push(str) | ||
| 207 | +} | ||
| 208 | + | ||
| 209 | +function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) { | ||
| 210 | + const str = `${exportDefault}{ | ||
| 211 | + ${inheritAttrs[type]} | ||
| 212 | + components: {}, | ||
| 213 | + props: [], | ||
| 214 | + data () { | ||
| 215 | + return { | ||
| 216 | + ${conf.formModel}: { | ||
| 217 | + ${data} | ||
| 218 | + }, | ||
| 219 | + ${conf.formRules}: { | ||
| 220 | + ${rules} | ||
| 221 | + }, | ||
| 222 | + ${uploadVar} | ||
| 223 | + ${selectOptions} | ||
| 224 | + ${props} | ||
| 225 | + } | ||
| 226 | + }, | ||
| 227 | + computed: {}, | ||
| 228 | + watch: {}, | ||
| 229 | + created () {}, | ||
| 230 | + mounted () {}, | ||
| 231 | + methods: { | ||
| 232 | + ${methods} | ||
| 233 | + } | ||
| 234 | +}` | ||
| 235 | + return str | ||
| 236 | +} |
| 1 | -<template> | ||
| 2 | - <div> | ||
| 3 | - <el-dialog | ||
| 4 | - v-bind="$attrs" | ||
| 5 | - width="500px" | ||
| 6 | - :close-on-click-modal="false" | ||
| 7 | - :modal-append-to-body="false" | ||
| 8 | - v-on="$listeners" | ||
| 9 | - @open="onOpen" | ||
| 10 | - @close="onClose" | ||
| 11 | - > | ||
| 12 | - <el-row :gutter="15"> | ||
| 13 | - <el-form | ||
| 14 | - ref="elForm" | ||
| 15 | - :model="formData" | ||
| 16 | - :rules="rules" | ||
| 17 | - size="medium" | ||
| 18 | - label-width="100px" | ||
| 19 | - > | ||
| 20 | - <el-col :span="24"> | ||
| 21 | - <el-form-item label="生成类型" prop="type"> | ||
| 22 | - <el-radio-group v-model="formData.type"> | ||
| 23 | - <el-radio-button | ||
| 24 | - v-for="(item, index) in typeOptions" | ||
| 25 | - :key="index" | ||
| 26 | - :label="item.value" | ||
| 27 | - :disabled="item.disabled" | ||
| 28 | - > | ||
| 29 | - {{ item.label }} | ||
| 30 | - </el-radio-button> | ||
| 31 | - </el-radio-group> | ||
| 32 | - </el-form-item> | ||
| 33 | - <el-form-item v-if="showFileName" label="文件名" prop="fileName"> | ||
| 34 | - <el-input v-model="formData.fileName" placeholder="请输入文件名" clearable /> | ||
| 35 | - </el-form-item> | ||
| 36 | - </el-col> | ||
| 37 | - </el-form> | ||
| 38 | - </el-row> | ||
| 39 | - | ||
| 40 | - <div slot="footer"> | ||
| 41 | - <el-button @click="close"> | ||
| 42 | - 取消 | ||
| 43 | - </el-button> | ||
| 44 | - <el-button type="primary" @click="handelConfirm"> | ||
| 45 | - 确定 | ||
| 46 | - </el-button> | ||
| 47 | - </div> | ||
| 48 | - </el-dialog> | ||
| 49 | - </div> | ||
| 50 | -</template> | ||
| 51 | -<script> | ||
| 52 | -export default { | ||
| 53 | - inheritAttrs: false, | ||
| 54 | - props: ['showFileName'], | ||
| 55 | - data() { | ||
| 56 | - return { | ||
| 57 | - formData: { | ||
| 58 | - fileName: undefined, | ||
| 59 | - type: 'file' | ||
| 60 | - }, | ||
| 61 | - rules: { | ||
| 62 | - fileName: [{ | ||
| 63 | - required: true, | ||
| 64 | - message: '请输入文件名', | ||
| 65 | - trigger: 'blur' | ||
| 66 | - }], | ||
| 67 | - type: [{ | ||
| 68 | - required: true, | ||
| 69 | - message: '生成类型不能为空', | ||
| 70 | - trigger: 'change' | ||
| 71 | - }] | ||
| 72 | - }, | ||
| 73 | - typeOptions: [{ | ||
| 74 | - label: '页面', | ||
| 75 | - value: 'file' | ||
| 76 | - }, { | ||
| 77 | - label: '弹窗', | ||
| 78 | - value: 'dialog' | ||
| 79 | - }] | ||
| 80 | - } | ||
| 81 | - }, | ||
| 82 | - computed: { | ||
| 83 | - }, | ||
| 84 | - watch: {}, | ||
| 85 | - mounted() {}, | ||
| 86 | - methods: { | ||
| 87 | - onOpen() { | ||
| 88 | - if (this.showFileName) { | ||
| 89 | - this.formData.fileName = `${+new Date()}.vue` | ||
| 90 | - } | ||
| 91 | - }, | ||
| 92 | - onClose() { | ||
| 93 | - }, | ||
| 94 | - close(e) { | ||
| 95 | - this.$emit('update:visible', false) | ||
| 96 | - }, | ||
| 97 | - handelConfirm() { | ||
| 98 | - this.$refs.elForm.validate(valid => { | ||
| 99 | - if (!valid) return | ||
| 100 | - this.$emit('confirm', { ...this.formData }) | ||
| 101 | - this.close() | ||
| 102 | - }) | ||
| 103 | - } | ||
| 104 | - } | ||
| 105 | -} | ||
| 106 | -</script> | 1 | +<template> |
| 2 | + <div> | ||
| 3 | + <el-dialog | ||
| 4 | + v-bind="$attrs" | ||
| 5 | + width="500px" | ||
| 6 | + :close-on-click-modal="false" | ||
| 7 | + :modal-append-to-body="false" | ||
| 8 | + v-on="$listeners" | ||
| 9 | + @open="onOpen" | ||
| 10 | + @close="onClose" | ||
| 11 | + > | ||
| 12 | + <el-row :gutter="15"> | ||
| 13 | + <el-form | ||
| 14 | + ref="elForm" | ||
| 15 | + :model="formData" | ||
| 16 | + :rules="rules" | ||
| 17 | + size="medium" | ||
| 18 | + label-width="100px" | ||
| 19 | + > | ||
| 20 | + <el-col :span="24"> | ||
| 21 | + <el-form-item label="生成类型" prop="type"> | ||
| 22 | + <el-radio-group v-model="formData.type"> | ||
| 23 | + <el-radio-button | ||
| 24 | + v-for="(item, index) in typeOptions" | ||
| 25 | + :key="index" | ||
| 26 | + :label="item.value" | ||
| 27 | + :disabled="item.disabled" | ||
| 28 | + > | ||
| 29 | + {{ item.label }} | ||
| 30 | + </el-radio-button> | ||
| 31 | + </el-radio-group> | ||
| 32 | + </el-form-item> | ||
| 33 | + <el-form-item v-if="showFileName" label="文件名" prop="fileName"> | ||
| 34 | + <el-input v-model="formData.fileName" placeholder="请输入文件名" clearable /> | ||
| 35 | + </el-form-item> | ||
| 36 | + </el-col> | ||
| 37 | + </el-form> | ||
| 38 | + </el-row> | ||
| 39 | + | ||
| 40 | + <div slot="footer"> | ||
| 41 | + <el-button @click="close"> | ||
| 42 | + 取消 | ||
| 43 | + </el-button> | ||
| 44 | + <el-button type="primary" @click="handleConfirm"> | ||
| 45 | + 确定 | ||
| 46 | + </el-button> | ||
| 47 | + </div> | ||
| 48 | + </el-dialog> | ||
| 49 | + </div> | ||
| 50 | +</template> | ||
| 51 | +<script> | ||
| 52 | +export default { | ||
| 53 | + inheritAttrs: false, | ||
| 54 | + props: ['showFileName'], | ||
| 55 | + data() { | ||
| 56 | + return { | ||
| 57 | + formData: { | ||
| 58 | + fileName: undefined, | ||
| 59 | + type: 'file' | ||
| 60 | + }, | ||
| 61 | + rules: { | ||
| 62 | + fileName: [{ | ||
| 63 | + required: true, | ||
| 64 | + message: '请输入文件名', | ||
| 65 | + trigger: 'blur' | ||
| 66 | + }], | ||
| 67 | + type: [{ | ||
| 68 | + required: true, | ||
| 69 | + message: '生成类型不能为空', | ||
| 70 | + trigger: 'change' | ||
| 71 | + }] | ||
| 72 | + }, | ||
| 73 | + typeOptions: [{ | ||
| 74 | + label: '页面', | ||
| 75 | + value: 'file' | ||
| 76 | + }, { | ||
| 77 | + label: '弹窗', | ||
| 78 | + value: 'dialog' | ||
| 79 | + }] | ||
| 80 | + } | ||
| 81 | + }, | ||
| 82 | + computed: { | ||
| 83 | + }, | ||
| 84 | + watch: {}, | ||
| 85 | + mounted() {}, | ||
| 86 | + methods: { | ||
| 87 | + onOpen() { | ||
| 88 | + if (this.showFileName) { | ||
| 89 | + this.formData.fileName = `${+new Date()}.vue` | ||
| 90 | + } | ||
| 91 | + }, | ||
| 92 | + onClose() { | ||
| 93 | + }, | ||
| 94 | + close(e) { | ||
| 95 | + this.$emit('update:visible', false) | ||
| 96 | + }, | ||
| 97 | + handleConfirm() { | ||
| 98 | + this.$refs.elForm.validate(valid => { | ||
| 99 | + if (!valid) return | ||
| 100 | + this.$emit('confirm', { ...this.formData }) | ||
| 101 | + this.close() | ||
| 102 | + }) | ||
| 103 | + } | ||
| 104 | + } | ||
| 105 | +} | ||
| 106 | +</script> |
| 1 | -<template> | ||
| 2 | - <div> | ||
| 3 | - <el-dialog | ||
| 4 | - v-bind="$attrs" | ||
| 5 | - :close-on-click-modal="false" | ||
| 6 | - :modal-append-to-body="false" | ||
| 7 | - v-on="$listeners" | ||
| 8 | - @open="onOpen" | ||
| 9 | - @close="onClose" | ||
| 10 | - > | ||
| 11 | - <el-row :gutter="0"> | ||
| 12 | - <el-form | ||
| 13 | - ref="elForm" | ||
| 14 | - :model="formData" | ||
| 15 | - :rules="rules" | ||
| 16 | - size="small" | ||
| 17 | - label-width="100px" | ||
| 18 | - > | ||
| 19 | - <el-col :span="24"> | ||
| 20 | - <el-form-item | ||
| 21 | - label="选项名" | ||
| 22 | - prop="label" | ||
| 23 | - > | ||
| 24 | - <el-input | ||
| 25 | - v-model="formData.label" | ||
| 26 | - placeholder="请输入选项名" | ||
| 27 | - clearable | ||
| 28 | - /> | ||
| 29 | - </el-form-item> | ||
| 30 | - </el-col> | ||
| 31 | - <el-col :span="24"> | ||
| 32 | - <el-form-item | ||
| 33 | - label="选项值" | ||
| 34 | - prop="value" | ||
| 35 | - > | ||
| 36 | - <el-input | ||
| 37 | - v-model="formData.value" | ||
| 38 | - placeholder="请输入选项值" | ||
| 39 | - clearable | ||
| 40 | - > | ||
| 41 | - <el-select | ||
| 42 | - slot="append" | ||
| 43 | - v-model="dataType" | ||
| 44 | - :style="{width: '100px'}" | ||
| 45 | - > | ||
| 46 | - <el-option | ||
| 47 | - v-for="(item, index) in dataTypeOptions" | ||
| 48 | - :key="index" | ||
| 49 | - :label="item.label" | ||
| 50 | - :value="item.value" | ||
| 51 | - :disabled="item.disabled" | ||
| 52 | - /> | ||
| 53 | - </el-select> | ||
| 54 | - </el-input> | ||
| 55 | - </el-form-item> | ||
| 56 | - </el-col> | ||
| 57 | - </el-form> | ||
| 58 | - </el-row> | ||
| 59 | - <div slot="footer"> | ||
| 60 | - <el-button | ||
| 61 | - type="primary" | ||
| 62 | - @click="handelConfirm" | ||
| 63 | - > | ||
| 64 | - 确定 | ||
| 65 | - </el-button> | ||
| 66 | - <el-button @click="close"> | ||
| 67 | - 取消 | ||
| 68 | - </el-button> | ||
| 69 | - </div> | ||
| 70 | - </el-dialog> | ||
| 71 | - </div> | ||
| 72 | -</template> | ||
| 73 | -<script> | ||
| 74 | -import { isNumberStr } from '@/utils/index' | ||
| 75 | - | ||
| 76 | -export default { | ||
| 77 | - components: {}, | ||
| 78 | - inheritAttrs: false, | ||
| 79 | - props: [], | ||
| 80 | - data() { | ||
| 81 | - return { | ||
| 82 | - id: 100, | ||
| 83 | - formData: { | ||
| 84 | - label: undefined, | ||
| 85 | - value: undefined | ||
| 86 | - }, | ||
| 87 | - rules: { | ||
| 88 | - label: [ | ||
| 89 | - { | ||
| 90 | - required: true, | ||
| 91 | - message: '请输入选项名', | ||
| 92 | - trigger: 'blur' | ||
| 93 | - } | ||
| 94 | - ], | ||
| 95 | - value: [ | ||
| 96 | - { | ||
| 97 | - required: true, | ||
| 98 | - message: '请输入选项值', | ||
| 99 | - trigger: 'blur' | ||
| 100 | - } | ||
| 101 | - ] | ||
| 102 | - }, | ||
| 103 | - dataType: 'string', | ||
| 104 | - dataTypeOptions: [ | ||
| 105 | - { | ||
| 106 | - label: '字符串', | ||
| 107 | - value: 'string' | ||
| 108 | - }, | ||
| 109 | - { | ||
| 110 | - label: '数字', | ||
| 111 | - value: 'number' | ||
| 112 | - } | ||
| 113 | - ] | ||
| 114 | - } | ||
| 115 | - }, | ||
| 116 | - computed: {}, | ||
| 117 | - watch: { | ||
| 118 | - // eslint-disable-next-line func-names | ||
| 119 | - 'formData.value': function (val) { | ||
| 120 | - this.dataType = isNumberStr(val) ? 'number' : 'string' | ||
| 121 | - } | ||
| 122 | - }, | ||
| 123 | - created() {}, | ||
| 124 | - mounted() {}, | ||
| 125 | - methods: { | ||
| 126 | - onOpen() { | ||
| 127 | - this.formData = { | ||
| 128 | - label: undefined, | ||
| 129 | - value: undefined | ||
| 130 | - } | ||
| 131 | - }, | ||
| 132 | - onClose() {}, | ||
| 133 | - close() { | ||
| 134 | - this.$emit('update:visible', false) | ||
| 135 | - }, | ||
| 136 | - handelConfirm() { | ||
| 137 | - this.$refs.elForm.validate(valid => { | ||
| 138 | - if (!valid) return | ||
| 139 | - if (this.dataType === 'number') { | ||
| 140 | - this.formData.value = parseFloat(this.formData.value) | ||
| 141 | - } | ||
| 142 | - this.formData.id = this.id++ | ||
| 143 | - this.$emit('commit', this.formData) | ||
| 144 | - this.close() | ||
| 145 | - }) | ||
| 146 | - } | ||
| 147 | - } | ||
| 148 | -} | ||
| 149 | -</script> | 1 | +<template> |
| 2 | + <div> | ||
| 3 | + <el-dialog | ||
| 4 | + v-bind="$attrs" | ||
| 5 | + :close-on-click-modal="false" | ||
| 6 | + :modal-append-to-body="false" | ||
| 7 | + v-on="$listeners" | ||
| 8 | + @open="onOpen" | ||
| 9 | + @close="onClose" | ||
| 10 | + > | ||
| 11 | + <el-row :gutter="0"> | ||
| 12 | + <el-form | ||
| 13 | + ref="elForm" | ||
| 14 | + :model="formData" | ||
| 15 | + :rules="rules" | ||
| 16 | + size="small" | ||
| 17 | + label-width="100px" | ||
| 18 | + > | ||
| 19 | + <el-col :span="24"> | ||
| 20 | + <el-form-item | ||
| 21 | + label="选项名" | ||
| 22 | + prop="label" | ||
| 23 | + > | ||
| 24 | + <el-input | ||
| 25 | + v-model="formData.label" | ||
| 26 | + placeholder="请输入选项名" | ||
| 27 | + clearable | ||
| 28 | + /> | ||
| 29 | + </el-form-item> | ||
| 30 | + </el-col> | ||
| 31 | + <el-col :span="24"> | ||
| 32 | + <el-form-item | ||
| 33 | + label="选项值" | ||
| 34 | + prop="value" | ||
| 35 | + > | ||
| 36 | + <el-input | ||
| 37 | + v-model="formData.value" | ||
| 38 | + placeholder="请输入选项值" | ||
| 39 | + clearable | ||
| 40 | + > | ||
| 41 | + <el-select | ||
| 42 | + slot="append" | ||
| 43 | + v-model="dataType" | ||
| 44 | + :style="{width: '100px'}" | ||
| 45 | + > | ||
| 46 | + <el-option | ||
| 47 | + v-for="(item, index) in dataTypeOptions" | ||
| 48 | + :key="index" | ||
| 49 | + :label="item.label" | ||
| 50 | + :value="item.value" | ||
| 51 | + :disabled="item.disabled" | ||
| 52 | + /> | ||
| 53 | + </el-select> | ||
| 54 | + </el-input> | ||
| 55 | + </el-form-item> | ||
| 56 | + </el-col> | ||
| 57 | + </el-form> | ||
| 58 | + </el-row> | ||
| 59 | + <div slot="footer"> | ||
| 60 | + <el-button | ||
| 61 | + type="primary" | ||
| 62 | + @click="handleConfirm" | ||
| 63 | + > | ||
| 64 | + 确定 | ||
| 65 | + </el-button> | ||
| 66 | + <el-button @click="close"> | ||
| 67 | + 取消 | ||
| 68 | + </el-button> | ||
| 69 | + </div> | ||
| 70 | + </el-dialog> | ||
| 71 | + </div> | ||
| 72 | +</template> | ||
| 73 | +<script> | ||
| 74 | +import { isNumberStr } from '@/utils/index' | ||
| 75 | + | ||
| 76 | +export default { | ||
| 77 | + components: {}, | ||
| 78 | + inheritAttrs: false, | ||
| 79 | + props: [], | ||
| 80 | + data() { | ||
| 81 | + return { | ||
| 82 | + id: 100, | ||
| 83 | + formData: { | ||
| 84 | + label: undefined, | ||
| 85 | + value: undefined | ||
| 86 | + }, | ||
| 87 | + rules: { | ||
| 88 | + label: [ | ||
| 89 | + { | ||
| 90 | + required: true, | ||
| 91 | + message: '请输入选项名', | ||
| 92 | + trigger: 'blur' | ||
| 93 | + } | ||
| 94 | + ], | ||
| 95 | + value: [ | ||
| 96 | + { | ||
| 97 | + required: true, | ||
| 98 | + message: '请输入选项值', | ||
| 99 | + trigger: 'blur' | ||
| 100 | + } | ||
| 101 | + ] | ||
| 102 | + }, | ||
| 103 | + dataType: 'string', | ||
| 104 | + dataTypeOptions: [ | ||
| 105 | + { | ||
| 106 | + label: '字符串', | ||
| 107 | + value: 'string' | ||
| 108 | + }, | ||
| 109 | + { | ||
| 110 | + label: '数字', | ||
| 111 | + value: 'number' | ||
| 112 | + } | ||
| 113 | + ] | ||
| 114 | + } | ||
| 115 | + }, | ||
| 116 | + computed: {}, | ||
| 117 | + watch: { | ||
| 118 | + // eslint-disable-next-line func-names | ||
| 119 | + 'formData.value': function (val) { | ||
| 120 | + this.dataType = isNumberStr(val) ? 'number' : 'string' | ||
| 121 | + } | ||
| 122 | + }, | ||
| 123 | + created() {}, | ||
| 124 | + mounted() {}, | ||
| 125 | + methods: { | ||
| 126 | + onOpen() { | ||
| 127 | + this.formData = { | ||
| 128 | + label: undefined, | ||
| 129 | + value: undefined | ||
| 130 | + } | ||
| 131 | + }, | ||
| 132 | + onClose() {}, | ||
| 133 | + close() { | ||
| 134 | + this.$emit('update:visible', false) | ||
| 135 | + }, | ||
| 136 | + handleConfirm() { | ||
| 137 | + this.$refs.elForm.validate(valid => { | ||
| 138 | + if (!valid) return | ||
| 139 | + if (this.dataType === 'number') { | ||
| 140 | + this.formData.value = parseFloat(this.formData.value) | ||
| 141 | + } | ||
| 142 | + this.formData.id = this.id++ | ||
| 143 | + this.$emit('commit', this.formData) | ||
| 144 | + this.close() | ||
| 145 | + }) | ||
| 146 | + } | ||
| 147 | + } | ||
| 148 | +} | ||
| 149 | +</script> |
| 1 | -<template> | ||
| 2 | - <div class="container"> | ||
| 3 | - <div class="left-board"> | ||
| 4 | - <div class="logo-wrapper"> | ||
| 5 | - <div class="logo"> | ||
| 6 | - <img :src="logo" alt="logo"> Form Generator | ||
| 7 | - </div> | ||
| 8 | - </div> | ||
| 9 | - <el-scrollbar class="left-scrollbar"> | ||
| 10 | - <div class="components-list"> | ||
| 11 | - <div class="components-title"> | ||
| 12 | - <svg-icon icon-class="component" />输入型组件 | ||
| 13 | - </div> | ||
| 14 | - <draggable | ||
| 15 | - class="components-draggable" | ||
| 16 | - :list="inputComponents" | ||
| 17 | - :group="{ name: 'componentsGroup', pull: 'clone', put: false }" | ||
| 18 | - :clone="cloneComponent" | ||
| 19 | - draggable=".components-item" | ||
| 20 | - :sort="false" | ||
| 21 | - @end="onEnd" | ||
| 22 | - > | ||
| 23 | - <div | ||
| 24 | - v-for="(element, index) in inputComponents" :key="index" class="components-item" | ||
| 25 | - @click="addComponent(element)" | ||
| 26 | - > | ||
| 27 | - <div class="components-body"> | ||
| 28 | - <svg-icon :icon-class="element.tagIcon" /> | ||
| 29 | - {{ element.label }} | ||
| 30 | - </div> | ||
| 31 | - </div> | ||
| 32 | - </draggable> | ||
| 33 | - <div class="components-title"> | ||
| 34 | - <svg-icon icon-class="component" />选择型组件 | ||
| 35 | - </div> | ||
| 36 | - <draggable | ||
| 37 | - class="components-draggable" | ||
| 38 | - :list="selectComponents" | ||
| 39 | - :group="{ name: 'componentsGroup', pull: 'clone', put: false }" | ||
| 40 | - :clone="cloneComponent" | ||
| 41 | - draggable=".components-item" | ||
| 42 | - :sort="false" | ||
| 43 | - @end="onEnd" | ||
| 44 | - > | ||
| 45 | - <div | ||
| 46 | - v-for="(element, index) in selectComponents" | ||
| 47 | - :key="index" | ||
| 48 | - class="components-item" | ||
| 49 | - @click="addComponent(element)" | ||
| 50 | - > | ||
| 51 | - <div class="components-body"> | ||
| 52 | - <svg-icon :icon-class="element.tagIcon" /> | ||
| 53 | - {{ element.label }} | ||
| 54 | - </div> | ||
| 55 | - </div> | ||
| 56 | - </draggable> | ||
| 57 | - <div class="components-title"> | ||
| 58 | - <svg-icon icon-class="component" /> 布局型组件 | ||
| 59 | - </div> | ||
| 60 | - <draggable | ||
| 61 | - class="components-draggable" :list="layoutComponents" | ||
| 62 | - :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent" | ||
| 63 | - draggable=".components-item" :sort="false" @end="onEnd" | ||
| 64 | - > | ||
| 65 | - <div | ||
| 66 | - v-for="(element, index) in layoutComponents" :key="index" class="components-item" | ||
| 67 | - @click="addComponent(element)" | ||
| 68 | - > | ||
| 69 | - <div class="components-body"> | ||
| 70 | - <svg-icon :icon-class="element.tagIcon" /> | ||
| 71 | - {{ element.label }} | ||
| 72 | - </div> | ||
| 73 | - </div> | ||
| 74 | - </draggable> | ||
| 75 | - </div> | ||
| 76 | - </el-scrollbar> | ||
| 77 | - </div> | ||
| 78 | - | ||
| 79 | - <div class="center-board"> | ||
| 80 | - <div class="action-bar"> | ||
| 81 | - <el-button icon="el-icon-download" type="text" @click="download"> | ||
| 82 | - 导出vue文件 | ||
| 83 | - </el-button> | ||
| 84 | - <el-button class="copy-btn-main" icon="el-icon-document-copy" type="text" @click="copy"> | ||
| 85 | - 复制代码 | ||
| 86 | - </el-button> | ||
| 87 | - <el-button class="delete-btn" icon="el-icon-delete" type="text" @click="empty"> | ||
| 88 | - 清空 | ||
| 89 | - </el-button> | ||
| 90 | - </div> | ||
| 91 | - <el-scrollbar class="center-scrollbar"> | ||
| 92 | - <el-row class="center-board-row" :gutter="formConf.gutter"> | ||
| 93 | - <el-form | ||
| 94 | - :size="formConf.size" | ||
| 95 | - :label-position="formConf.labelPosition" | ||
| 96 | - :disabled="formConf.disabled" | ||
| 97 | - :label-width="formConf.labelWidth + 'px'" | ||
| 98 | - > | ||
| 99 | - <draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup"> | ||
| 100 | - <draggable-item | ||
| 101 | - v-for="(element, index) in drawingList" | ||
| 102 | - :key="element.renderKey" | ||
| 103 | - :drawing-list="drawingList" | ||
| 104 | - :element="element" | ||
| 105 | - :index="index" | ||
| 106 | - :active-id="activeId" | ||
| 107 | - :form-conf="formConf" | ||
| 108 | - @activeItem="activeFormItem" | ||
| 109 | - @copyItem="drawingItemCopy" | ||
| 110 | - @deleteItem="drawingItemDelete" | ||
| 111 | - /> | ||
| 112 | - </draggable> | ||
| 113 | - <div v-show="!drawingList.length" class="empty-info"> | ||
| 114 | - 从左侧拖入或点选组件进行表单设计 | ||
| 115 | - </div> | ||
| 116 | - </el-form> | ||
| 117 | - </el-row> | ||
| 118 | - </el-scrollbar> | ||
| 119 | - </div> | ||
| 120 | - | ||
| 121 | - <right-panel | ||
| 122 | - :active-data="activeData" | ||
| 123 | - :form-conf="formConf" | ||
| 124 | - :show-field="!!drawingList.length" | ||
| 125 | - @tag-change="tagChange" | ||
| 126 | - /> | ||
| 127 | - | ||
| 128 | - <code-type-dialog | ||
| 129 | - :visible.sync="dialogVisible" | ||
| 130 | - title="选择生成类型" | ||
| 131 | - :show-file-name="showFileName" | ||
| 132 | - @confirm="generate" | ||
| 133 | - /> | ||
| 134 | - <input id="copyNode" type="hidden"> | ||
| 135 | - </div> | ||
| 136 | -</template> | ||
| 137 | - | ||
| 138 | -<script> | ||
| 139 | -import draggable from 'vuedraggable' | ||
| 140 | -import beautifier from 'js-beautify' | ||
| 141 | -import ClipboardJS from 'clipboard' | ||
| 142 | -import render from '@/utils/generator/render' | ||
| 143 | -import RightPanel from './RightPanel' | ||
| 144 | -import { inputComponents, selectComponents, layoutComponents, formConf } from '@/utils/generator/config' | ||
| 145 | -import { beautifierConf, titleCase } from '@/utils/index' | ||
| 146 | -import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html' | ||
| 147 | -import { makeUpJs } from '@/utils/generator/js' | ||
| 148 | -import { makeUpCss } from '@/utils/generator/css' | ||
| 149 | -import drawingDefalut from '@/utils/generator/drawingDefalut' | ||
| 150 | -import logo from '@/assets/logo/logo.png' | ||
| 151 | -import CodeTypeDialog from './CodeTypeDialog' | ||
| 152 | -import DraggableItem from './DraggableItem' | ||
| 153 | - | ||
| 154 | -let oldActiveId | ||
| 155 | -let tempActiveData | ||
| 156 | - | ||
| 157 | -export default { | ||
| 158 | - components: { | ||
| 159 | - draggable, | ||
| 160 | - render, | ||
| 161 | - RightPanel, | ||
| 162 | - CodeTypeDialog, | ||
| 163 | - DraggableItem | ||
| 164 | - }, | ||
| 165 | - data() { | ||
| 166 | - return { | ||
| 167 | - logo, | ||
| 168 | - idGlobal: 100, | ||
| 169 | - formConf, | ||
| 170 | - inputComponents, | ||
| 171 | - selectComponents, | ||
| 172 | - layoutComponents, | ||
| 173 | - labelWidth: 100, | ||
| 174 | - drawingList: drawingDefalut, | ||
| 175 | - drawingData: {}, | ||
| 176 | - activeId: drawingDefalut[0].formId, | ||
| 177 | - drawerVisible: false, | ||
| 178 | - formData: {}, | ||
| 179 | - dialogVisible: false, | ||
| 180 | - generateConf: null, | ||
| 181 | - showFileName: false, | ||
| 182 | - activeData: drawingDefalut[0] | ||
| 183 | - } | ||
| 184 | - }, | ||
| 185 | - created() { | ||
| 186 | - // 防止 firefox 下 拖拽 会新打卡一个选项卡 | ||
| 187 | - document.body.ondrop = event => { | ||
| 188 | - event.preventDefault() | ||
| 189 | - event.stopPropagation() | ||
| 190 | - } | ||
| 191 | - }, | ||
| 192 | - watch: { | ||
| 193 | - // eslint-disable-next-line func-names | ||
| 194 | - 'activeData.label': function (val, oldVal) { | ||
| 195 | - if ( | ||
| 196 | - this.activeData.placeholder === undefined | ||
| 197 | - || !this.activeData.tag | ||
| 198 | - || oldActiveId !== this.activeId | ||
| 199 | - ) { | ||
| 200 | - return | ||
| 201 | - } | ||
| 202 | - this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val | ||
| 203 | - }, | ||
| 204 | - activeId: { | ||
| 205 | - handler(val) { | ||
| 206 | - oldActiveId = val | ||
| 207 | - }, | ||
| 208 | - immediate: true | ||
| 209 | - } | ||
| 210 | - }, | ||
| 211 | - mounted() { | ||
| 212 | - const clipboard = new ClipboardJS('#copyNode', { | ||
| 213 | - text: trigger => { | ||
| 214 | - const codeStr = this.generateCode() | ||
| 215 | - this.$notify({ | ||
| 216 | - title: '成功', | ||
| 217 | - message: '代码已复制到剪切板,可粘贴。', | ||
| 218 | - type: 'success' | ||
| 219 | - }) | ||
| 220 | - return codeStr | ||
| 221 | - } | ||
| 222 | - }) | ||
| 223 | - clipboard.on('error', e => { | ||
| 224 | - this.$message.error('代码复制失败') | ||
| 225 | - }) | ||
| 226 | - }, | ||
| 227 | - methods: { | ||
| 228 | - activeFormItem(element) { | ||
| 229 | - this.activeData = element | ||
| 230 | - this.activeId = element.formId | ||
| 231 | - }, | ||
| 232 | - onEnd(obj, a) { | ||
| 233 | - if (obj.from !== obj.to) { | ||
| 234 | - this.activeData = tempActiveData | ||
| 235 | - this.activeId = this.idGlobal | ||
| 236 | - } | ||
| 237 | - }, | ||
| 238 | - addComponent(item) { | ||
| 239 | - const clone = this.cloneComponent(item) | ||
| 240 | - this.drawingList.push(clone) | ||
| 241 | - this.activeFormItem(clone) | ||
| 242 | - }, | ||
| 243 | - cloneComponent(origin) { | ||
| 244 | - const clone = JSON.parse(JSON.stringify(origin)) | ||
| 245 | - clone.formId = ++this.idGlobal | ||
| 246 | - clone.span = formConf.span | ||
| 247 | - clone.renderKey = +new Date() // 改变renderKey后可以实现强制更新组件 | ||
| 248 | - if (!clone.layout) clone.layout = 'colFormItem' | ||
| 249 | - if (clone.layout === 'colFormItem') { | ||
| 250 | - clone.vModel = `field${this.idGlobal}` | ||
| 251 | - clone.placeholder !== undefined && (clone.placeholder += clone.label) | ||
| 252 | - tempActiveData = clone | ||
| 253 | - } else if (clone.layout === 'rowFormItem') { | ||
| 254 | - delete clone.label | ||
| 255 | - clone.componentName = `row${this.idGlobal}` | ||
| 256 | - clone.gutter = this.formConf.gutter | ||
| 257 | - tempActiveData = clone | ||
| 258 | - } | ||
| 259 | - return tempActiveData | ||
| 260 | - }, | ||
| 261 | - AssembleFormData() { | ||
| 262 | - this.formData = { | ||
| 263 | - fields: JSON.parse(JSON.stringify(this.drawingList)), | ||
| 264 | - ...this.formConf | ||
| 265 | - } | ||
| 266 | - }, | ||
| 267 | - generate(data) { | ||
| 268 | - const func = this[`exec${titleCase(this.operationType)}`] | ||
| 269 | - this.generateConf = data | ||
| 270 | - func && func(data) | ||
| 271 | - }, | ||
| 272 | - execRun(data) { | ||
| 273 | - this.AssembleFormData() | ||
| 274 | - this.drawerVisible = true | ||
| 275 | - }, | ||
| 276 | - execDownload(data) { | ||
| 277 | - const codeStr = this.generateCode() | ||
| 278 | - const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' }) | ||
| 279 | - this.$download.saveAs(blob, data.fileName) | ||
| 280 | - }, | ||
| 281 | - execCopy(data) { | ||
| 282 | - document.getElementById('copyNode').click() | ||
| 283 | - }, | ||
| 284 | - empty() { | ||
| 285 | - this.$confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then( | ||
| 286 | - () => { | ||
| 287 | - this.drawingList = [] | ||
| 288 | - } | ||
| 289 | - ) | ||
| 290 | - }, | ||
| 291 | - drawingItemCopy(item, parent) { | ||
| 292 | - let clone = JSON.parse(JSON.stringify(item)) | ||
| 293 | - clone = this.createIdAndKey(clone) | ||
| 294 | - parent.push(clone) | ||
| 295 | - this.activeFormItem(clone) | ||
| 296 | - }, | ||
| 297 | - createIdAndKey(item) { | ||
| 298 | - item.formId = ++this.idGlobal | ||
| 299 | - item.renderKey = +new Date() | ||
| 300 | - if (item.layout === 'colFormItem') { | ||
| 301 | - item.vModel = `field${this.idGlobal}` | ||
| 302 | - } else if (item.layout === 'rowFormItem') { | ||
| 303 | - item.componentName = `row${this.idGlobal}` | ||
| 304 | - } | ||
| 305 | - if (Array.isArray(item.children)) { | ||
| 306 | - item.children = item.children.map(childItem => this.createIdAndKey(childItem)) | ||
| 307 | - } | ||
| 308 | - return item | ||
| 309 | - }, | ||
| 310 | - drawingItemDelete(index, parent) { | ||
| 311 | - parent.splice(index, 1) | ||
| 312 | - this.$nextTick(() => { | ||
| 313 | - const len = this.drawingList.length | ||
| 314 | - if (len) { | ||
| 315 | - this.activeFormItem(this.drawingList[len - 1]) | ||
| 316 | - } | ||
| 317 | - }) | ||
| 318 | - }, | ||
| 319 | - generateCode() { | ||
| 320 | - const { type } = this.generateConf | ||
| 321 | - this.AssembleFormData() | ||
| 322 | - const script = vueScript(makeUpJs(this.formData, type)) | ||
| 323 | - const html = vueTemplate(makeUpHtml(this.formData, type)) | ||
| 324 | - const css = cssStyle(makeUpCss(this.formData)) | ||
| 325 | - return beautifier.html(html + script + css, beautifierConf.html) | ||
| 326 | - }, | ||
| 327 | - download() { | ||
| 328 | - this.dialogVisible = true | ||
| 329 | - this.showFileName = true | ||
| 330 | - this.operationType = 'download' | ||
| 331 | - }, | ||
| 332 | - run() { | ||
| 333 | - this.dialogVisible = true | ||
| 334 | - this.showFileName = false | ||
| 335 | - this.operationType = 'run' | ||
| 336 | - }, | ||
| 337 | - copy() { | ||
| 338 | - this.dialogVisible = true | ||
| 339 | - this.showFileName = false | ||
| 340 | - this.operationType = 'copy' | ||
| 341 | - }, | ||
| 342 | - tagChange(newTag) { | ||
| 343 | - newTag = this.cloneComponent(newTag) | ||
| 344 | - newTag.vModel = this.activeData.vModel | ||
| 345 | - newTag.formId = this.activeId | ||
| 346 | - newTag.span = this.activeData.span | ||
| 347 | - delete this.activeData.tag | ||
| 348 | - delete this.activeData.tagIcon | ||
| 349 | - delete this.activeData.document | ||
| 350 | - Object.keys(newTag).forEach(key => { | ||
| 351 | - if (this.activeData[key] !== undefined | ||
| 352 | - && typeof this.activeData[key] === typeof newTag[key]) { | ||
| 353 | - newTag[key] = this.activeData[key] | ||
| 354 | - } | ||
| 355 | - }) | ||
| 356 | - this.activeData = newTag | ||
| 357 | - this.updateDrawingList(newTag, this.drawingList) | ||
| 358 | - }, | ||
| 359 | - updateDrawingList(newTag, list) { | ||
| 360 | - const index = list.findIndex(item => item.formId === this.activeId) | ||
| 361 | - if (index > -1) { | ||
| 362 | - list.splice(index, 1, newTag) | ||
| 363 | - } else { | ||
| 364 | - list.forEach(item => { | ||
| 365 | - if (Array.isArray(item.children)) this.updateDrawingList(newTag, item.children) | ||
| 366 | - }) | ||
| 367 | - } | ||
| 368 | - } | ||
| 369 | - } | ||
| 370 | -} | ||
| 371 | -</script> | ||
| 372 | - | ||
| 373 | -<style lang='scss'> | ||
| 374 | -body, html{ | ||
| 375 | - margin: 0; | ||
| 376 | - padding: 0; | ||
| 377 | - background: #fff; | ||
| 378 | - --moz-osx-font-smoothing: grayscale; | ||
| 379 | - --webkit-font-smoothing: antialiased; | ||
| 380 | - text-rendering: optimizeLegibility; | ||
| 381 | - font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; | ||
| 382 | -} | ||
| 383 | - | ||
| 384 | -input, textarea{ | ||
| 385 | - font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; | ||
| 386 | -} | ||
| 387 | - | ||
| 388 | -.editor-tabs{ | ||
| 389 | - background: #121315; | ||
| 390 | - .el-tabs__header{ | ||
| 391 | - margin: 0; | ||
| 392 | - border-bottom-color: #121315; | ||
| 393 | - .el-tabs__nav{ | ||
| 394 | - border-color: #121315; | ||
| 395 | - } | ||
| 396 | - } | ||
| 397 | - .el-tabs__item{ | ||
| 398 | - height: 32px; | ||
| 399 | - line-height: 32px; | ||
| 400 | - color: #888a8e; | ||
| 401 | - border-left: 1px solid #121315 !important; | ||
| 402 | - background: #363636; | ||
| 403 | - margin-right: 5px; | ||
| 404 | - user-select: none; | ||
| 405 | - } | ||
| 406 | - .el-tabs__item.is-active{ | ||
| 407 | - background: #1e1e1e; | ||
| 408 | - border-bottom-color: #1e1e1e!important; | ||
| 409 | - color: #fff; | ||
| 410 | - } | ||
| 411 | - .el-icon-edit{ | ||
| 412 | - color: #f1fa8c; | ||
| 413 | - } | ||
| 414 | - .el-icon-document{ | ||
| 415 | - color: #a95812; | ||
| 416 | - } | ||
| 417 | -} | ||
| 418 | - | ||
| 419 | -// home | ||
| 420 | -.right-scrollbar { | ||
| 421 | - .el-scrollbar__view { | ||
| 422 | - padding: 12px 18px 15px 15px; | ||
| 423 | - } | ||
| 424 | -} | ||
| 425 | -.left-scrollbar .el-scrollbar__wrap { | ||
| 426 | - box-sizing: border-box; | ||
| 427 | - overflow-x: hidden !important; | ||
| 428 | - margin-bottom: 0 !important; | ||
| 429 | -} | ||
| 430 | -.center-tabs{ | ||
| 431 | - .el-tabs__header{ | ||
| 432 | - margin-bottom: 0!important; | ||
| 433 | - } | ||
| 434 | - .el-tabs__item{ | ||
| 435 | - width: 50%; | ||
| 436 | - text-align: center; | ||
| 437 | - } | ||
| 438 | - .el-tabs__nav{ | ||
| 439 | - width: 100%; | ||
| 440 | - } | ||
| 441 | -} | ||
| 442 | -.reg-item{ | ||
| 443 | - padding: 12px 6px; | ||
| 444 | - background: #f8f8f8; | ||
| 445 | - position: relative; | ||
| 446 | - border-radius: 4px; | ||
| 447 | - .close-btn{ | ||
| 448 | - position: absolute; | ||
| 449 | - right: -6px; | ||
| 450 | - top: -6px; | ||
| 451 | - display: block; | ||
| 452 | - width: 16px; | ||
| 453 | - height: 16px; | ||
| 454 | - line-height: 16px; | ||
| 455 | - background: rgba(0, 0, 0, 0.2); | ||
| 456 | - border-radius: 50%; | ||
| 457 | - color: #fff; | ||
| 458 | - text-align: center; | ||
| 459 | - z-index: 1; | ||
| 460 | - cursor: pointer; | ||
| 461 | - font-size: 12px; | ||
| 462 | - &:hover{ | ||
| 463 | - background: rgba(210, 23, 23, 0.5) | ||
| 464 | - } | ||
| 465 | - } | ||
| 466 | - & + .reg-item{ | ||
| 467 | - margin-top: 18px; | ||
| 468 | - } | ||
| 469 | -} | ||
| 470 | -.action-bar{ | ||
| 471 | - & .el-button+.el-button { | ||
| 472 | - margin-left: 15px; | ||
| 473 | - } | ||
| 474 | - & i { | ||
| 475 | - font-size: 20px; | ||
| 476 | - vertical-align: middle; | ||
| 477 | - position: relative; | ||
| 478 | - top: -1px; | ||
| 479 | - } | ||
| 480 | -} | ||
| 481 | - | ||
| 482 | -.custom-tree-node{ | ||
| 483 | - width: 100%; | ||
| 484 | - font-size: 14px; | ||
| 485 | - .node-operation{ | ||
| 486 | - float: right; | ||
| 487 | - } | ||
| 488 | - i[class*="el-icon"] + i[class*="el-icon"]{ | ||
| 489 | - margin-left: 6px; | ||
| 490 | - } | ||
| 491 | - .el-icon-plus{ | ||
| 492 | - color: #409EFF; | ||
| 493 | - } | ||
| 494 | - .el-icon-delete{ | ||
| 495 | - color: #157a0c; | ||
| 496 | - } | ||
| 497 | -} | ||
| 498 | - | ||
| 499 | -.left-scrollbar .el-scrollbar__view{ | ||
| 500 | - overflow-x: hidden; | ||
| 501 | -} | ||
| 502 | - | ||
| 503 | -.el-rate{ | ||
| 504 | - display: inline-block; | ||
| 505 | - vertical-align: text-top; | ||
| 506 | -} | ||
| 507 | -.el-upload__tip{ | ||
| 508 | - line-height: 1.2; | ||
| 509 | -} | ||
| 510 | - | ||
| 511 | -$selectedColor: #f6f7ff; | ||
| 512 | -$lighterBlue: #409EFF; | ||
| 513 | - | ||
| 514 | -.container { | ||
| 515 | - position: relative; | ||
| 516 | - width: 100%; | ||
| 517 | - height: 100%; | ||
| 518 | -} | ||
| 519 | - | ||
| 520 | -.components-list { | ||
| 521 | - padding: 8px; | ||
| 522 | - box-sizing: border-box; | ||
| 523 | - height: 100%; | ||
| 524 | - .components-item { | ||
| 525 | - display: inline-block; | ||
| 526 | - width: 48%; | ||
| 527 | - margin: 1%; | ||
| 528 | - transition: transform 0ms !important; | ||
| 529 | - } | ||
| 530 | -} | ||
| 531 | -.components-draggable{ | ||
| 532 | - padding-bottom: 20px; | ||
| 533 | -} | ||
| 534 | -.components-title{ | ||
| 535 | - font-size: 14px; | ||
| 536 | - color: #222; | ||
| 537 | - margin: 6px 2px; | ||
| 538 | - .svg-icon{ | ||
| 539 | - color: #666; | ||
| 540 | - font-size: 18px; | ||
| 541 | - } | ||
| 542 | -} | ||
| 543 | - | ||
| 544 | -.components-body { | ||
| 545 | - padding: 8px 10px; | ||
| 546 | - background: $selectedColor; | ||
| 547 | - font-size: 12px; | ||
| 548 | - cursor: move; | ||
| 549 | - border: 1px dashed $selectedColor; | ||
| 550 | - border-radius: 3px; | ||
| 551 | - .svg-icon{ | ||
| 552 | - color: #777; | ||
| 553 | - font-size: 15px; | ||
| 554 | - } | ||
| 555 | - &:hover { | ||
| 556 | - border: 1px dashed #787be8; | ||
| 557 | - color: #787be8; | ||
| 558 | - .svg-icon { | ||
| 559 | - color: #787be8; | ||
| 560 | - } | ||
| 561 | - } | ||
| 562 | -} | ||
| 563 | - | ||
| 564 | -.left-board { | ||
| 565 | - width: 260px; | ||
| 566 | - position: absolute; | ||
| 567 | - left: 0; | ||
| 568 | - top: 0; | ||
| 569 | - height: 100vh; | ||
| 570 | -} | ||
| 571 | -.left-scrollbar{ | ||
| 572 | - height: calc(100vh - 42px); | ||
| 573 | - overflow: hidden; | ||
| 574 | -} | ||
| 575 | -.center-scrollbar { | ||
| 576 | - height: calc(100vh - 42px); | ||
| 577 | - overflow: hidden; | ||
| 578 | - border-left: 1px solid #f1e8e8; | ||
| 579 | - border-right: 1px solid #f1e8e8; | ||
| 580 | - box-sizing: border-box; | ||
| 581 | -} | ||
| 582 | -.center-board { | ||
| 583 | - height: 100vh; | ||
| 584 | - width: auto; | ||
| 585 | - margin: 0 350px 0 260px; | ||
| 586 | - box-sizing: border-box; | ||
| 587 | -} | ||
| 588 | -.empty-info{ | ||
| 589 | - position: absolute; | ||
| 590 | - top: 46%; | ||
| 591 | - left: 0; | ||
| 592 | - right: 0; | ||
| 593 | - text-align: center; | ||
| 594 | - font-size: 18px; | ||
| 595 | - color: #ccb1ea; | ||
| 596 | - letter-spacing: 4px; | ||
| 597 | -} | ||
| 598 | -.action-bar{ | ||
| 599 | - position: relative; | ||
| 600 | - height: 42px; | ||
| 601 | - text-align: right; | ||
| 602 | - padding: 0 15px; | ||
| 603 | - box-sizing: border-box;; | ||
| 604 | - border: 1px solid #f1e8e8; | ||
| 605 | - border-top: none; | ||
| 606 | - border-left: none; | ||
| 607 | - .delete-btn{ | ||
| 608 | - color: #F56C6C; | ||
| 609 | - } | ||
| 610 | -} | ||
| 611 | -.logo-wrapper{ | ||
| 612 | - position: relative; | ||
| 613 | - height: 42px; | ||
| 614 | - background: #fff; | ||
| 615 | - border-bottom: 1px solid #f1e8e8; | ||
| 616 | - box-sizing: border-box; | ||
| 617 | -} | ||
| 618 | -.logo{ | ||
| 619 | - position: absolute; | ||
| 620 | - left: 12px; | ||
| 621 | - top: 6px; | ||
| 622 | - line-height: 30px; | ||
| 623 | - color: #00afff; | ||
| 624 | - font-weight: 600; | ||
| 625 | - font-size: 17px; | ||
| 626 | - white-space: nowrap; | ||
| 627 | - > img{ | ||
| 628 | - width: 30px; | ||
| 629 | - height: 30px; | ||
| 630 | - vertical-align: top; | ||
| 631 | - } | ||
| 632 | - .github{ | ||
| 633 | - display: inline-block; | ||
| 634 | - vertical-align: sub; | ||
| 635 | - margin-left: 15px; | ||
| 636 | - > img{ | ||
| 637 | - height: 22px; | ||
| 638 | - } | ||
| 639 | - } | ||
| 640 | -} | ||
| 641 | - | ||
| 642 | -.center-board-row { | ||
| 643 | - padding: 12px 12px 15px 12px; | ||
| 644 | - box-sizing: border-box; | ||
| 645 | - & > .el-form { | ||
| 646 | - // 69 = 12+15+42 | ||
| 647 | - height: calc(100vh - 69px); | ||
| 648 | - } | ||
| 649 | -} | ||
| 650 | -.drawing-board { | ||
| 651 | - height: 100%; | ||
| 652 | - position: relative; | ||
| 653 | - .components-body { | ||
| 654 | - padding: 0; | ||
| 655 | - margin: 0; | ||
| 656 | - font-size: 0; | ||
| 657 | - } | ||
| 658 | - .sortable-ghost { | ||
| 659 | - position: relative; | ||
| 660 | - display: block; | ||
| 661 | - overflow: hidden; | ||
| 662 | - &::before { | ||
| 663 | - content: " "; | ||
| 664 | - position: absolute; | ||
| 665 | - left: 0; | ||
| 666 | - right: 0; | ||
| 667 | - top: 0; | ||
| 668 | - height: 3px; | ||
| 669 | - background: rgb(89, 89, 223); | ||
| 670 | - z-index: 2; | ||
| 671 | - } | ||
| 672 | - } | ||
| 673 | - .components-item.sortable-ghost { | ||
| 674 | - width: 100%; | ||
| 675 | - height: 60px; | ||
| 676 | - background-color: $selectedColor; | ||
| 677 | - } | ||
| 678 | - .active-from-item { | ||
| 679 | - & > .el-form-item{ | ||
| 680 | - background: $selectedColor; | ||
| 681 | - border-radius: 6px; | ||
| 682 | - } | ||
| 683 | - & > .drawing-item-copy, & > .drawing-item-delete{ | ||
| 684 | - display: initial; | ||
| 685 | - } | ||
| 686 | - & > .component-name{ | ||
| 687 | - color: $lighterBlue; | ||
| 688 | - } | ||
| 689 | - } | ||
| 690 | - .el-form-item{ | ||
| 691 | - margin-bottom: 15px; | ||
| 692 | - } | ||
| 693 | -} | ||
| 694 | -.drawing-item{ | ||
| 695 | - position: relative; | ||
| 696 | - cursor: move; | ||
| 697 | - &.unfocus-bordered:not(.activeFromItem) > div:first-child { | ||
| 698 | - border: 1px dashed #ccc; | ||
| 699 | - } | ||
| 700 | - .el-form-item{ | ||
| 701 | - padding: 12px 10px; | ||
| 702 | - } | ||
| 703 | -} | ||
| 704 | -.drawing-row-item{ | ||
| 705 | - position: relative; | ||
| 706 | - cursor: move; | ||
| 707 | - box-sizing: border-box; | ||
| 708 | - border: 1px dashed #ccc; | ||
| 709 | - border-radius: 3px; | ||
| 710 | - padding: 0 2px; | ||
| 711 | - margin-bottom: 15px; | ||
| 712 | - .drawing-row-item { | ||
| 713 | - margin-bottom: 2px; | ||
| 714 | - } | ||
| 715 | - .el-col{ | ||
| 716 | - margin-top: 22px; | ||
| 717 | - } | ||
| 718 | - .el-form-item{ | ||
| 719 | - margin-bottom: 0; | ||
| 720 | - } | ||
| 721 | - .drag-wrapper{ | ||
| 722 | - min-height: 80px; | ||
| 723 | - } | ||
| 724 | - &.active-from-item{ | ||
| 725 | - border: 1px dashed $lighterBlue; | ||
| 726 | - } | ||
| 727 | - .component-name{ | ||
| 728 | - position: absolute; | ||
| 729 | - top: 0; | ||
| 730 | - left: 0; | ||
| 731 | - font-size: 12px; | ||
| 732 | - color: #bbb; | ||
| 733 | - display: inline-block; | ||
| 734 | - padding: 0 6px; | ||
| 735 | - } | ||
| 736 | -} | ||
| 737 | -.drawing-item, .drawing-row-item{ | ||
| 738 | - &:hover { | ||
| 739 | - & > .el-form-item{ | ||
| 740 | - background: $selectedColor; | ||
| 741 | - border-radius: 6px; | ||
| 742 | - } | ||
| 743 | - & > .drawing-item-copy, & > .drawing-item-delete{ | ||
| 744 | - display: initial; | ||
| 745 | - } | ||
| 746 | - } | ||
| 747 | - & > .drawing-item-copy, & > .drawing-item-delete{ | ||
| 748 | - display: none; | ||
| 749 | - position: absolute; | ||
| 750 | - top: -10px; | ||
| 751 | - width: 22px; | ||
| 752 | - height: 22px; | ||
| 753 | - line-height: 22px; | ||
| 754 | - text-align: center; | ||
| 755 | - border-radius: 50%; | ||
| 756 | - font-size: 12px; | ||
| 757 | - border: 1px solid; | ||
| 758 | - cursor: pointer; | ||
| 759 | - z-index: 1; | ||
| 760 | - } | ||
| 761 | - & > .drawing-item-copy{ | ||
| 762 | - right: 56px; | ||
| 763 | - border-color: $lighterBlue; | ||
| 764 | - color: $lighterBlue; | ||
| 765 | - background: #fff; | ||
| 766 | - &:hover{ | ||
| 767 | - background: $lighterBlue; | ||
| 768 | - color: #fff; | ||
| 769 | - } | ||
| 770 | - } | ||
| 771 | - & > .drawing-item-delete{ | ||
| 772 | - right: 24px; | ||
| 773 | - border-color: #F56C6C; | ||
| 774 | - color: #F56C6C; | ||
| 775 | - background: #fff; | ||
| 776 | - &:hover{ | ||
| 777 | - background: #F56C6C; | ||
| 778 | - color: #fff; | ||
| 779 | - } | ||
| 780 | - } | ||
| 781 | -} | ||
| 782 | - | ||
| 783 | -</style> | 1 | +<template> |
| 2 | + <div class="container"> | ||
| 3 | + <div class="left-board"> | ||
| 4 | + <div class="logo-wrapper"> | ||
| 5 | + <div class="logo"> | ||
| 6 | + <img :src="logo" alt="logo"> Form Generator | ||
| 7 | + </div> | ||
| 8 | + </div> | ||
| 9 | + <el-scrollbar class="left-scrollbar"> | ||
| 10 | + <div class="components-list"> | ||
| 11 | + <div class="components-title"> | ||
| 12 | + <svg-icon icon-class="component" />输入型组件 | ||
| 13 | + </div> | ||
| 14 | + <draggable | ||
| 15 | + class="components-draggable" | ||
| 16 | + :list="inputComponents" | ||
| 17 | + :group="{ name: 'componentsGroup', pull: 'clone', put: false }" | ||
| 18 | + :clone="cloneComponent" | ||
| 19 | + draggable=".components-item" | ||
| 20 | + :sort="false" | ||
| 21 | + @end="onEnd" | ||
| 22 | + > | ||
| 23 | + <div | ||
| 24 | + v-for="(element, index) in inputComponents" :key="index" class="components-item" | ||
| 25 | + @click="addComponent(element)" | ||
| 26 | + > | ||
| 27 | + <div class="components-body"> | ||
| 28 | + <svg-icon :icon-class="element.tagIcon" /> | ||
| 29 | + {{ element.label }} | ||
| 30 | + </div> | ||
| 31 | + </div> | ||
| 32 | + </draggable> | ||
| 33 | + <div class="components-title"> | ||
| 34 | + <svg-icon icon-class="component" />选择型组件 | ||
| 35 | + </div> | ||
| 36 | + <draggable | ||
| 37 | + class="components-draggable" | ||
| 38 | + :list="selectComponents" | ||
| 39 | + :group="{ name: 'componentsGroup', pull: 'clone', put: false }" | ||
| 40 | + :clone="cloneComponent" | ||
| 41 | + draggable=".components-item" | ||
| 42 | + :sort="false" | ||
| 43 | + @end="onEnd" | ||
| 44 | + > | ||
| 45 | + <div | ||
| 46 | + v-for="(element, index) in selectComponents" | ||
| 47 | + :key="index" | ||
| 48 | + class="components-item" | ||
| 49 | + @click="addComponent(element)" | ||
| 50 | + > | ||
| 51 | + <div class="components-body"> | ||
| 52 | + <svg-icon :icon-class="element.tagIcon" /> | ||
| 53 | + {{ element.label }} | ||
| 54 | + </div> | ||
| 55 | + </div> | ||
| 56 | + </draggable> | ||
| 57 | + <div class="components-title"> | ||
| 58 | + <svg-icon icon-class="component" /> 布局型组件 | ||
| 59 | + </div> | ||
| 60 | + <draggable | ||
| 61 | + class="components-draggable" :list="layoutComponents" | ||
| 62 | + :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent" | ||
| 63 | + draggable=".components-item" :sort="false" @end="onEnd" | ||
| 64 | + > | ||
| 65 | + <div | ||
| 66 | + v-for="(element, index) in layoutComponents" :key="index" class="components-item" | ||
| 67 | + @click="addComponent(element)" | ||
| 68 | + > | ||
| 69 | + <div class="components-body"> | ||
| 70 | + <svg-icon :icon-class="element.tagIcon" /> | ||
| 71 | + {{ element.label }} | ||
| 72 | + </div> | ||
| 73 | + </div> | ||
| 74 | + </draggable> | ||
| 75 | + </div> | ||
| 76 | + </el-scrollbar> | ||
| 77 | + </div> | ||
| 78 | + | ||
| 79 | + <div class="center-board"> | ||
| 80 | + <div class="action-bar"> | ||
| 81 | + <el-button icon="el-icon-download" type="text" @click="download"> | ||
| 82 | + 导出vue文件 | ||
| 83 | + </el-button> | ||
| 84 | + <el-button class="copy-btn-main" icon="el-icon-document-copy" type="text" @click="copy"> | ||
| 85 | + 复制代码 | ||
| 86 | + </el-button> | ||
| 87 | + <el-button class="delete-btn" icon="el-icon-delete" type="text" @click="empty"> | ||
| 88 | + 清空 | ||
| 89 | + </el-button> | ||
| 90 | + </div> | ||
| 91 | + <el-scrollbar class="center-scrollbar"> | ||
| 92 | + <el-row class="center-board-row" :gutter="formConf.gutter"> | ||
| 93 | + <el-form | ||
| 94 | + :size="formConf.size" | ||
| 95 | + :label-position="formConf.labelPosition" | ||
| 96 | + :disabled="formConf.disabled" | ||
| 97 | + :label-width="formConf.labelWidth + 'px'" | ||
| 98 | + > | ||
| 99 | + <draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup"> | ||
| 100 | + <draggable-item | ||
| 101 | + v-for="(element, index) in drawingList" | ||
| 102 | + :key="element.renderKey" | ||
| 103 | + :drawing-list="drawingList" | ||
| 104 | + :element="element" | ||
| 105 | + :index="index" | ||
| 106 | + :active-id="activeId" | ||
| 107 | + :form-conf="formConf" | ||
| 108 | + @activeItem="activeFormItem" | ||
| 109 | + @copyItem="drawingItemCopy" | ||
| 110 | + @deleteItem="drawingItemDelete" | ||
| 111 | + /> | ||
| 112 | + </draggable> | ||
| 113 | + <div v-show="!drawingList.length" class="empty-info"> | ||
| 114 | + 从左侧拖入或点选组件进行表单设计 | ||
| 115 | + </div> | ||
| 116 | + </el-form> | ||
| 117 | + </el-row> | ||
| 118 | + </el-scrollbar> | ||
| 119 | + </div> | ||
| 120 | + | ||
| 121 | + <right-panel | ||
| 122 | + :active-data="activeData" | ||
| 123 | + :form-conf="formConf" | ||
| 124 | + :show-field="!!drawingList.length" | ||
| 125 | + @tag-change="tagChange" | ||
| 126 | + /> | ||
| 127 | + | ||
| 128 | + <code-type-dialog | ||
| 129 | + :visible.sync="dialogVisible" | ||
| 130 | + title="选择生成类型" | ||
| 131 | + :show-file-name="showFileName" | ||
| 132 | + @confirm="generate" | ||
| 133 | + /> | ||
| 134 | + <input id="copyNode" type="hidden"> | ||
| 135 | + </div> | ||
| 136 | +</template> | ||
| 137 | + | ||
| 138 | +<script> | ||
| 139 | +import draggable from 'vuedraggable' | ||
| 140 | +import beautifier from 'js-beautify' | ||
| 141 | +import ClipboardJS from 'clipboard' | ||
| 142 | +import render from '@/utils/generator/render' | ||
| 143 | +import RightPanel from './RightPanel' | ||
| 144 | +import { inputComponents, selectComponents, layoutComponents, formConf } from '@/utils/generator/config' | ||
| 145 | +import { beautifierConf, titleCase } from '@/utils/index' | ||
| 146 | +import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html' | ||
| 147 | +import { makeUpJs } from '@/utils/generator/js' | ||
| 148 | +import { makeUpCss } from '@/utils/generator/css' | ||
| 149 | +import drawingDefault from '@/utils/generator/drawingDefault' | ||
| 150 | +import logo from '@/assets/logo/logo.png' | ||
| 151 | +import CodeTypeDialog from './CodeTypeDialog' | ||
| 152 | +import DraggableItem from './DraggableItem' | ||
| 153 | + | ||
| 154 | +let oldActiveId | ||
| 155 | +let tempActiveData | ||
| 156 | + | ||
| 157 | +export default { | ||
| 158 | + components: { | ||
| 159 | + draggable, | ||
| 160 | + render, | ||
| 161 | + RightPanel, | ||
| 162 | + CodeTypeDialog, | ||
| 163 | + DraggableItem | ||
| 164 | + }, | ||
| 165 | + data() { | ||
| 166 | + return { | ||
| 167 | + logo, | ||
| 168 | + idGlobal: 100, | ||
| 169 | + formConf, | ||
| 170 | + inputComponents, | ||
| 171 | + selectComponents, | ||
| 172 | + layoutComponents, | ||
| 173 | + labelWidth: 100, | ||
| 174 | + drawingList: drawingDefault, | ||
| 175 | + drawingData: {}, | ||
| 176 | + activeId: drawingDefault[0].formId, | ||
| 177 | + drawerVisible: false, | ||
| 178 | + formData: {}, | ||
| 179 | + dialogVisible: false, | ||
| 180 | + generateConf: null, | ||
| 181 | + showFileName: false, | ||
| 182 | + activeData: drawingDefault[0] | ||
| 183 | + } | ||
| 184 | + }, | ||
| 185 | + created() { | ||
| 186 | + // 防止 firefox 下 拖拽 会新打卡一个选项卡 | ||
| 187 | + document.body.ondrop = event => { | ||
| 188 | + event.preventDefault() | ||
| 189 | + event.stopPropagation() | ||
| 190 | + } | ||
| 191 | + }, | ||
| 192 | + watch: { | ||
| 193 | + // eslint-disable-next-line func-names | ||
| 194 | + 'activeData.label': function (val, oldVal) { | ||
| 195 | + if ( | ||
| 196 | + this.activeData.placeholder === undefined | ||
| 197 | + || !this.activeData.tag | ||
| 198 | + || oldActiveId !== this.activeId | ||
| 199 | + ) { | ||
| 200 | + return | ||
| 201 | + } | ||
| 202 | + this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val | ||
| 203 | + }, | ||
| 204 | + activeId: { | ||
| 205 | + handler(val) { | ||
| 206 | + oldActiveId = val | ||
| 207 | + }, | ||
| 208 | + immediate: true | ||
| 209 | + } | ||
| 210 | + }, | ||
| 211 | + mounted() { | ||
| 212 | + const clipboard = new ClipboardJS('#copyNode', { | ||
| 213 | + text: trigger => { | ||
| 214 | + const codeStr = this.generateCode() | ||
| 215 | + this.$notify({ | ||
| 216 | + title: '成功', | ||
| 217 | + message: '代码已复制到剪切板,可粘贴。', | ||
| 218 | + type: 'success' | ||
| 219 | + }) | ||
| 220 | + return codeStr | ||
| 221 | + } | ||
| 222 | + }) | ||
| 223 | + clipboard.on('error', e => { | ||
| 224 | + this.$message.error('代码复制失败') | ||
| 225 | + }) | ||
| 226 | + }, | ||
| 227 | + methods: { | ||
| 228 | + activeFormItem(element) { | ||
| 229 | + this.activeData = element | ||
| 230 | + this.activeId = element.formId | ||
| 231 | + }, | ||
| 232 | + onEnd(obj, a) { | ||
| 233 | + if (obj.from !== obj.to) { | ||
| 234 | + this.activeData = tempActiveData | ||
| 235 | + this.activeId = this.idGlobal | ||
| 236 | + } | ||
| 237 | + }, | ||
| 238 | + addComponent(item) { | ||
| 239 | + const clone = this.cloneComponent(item) | ||
| 240 | + this.drawingList.push(clone) | ||
| 241 | + this.activeFormItem(clone) | ||
| 242 | + }, | ||
| 243 | + cloneComponent(origin) { | ||
| 244 | + const clone = JSON.parse(JSON.stringify(origin)) | ||
| 245 | + clone.formId = ++this.idGlobal | ||
| 246 | + clone.span = formConf.span | ||
| 247 | + clone.renderKey = +new Date() // 改变renderKey后可以实现强制更新组件 | ||
| 248 | + if (!clone.layout) clone.layout = 'colFormItem' | ||
| 249 | + if (clone.layout === 'colFormItem') { | ||
| 250 | + clone.vModel = `field${this.idGlobal}` | ||
| 251 | + clone.placeholder !== undefined && (clone.placeholder += clone.label) | ||
| 252 | + tempActiveData = clone | ||
| 253 | + } else if (clone.layout === 'rowFormItem') { | ||
| 254 | + delete clone.label | ||
| 255 | + clone.componentName = `row${this.idGlobal}` | ||
| 256 | + clone.gutter = this.formConf.gutter | ||
| 257 | + tempActiveData = clone | ||
| 258 | + } | ||
| 259 | + return tempActiveData | ||
| 260 | + }, | ||
| 261 | + AssembleFormData() { | ||
| 262 | + this.formData = { | ||
| 263 | + fields: JSON.parse(JSON.stringify(this.drawingList)), | ||
| 264 | + ...this.formConf | ||
| 265 | + } | ||
| 266 | + }, | ||
| 267 | + generate(data) { | ||
| 268 | + const func = this[`exec${titleCase(this.operationType)}`] | ||
| 269 | + this.generateConf = data | ||
| 270 | + func && func(data) | ||
| 271 | + }, | ||
| 272 | + execRun(data) { | ||
| 273 | + this.AssembleFormData() | ||
| 274 | + this.drawerVisible = true | ||
| 275 | + }, | ||
| 276 | + execDownload(data) { | ||
| 277 | + const codeStr = this.generateCode() | ||
| 278 | + const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' }) | ||
| 279 | + this.$download.saveAs(blob, data.fileName) | ||
| 280 | + }, | ||
| 281 | + execCopy(data) { | ||
| 282 | + document.getElementById('copyNode').click() | ||
| 283 | + }, | ||
| 284 | + empty() { | ||
| 285 | + this.$confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then( | ||
| 286 | + () => { | ||
| 287 | + this.drawingList = [] | ||
| 288 | + } | ||
| 289 | + ) | ||
| 290 | + }, | ||
| 291 | + drawingItemCopy(item, parent) { | ||
| 292 | + let clone = JSON.parse(JSON.stringify(item)) | ||
| 293 | + clone = this.createIdAndKey(clone) | ||
| 294 | + parent.push(clone) | ||
| 295 | + this.activeFormItem(clone) | ||
| 296 | + }, | ||
| 297 | + createIdAndKey(item) { | ||
| 298 | + item.formId = ++this.idGlobal | ||
| 299 | + item.renderKey = +new Date() | ||
| 300 | + if (item.layout === 'colFormItem') { | ||
| 301 | + item.vModel = `field${this.idGlobal}` | ||
| 302 | + } else if (item.layout === 'rowFormItem') { | ||
| 303 | + item.componentName = `row${this.idGlobal}` | ||
| 304 | + } | ||
| 305 | + if (Array.isArray(item.children)) { | ||
| 306 | + item.children = item.children.map(childItem => this.createIdAndKey(childItem)) | ||
| 307 | + } | ||
| 308 | + return item | ||
| 309 | + }, | ||
| 310 | + drawingItemDelete(index, parent) { | ||
| 311 | + parent.splice(index, 1) | ||
| 312 | + this.$nextTick(() => { | ||
| 313 | + const len = this.drawingList.length | ||
| 314 | + if (len) { | ||
| 315 | + this.activeFormItem(this.drawingList[len - 1]) | ||
| 316 | + } | ||
| 317 | + }) | ||
| 318 | + }, | ||
| 319 | + generateCode() { | ||
| 320 | + const { type } = this.generateConf | ||
| 321 | + this.AssembleFormData() | ||
| 322 | + const script = vueScript(makeUpJs(this.formData, type)) | ||
| 323 | + const html = vueTemplate(makeUpHtml(this.formData, type)) | ||
| 324 | + const css = cssStyle(makeUpCss(this.formData)) | ||
| 325 | + return beautifier.html(html + script + css, beautifierConf.html) | ||
| 326 | + }, | ||
| 327 | + download() { | ||
| 328 | + this.dialogVisible = true | ||
| 329 | + this.showFileName = true | ||
| 330 | + this.operationType = 'download' | ||
| 331 | + }, | ||
| 332 | + run() { | ||
| 333 | + this.dialogVisible = true | ||
| 334 | + this.showFileName = false | ||
| 335 | + this.operationType = 'run' | ||
| 336 | + }, | ||
| 337 | + copy() { | ||
| 338 | + this.dialogVisible = true | ||
| 339 | + this.showFileName = false | ||
| 340 | + this.operationType = 'copy' | ||
| 341 | + }, | ||
| 342 | + tagChange(newTag) { | ||
| 343 | + newTag = this.cloneComponent(newTag) | ||
| 344 | + newTag.vModel = this.activeData.vModel | ||
| 345 | + newTag.formId = this.activeId | ||
| 346 | + newTag.span = this.activeData.span | ||
| 347 | + delete this.activeData.tag | ||
| 348 | + delete this.activeData.tagIcon | ||
| 349 | + delete this.activeData.document | ||
| 350 | + Object.keys(newTag).forEach(key => { | ||
| 351 | + if (this.activeData[key] !== undefined | ||
| 352 | + && typeof this.activeData[key] === typeof newTag[key]) { | ||
| 353 | + newTag[key] = this.activeData[key] | ||
| 354 | + } | ||
| 355 | + }) | ||
| 356 | + this.activeData = newTag | ||
| 357 | + this.updateDrawingList(newTag, this.drawingList) | ||
| 358 | + }, | ||
| 359 | + updateDrawingList(newTag, list) { | ||
| 360 | + const index = list.findIndex(item => item.formId === this.activeId) | ||
| 361 | + if (index > -1) { | ||
| 362 | + list.splice(index, 1, newTag) | ||
| 363 | + } else { | ||
| 364 | + list.forEach(item => { | ||
| 365 | + if (Array.isArray(item.children)) this.updateDrawingList(newTag, item.children) | ||
| 366 | + }) | ||
| 367 | + } | ||
| 368 | + } | ||
| 369 | + } | ||
| 370 | +} | ||
| 371 | +</script> | ||
| 372 | + | ||
| 373 | +<style lang='scss'> | ||
| 374 | +body, html{ | ||
| 375 | + margin: 0; | ||
| 376 | + padding: 0; | ||
| 377 | + background: #fff; | ||
| 378 | + --moz-osx-font-smoothing: grayscale; | ||
| 379 | + --webkit-font-smoothing: antialiased; | ||
| 380 | + text-rendering: optimizeLegibility; | ||
| 381 | + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; | ||
| 382 | +} | ||
| 383 | + | ||
| 384 | +input, textarea{ | ||
| 385 | + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; | ||
| 386 | +} | ||
| 387 | + | ||
| 388 | +.editor-tabs{ | ||
| 389 | + background: #121315; | ||
| 390 | + .el-tabs__header{ | ||
| 391 | + margin: 0; | ||
| 392 | + border-bottom-color: #121315; | ||
| 393 | + .el-tabs__nav{ | ||
| 394 | + border-color: #121315; | ||
| 395 | + } | ||
| 396 | + } | ||
| 397 | + .el-tabs__item{ | ||
| 398 | + height: 32px; | ||
| 399 | + line-height: 32px; | ||
| 400 | + color: #888a8e; | ||
| 401 | + border-left: 1px solid #121315 !important; | ||
| 402 | + background: #363636; | ||
| 403 | + margin-right: 5px; | ||
| 404 | + user-select: none; | ||
| 405 | + } | ||
| 406 | + .el-tabs__item.is-active{ | ||
| 407 | + background: #1e1e1e; | ||
| 408 | + border-bottom-color: #1e1e1e!important; | ||
| 409 | + color: #fff; | ||
| 410 | + } | ||
| 411 | + .el-icon-edit{ | ||
| 412 | + color: #f1fa8c; | ||
| 413 | + } | ||
| 414 | + .el-icon-document{ | ||
| 415 | + color: #a95812; | ||
| 416 | + } | ||
| 417 | +} | ||
| 418 | + | ||
| 419 | +// home | ||
| 420 | +.right-scrollbar { | ||
| 421 | + .el-scrollbar__view { | ||
| 422 | + padding: 12px 18px 15px 15px; | ||
| 423 | + } | ||
| 424 | +} | ||
| 425 | +.left-scrollbar .el-scrollbar__wrap { | ||
| 426 | + box-sizing: border-box; | ||
| 427 | + overflow-x: hidden !important; | ||
| 428 | + margin-bottom: 0 !important; | ||
| 429 | +} | ||
| 430 | +.center-tabs{ | ||
| 431 | + .el-tabs__header{ | ||
| 432 | + margin-bottom: 0!important; | ||
| 433 | + } | ||
| 434 | + .el-tabs__item{ | ||
| 435 | + width: 50%; | ||
| 436 | + text-align: center; | ||
| 437 | + } | ||
| 438 | + .el-tabs__nav{ | ||
| 439 | + width: 100%; | ||
| 440 | + } | ||
| 441 | +} | ||
| 442 | +.reg-item{ | ||
| 443 | + padding: 12px 6px; | ||
| 444 | + background: #f8f8f8; | ||
| 445 | + position: relative; | ||
| 446 | + border-radius: 4px; | ||
| 447 | + .close-btn{ | ||
| 448 | + position: absolute; | ||
| 449 | + right: -6px; | ||
| 450 | + top: -6px; | ||
| 451 | + display: block; | ||
| 452 | + width: 16px; | ||
| 453 | + height: 16px; | ||
| 454 | + line-height: 16px; | ||
| 455 | + background: rgba(0, 0, 0, 0.2); | ||
| 456 | + border-radius: 50%; | ||
| 457 | + color: #fff; | ||
| 458 | + text-align: center; | ||
| 459 | + z-index: 1; | ||
| 460 | + cursor: pointer; | ||
| 461 | + font-size: 12px; | ||
| 462 | + &:hover{ | ||
| 463 | + background: rgba(210, 23, 23, 0.5) | ||
| 464 | + } | ||
| 465 | + } | ||
| 466 | + & + .reg-item{ | ||
| 467 | + margin-top: 18px; | ||
| 468 | + } | ||
| 469 | +} | ||
| 470 | +.action-bar{ | ||
| 471 | + & .el-button+.el-button { | ||
| 472 | + margin-left: 15px; | ||
| 473 | + } | ||
| 474 | + & i { | ||
| 475 | + font-size: 20px; | ||
| 476 | + vertical-align: middle; | ||
| 477 | + position: relative; | ||
| 478 | + top: -1px; | ||
| 479 | + } | ||
| 480 | +} | ||
| 481 | + | ||
| 482 | +.custom-tree-node{ | ||
| 483 | + width: 100%; | ||
| 484 | + font-size: 14px; | ||
| 485 | + .node-operation{ | ||
| 486 | + float: right; | ||
| 487 | + } | ||
| 488 | + i[class*="el-icon"] + i[class*="el-icon"]{ | ||
| 489 | + margin-left: 6px; | ||
| 490 | + } | ||
| 491 | + .el-icon-plus{ | ||
| 492 | + color: #409EFF; | ||
| 493 | + } | ||
| 494 | + .el-icon-delete{ | ||
| 495 | + color: #157a0c; | ||
| 496 | + } | ||
| 497 | +} | ||
| 498 | + | ||
| 499 | +.left-scrollbar .el-scrollbar__view{ | ||
| 500 | + overflow-x: hidden; | ||
| 501 | +} | ||
| 502 | + | ||
| 503 | +.el-rate{ | ||
| 504 | + display: inline-block; | ||
| 505 | + vertical-align: text-top; | ||
| 506 | +} | ||
| 507 | +.el-upload__tip{ | ||
| 508 | + line-height: 1.2; | ||
| 509 | +} | ||
| 510 | + | ||
| 511 | +$selectedColor: #f6f7ff; | ||
| 512 | +$lighterBlue: #409EFF; | ||
| 513 | + | ||
| 514 | +.container { | ||
| 515 | + position: relative; | ||
| 516 | + width: 100%; | ||
| 517 | + height: 100%; | ||
| 518 | +} | ||
| 519 | + | ||
| 520 | +.components-list { | ||
| 521 | + padding: 8px; | ||
| 522 | + box-sizing: border-box; | ||
| 523 | + height: 100%; | ||
| 524 | + .components-item { | ||
| 525 | + display: inline-block; | ||
| 526 | + width: 48%; | ||
| 527 | + margin: 1%; | ||
| 528 | + transition: transform 0ms !important; | ||
| 529 | + } | ||
| 530 | +} | ||
| 531 | +.components-draggable{ | ||
| 532 | + padding-bottom: 20px; | ||
| 533 | +} | ||
| 534 | +.components-title{ | ||
| 535 | + font-size: 14px; | ||
| 536 | + color: #222; | ||
| 537 | + margin: 6px 2px; | ||
| 538 | + .svg-icon{ | ||
| 539 | + color: #666; | ||
| 540 | + font-size: 18px; | ||
| 541 | + } | ||
| 542 | +} | ||
| 543 | + | ||
| 544 | +.components-body { | ||
| 545 | + padding: 8px 10px; | ||
| 546 | + background: $selectedColor; | ||
| 547 | + font-size: 12px; | ||
| 548 | + cursor: move; | ||
| 549 | + border: 1px dashed $selectedColor; | ||
| 550 | + border-radius: 3px; | ||
| 551 | + .svg-icon{ | ||
| 552 | + color: #777; | ||
| 553 | + font-size: 15px; | ||
| 554 | + } | ||
| 555 | + &:hover { | ||
| 556 | + border: 1px dashed #787be8; | ||
| 557 | + color: #787be8; | ||
| 558 | + .svg-icon { | ||
| 559 | + color: #787be8; | ||
| 560 | + } | ||
| 561 | + } | ||
| 562 | +} | ||
| 563 | + | ||
| 564 | +.left-board { | ||
| 565 | + width: 260px; | ||
| 566 | + position: absolute; | ||
| 567 | + left: 0; | ||
| 568 | + top: 0; | ||
| 569 | + height: 100vh; | ||
| 570 | +} | ||
| 571 | +.left-scrollbar{ | ||
| 572 | + height: calc(100vh - 42px); | ||
| 573 | + overflow: hidden; | ||
| 574 | +} | ||
| 575 | +.center-scrollbar { | ||
| 576 | + height: calc(100vh - 42px); | ||
| 577 | + overflow: hidden; | ||
| 578 | + border-left: 1px solid #f1e8e8; | ||
| 579 | + border-right: 1px solid #f1e8e8; | ||
| 580 | + box-sizing: border-box; | ||
| 581 | +} | ||
| 582 | +.center-board { | ||
| 583 | + height: 100vh; | ||
| 584 | + width: auto; | ||
| 585 | + margin: 0 350px 0 260px; | ||
| 586 | + box-sizing: border-box; | ||
| 587 | +} | ||
| 588 | +.empty-info{ | ||
| 589 | + position: absolute; | ||
| 590 | + top: 46%; | ||
| 591 | + left: 0; | ||
| 592 | + right: 0; | ||
| 593 | + text-align: center; | ||
| 594 | + font-size: 18px; | ||
| 595 | + color: #ccb1ea; | ||
| 596 | + letter-spacing: 4px; | ||
| 597 | +} | ||
| 598 | +.action-bar{ | ||
| 599 | + position: relative; | ||
| 600 | + height: 42px; | ||
| 601 | + text-align: right; | ||
| 602 | + padding: 0 15px; | ||
| 603 | + box-sizing: border-box;; | ||
| 604 | + border: 1px solid #f1e8e8; | ||
| 605 | + border-top: none; | ||
| 606 | + border-left: none; | ||
| 607 | + .delete-btn{ | ||
| 608 | + color: #F56C6C; | ||
| 609 | + } | ||
| 610 | +} | ||
| 611 | +.logo-wrapper{ | ||
| 612 | + position: relative; | ||
| 613 | + height: 42px; | ||
| 614 | + background: #fff; | ||
| 615 | + border-bottom: 1px solid #f1e8e8; | ||
| 616 | + box-sizing: border-box; | ||
| 617 | +} | ||
| 618 | +.logo{ | ||
| 619 | + position: absolute; | ||
| 620 | + left: 12px; | ||
| 621 | + top: 6px; | ||
| 622 | + line-height: 30px; | ||
| 623 | + color: #00afff; | ||
| 624 | + font-weight: 600; | ||
| 625 | + font-size: 17px; | ||
| 626 | + white-space: nowrap; | ||
| 627 | + > img{ | ||
| 628 | + width: 30px; | ||
| 629 | + height: 30px; | ||
| 630 | + vertical-align: top; | ||
| 631 | + } | ||
| 632 | + .github{ | ||
| 633 | + display: inline-block; | ||
| 634 | + vertical-align: sub; | ||
| 635 | + margin-left: 15px; | ||
| 636 | + > img{ | ||
| 637 | + height: 22px; | ||
| 638 | + } | ||
| 639 | + } | ||
| 640 | +} | ||
| 641 | + | ||
| 642 | +.center-board-row { | ||
| 643 | + padding: 12px 12px 15px 12px; | ||
| 644 | + box-sizing: border-box; | ||
| 645 | + & > .el-form { | ||
| 646 | + // 69 = 12+15+42 | ||
| 647 | + height: calc(100vh - 69px); | ||
| 648 | + } | ||
| 649 | +} | ||
| 650 | +.drawing-board { | ||
| 651 | + height: 100%; | ||
| 652 | + position: relative; | ||
| 653 | + .components-body { | ||
| 654 | + padding: 0; | ||
| 655 | + margin: 0; | ||
| 656 | + font-size: 0; | ||
| 657 | + } | ||
| 658 | + .sortable-ghost { | ||
| 659 | + position: relative; | ||
| 660 | + display: block; | ||
| 661 | + overflow: hidden; | ||
| 662 | + &::before { | ||
| 663 | + content: " "; | ||
| 664 | + position: absolute; | ||
| 665 | + left: 0; | ||
| 666 | + right: 0; | ||
| 667 | + top: 0; | ||
| 668 | + height: 3px; | ||
| 669 | + background: rgb(89, 89, 223); | ||
| 670 | + z-index: 2; | ||
| 671 | + } | ||
| 672 | + } | ||
| 673 | + .components-item.sortable-ghost { | ||
| 674 | + width: 100%; | ||
| 675 | + height: 60px; | ||
| 676 | + background-color: $selectedColor; | ||
| 677 | + } | ||
| 678 | + .active-from-item { | ||
| 679 | + & > .el-form-item{ | ||
| 680 | + background: $selectedColor; | ||
| 681 | + border-radius: 6px; | ||
| 682 | + } | ||
| 683 | + & > .drawing-item-copy, & > .drawing-item-delete{ | ||
| 684 | + display: initial; | ||
| 685 | + } | ||
| 686 | + & > .component-name{ | ||
| 687 | + color: $lighterBlue; | ||
| 688 | + } | ||
| 689 | + } | ||
| 690 | + .el-form-item{ | ||
| 691 | + margin-bottom: 15px; | ||
| 692 | + } | ||
| 693 | +} | ||
| 694 | +.drawing-item{ | ||
| 695 | + position: relative; | ||
| 696 | + cursor: move; | ||
| 697 | + &.unfocus-bordered:not(.activeFromItem) > div:first-child { | ||
| 698 | + border: 1px dashed #ccc; | ||
| 699 | + } | ||
| 700 | + .el-form-item{ | ||
| 701 | + padding: 12px 10px; | ||
| 702 | + } | ||
| 703 | +} | ||
| 704 | +.drawing-row-item{ | ||
| 705 | + position: relative; | ||
| 706 | + cursor: move; | ||
| 707 | + box-sizing: border-box; | ||
| 708 | + border: 1px dashed #ccc; | ||
| 709 | + border-radius: 3px; | ||
| 710 | + padding: 0 2px; | ||
| 711 | + margin-bottom: 15px; | ||
| 712 | + .drawing-row-item { | ||
| 713 | + margin-bottom: 2px; | ||
| 714 | + } | ||
| 715 | + .el-col{ | ||
| 716 | + margin-top: 22px; | ||
| 717 | + } | ||
| 718 | + .el-form-item{ | ||
| 719 | + margin-bottom: 0; | ||
| 720 | + } | ||
| 721 | + .drag-wrapper{ | ||
| 722 | + min-height: 80px; | ||
| 723 | + } | ||
| 724 | + &.active-from-item{ | ||
| 725 | + border: 1px dashed $lighterBlue; | ||
| 726 | + } | ||
| 727 | + .component-name{ | ||
| 728 | + position: absolute; | ||
| 729 | + top: 0; | ||
| 730 | + left: 0; | ||
| 731 | + font-size: 12px; | ||
| 732 | + color: #bbb; | ||
| 733 | + display: inline-block; | ||
| 734 | + padding: 0 6px; | ||
| 735 | + } | ||
| 736 | +} | ||
| 737 | +.drawing-item, .drawing-row-item{ | ||
| 738 | + &:hover { | ||
| 739 | + & > .el-form-item{ | ||
| 740 | + background: $selectedColor; | ||
| 741 | + border-radius: 6px; | ||
| 742 | + } | ||
| 743 | + & > .drawing-item-copy, & > .drawing-item-delete{ | ||
| 744 | + display: initial; | ||
| 745 | + } | ||
| 746 | + } | ||
| 747 | + & > .drawing-item-copy, & > .drawing-item-delete{ | ||
| 748 | + display: none; | ||
| 749 | + position: absolute; | ||
| 750 | + top: -10px; | ||
| 751 | + width: 22px; | ||
| 752 | + height: 22px; | ||
| 753 | + line-height: 22px; | ||
| 754 | + text-align: center; | ||
| 755 | + border-radius: 50%; | ||
| 756 | + font-size: 12px; | ||
| 757 | + border: 1px solid; | ||
| 758 | + cursor: pointer; | ||
| 759 | + z-index: 1; | ||
| 760 | + } | ||
| 761 | + & > .drawing-item-copy{ | ||
| 762 | + right: 56px; | ||
| 763 | + border-color: $lighterBlue; | ||
| 764 | + color: $lighterBlue; | ||
| 765 | + background: #fff; | ||
| 766 | + &:hover{ | ||
| 767 | + background: $lighterBlue; | ||
| 768 | + color: #fff; | ||
| 769 | + } | ||
| 770 | + } | ||
| 771 | + & > .drawing-item-delete{ | ||
| 772 | + right: 24px; | ||
| 773 | + border-color: #F56C6C; | ||
| 774 | + color: #F56C6C; | ||
| 775 | + background: #fff; | ||
| 776 | + &:hover{ | ||
| 777 | + background: #F56C6C; | ||
| 778 | + color: #fff; | ||
| 779 | + } | ||
| 780 | + } | ||
| 781 | +} | ||
| 782 | + | ||
| 783 | +</style> |
-
请 注册 或 登录 后发表评论