From 3e7de4fa675482d081b7aa4e76dd196514df8245 Mon Sep 17 00:00:00 2001
From: wxy <14293288+zysysys@user.noreply.gitee.com>
Date: Fri, 24 May 2024 14:01:27 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/compiler.xml | 33 +
bin/clean.bat | 12 +
docker/copy.sh | 41 +
.../core/exception/CheckedException.java | 31 +
.../com/jing/common/core/text/Convert.java | 1012 +++++++++++++++++
.../main/resources/vm/java/controller.java.vm | 116 ++
.../java/com/jing/job/util/CronUtils.java | 63 +
jing-ui/src/assets/icons/svg/checkbox.svg | 1 +
jing-ui/src/assets/icons/svg/client.svg | 1 +
jing-ui/src/assets/icons/svg/clipboard.svg | 1 +
jing-ui/src/assets/icons/svg/code.svg | 1 +
jing-ui/src/assets/icons/svg/color.svg | 1 +
jing-ui/src/directive/module/clipboard.js | 54 +
.../src/views/tool/build/CodeTypeDialog.vue | 106 ++
14 files changed, 1473 insertions(+)
create mode 100644 .idea/compiler.xml
create mode 100644 bin/clean.bat
create mode 100644 docker/copy.sh
create mode 100644 jing-common/jing-common-core/src/main/java/com/jing/common/core/exception/CheckedException.java
create mode 100644 jing-common/jing-common-core/src/main/java/com/jing/common/core/text/Convert.java
create mode 100644 jing-modules/jing-gen/src/main/resources/vm/java/controller.java.vm
create mode 100644 jing-modules/jing-job/src/main/java/com/jing/job/util/CronUtils.java
create mode 100644 jing-ui/src/assets/icons/svg/checkbox.svg
create mode 100644 jing-ui/src/assets/icons/svg/client.svg
create mode 100644 jing-ui/src/assets/icons/svg/clipboard.svg
create mode 100644 jing-ui/src/assets/icons/svg/code.svg
create mode 100644 jing-ui/src/assets/icons/svg/color.svg
create mode 100644 jing-ui/src/directive/module/clipboard.js
create mode 100644 jing-ui/src/views/tool/build/CodeTypeDialog.vue
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..95f8bf0
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bin/clean.bat b/bin/clean.bat
new file mode 100644
index 0000000..24c0974
--- /dev/null
+++ b/bin/clean.bat
@@ -0,0 +1,12 @@
+@echo off
+echo.
+echo [信息] 清理工程target生成路径。
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+call mvn clean
+
+pause
\ No newline at end of file
diff --git a/docker/copy.sh b/docker/copy.sh
new file mode 100644
index 0000000..c9ec760
--- /dev/null
+++ b/docker/copy.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# 澶嶅埗椤圭洰鐨勬枃浠跺埌瀵瑰簲docker璺緞锛屼究浜庝竴閿敓鎴愰暅鍍忋
+usage() {
+ echo "Usage: sh copy.sh"
+ exit 1
+}
+
+
+# copy sql
+echo "begin copy sql "
+cp ../sql/ry_20231130.sql ./mysql/db
+cp ../sql/ry_config_20231204.sql ./mysql/db
+
+# copy html
+echo "begin copy html "
+cp -r ../jing-ui/dist/** ./nginx/html/dist
+
+
+# copy jar
+echo "begin copy jing-gateway "
+cp ../jing-gateway/target/jing-gateway.jar ./ruoyi/gateway/jar
+
+echo "begin copy jing-auth "
+cp ../jing-auth/target/jing-auth.jar ./ruoyi/auth/jar
+
+echo "begin copy jing-visual "
+cp ../jing-visual/jing-monitor/target/jing-visual-monitor.jar ./ruoyi/visual/monitor/jar
+
+echo "begin copy jing-modules-system "
+cp ../jing-modules/jing-system/target/jing-modules-system.jar ./ruoyi/modules/system/jar
+
+echo "begin copy jing-modules-file "
+cp ../jing-modules/jing-file/target/jing-modules-file.jar ./ruoyi/modules/file/jar
+
+echo "begin copy jing-modules-job "
+cp ../jing-modules/jing-job/target/jing-modules-job.jar ./ruoyi/modules/job/jar
+
+echo "begin copy jing-modules-gen "
+cp ../jing-modules/jing-gen/target/jing-modules-gen.jar ./ruoyi/modules/gen/jar
+
diff --git a/jing-common/jing-common-core/src/main/java/com/jing/common/core/exception/CheckedException.java b/jing-common/jing-common-core/src/main/java/com/jing/common/core/exception/CheckedException.java
new file mode 100644
index 0000000..2f2201f
--- /dev/null
+++ b/jing-common/jing-common-core/src/main/java/com/jing/common/core/exception/CheckedException.java
@@ -0,0 +1,31 @@
+package com.jing.common.core.exception;
+
+/**
+ * 妫鏌ュ紓甯
+ *
+ * @author ruoyi
+ */
+public class CheckedException extends RuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ public CheckedException(String message)
+ {
+ super(message);
+ }
+
+ public CheckedException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ public CheckedException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public CheckedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
+ {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/jing-common/jing-common-core/src/main/java/com/jing/common/core/text/Convert.java b/jing-common/jing-common-core/src/main/java/com/jing/common/core/text/Convert.java
new file mode 100644
index 0000000..bf3af00
--- /dev/null
+++ b/jing-common/jing-common-core/src/main/java/com/jing/common/core/text/Convert.java
@@ -0,0 +1,1012 @@
+package com.jing.common.core.text;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.text.NumberFormat;
+import java.util.Set;
+import com.jing.common.core.utils.StringUtils;
+
+/**
+ * 绫诲瀷杞崲鍣
+ *
+ * @author ruoyi
+ */
+public class Convert
+{
+ /**
+ * 杞崲涓哄瓧绗︿覆
+ * 濡傛灉缁欏畾鐨勫间负null锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static String toStr(Object value, String defaultValue)
+ {
+ if (null == value)
+ {
+ return defaultValue;
+ }
+ if (value instanceof String)
+ {
+ return (String) value;
+ }
+ return value.toString();
+ }
+
+ /**
+ * 杞崲涓哄瓧绗︿覆
+ * 濡傛灉缁欏畾鐨勫间负null
锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static String toStr(Object value)
+ {
+ return toStr(value, null);
+ }
+
+ /**
+ * 杞崲涓哄瓧绗
+ * 濡傛灉缁欏畾鐨勫间负null锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static Character toChar(Object value, Character defaultValue)
+ {
+ if (null == value)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Character)
+ {
+ return (Character) value;
+ }
+
+ final String valueStr = toStr(value, null);
+ return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);
+ }
+
+ /**
+ * 杞崲涓哄瓧绗
+ * 濡傛灉缁欏畾鐨勫间负null
锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Character toChar(Object value)
+ {
+ return toChar(value, null);
+ }
+
+ /**
+ * 杞崲涓篵yte
+ * 濡傛灉缁欏畾鐨勫间负null
锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static Byte toByte(Object value, Byte defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Byte)
+ {
+ return (Byte) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).byteValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Byte.parseByte(valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓篵yte
+ * 濡傛灉缁欏畾鐨勫间负null
锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Byte toByte(Object value)
+ {
+ return toByte(value, null);
+ }
+
+ /**
+ * 杞崲涓篠hort
+ * 濡傛灉缁欏畾鐨勫间负null
锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static Short toShort(Object value, Short defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Short)
+ {
+ return (Short) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).shortValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Short.parseShort(valueStr.trim());
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓篠hort
+ * 濡傛灉缁欏畾鐨勫间负null
锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Short toShort(Object value)
+ {
+ return toShort(value, null);
+ }
+
+ /**
+ * 杞崲涓篘umber
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static Number toNumber(Object value, Number defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Number)
+ {
+ return (Number) value;
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return NumberFormat.getInstance().parse(valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓篘umber
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Number toNumber(Object value)
+ {
+ return toNumber(value, null);
+ }
+
+ /**
+ * 杞崲涓篿nt
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static Integer toInt(Object value, Integer defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Integer)
+ {
+ return (Integer) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).intValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Integer.parseInt(valueStr.trim());
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓篿nt
+ * 濡傛灉缁欏畾鐨勫间负null
锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Integer toInt(Object value)
+ {
+ return toInt(value, null);
+ }
+
+ /**
+ * 杞崲涓篒nteger鏁扮粍
+ *
+ * @param str 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Integer[] toIntArray(String str)
+ {
+ return toIntArray(",", str);
+ }
+
+ /**
+ * 杞崲涓篖ong鏁扮粍
+ *
+ * @param str 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Long[] toLongArray(String str)
+ {
+ return toLongArray(",", str);
+ }
+
+ /**
+ * 杞崲涓篒nteger鏁扮粍
+ *
+ * @param split 鍒嗛殧绗
+ * @param str 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Integer[] toIntArray(String split, String str)
+ {
+ if (StringUtils.isEmpty(str))
+ {
+ return new Integer[] {};
+ }
+ String[] arr = str.split(split);
+ final Integer[] ints = new Integer[arr.length];
+ for (int i = 0; i < arr.length; i++)
+ {
+ final Integer v = toInt(arr[i], 0);
+ ints[i] = v;
+ }
+ return ints;
+ }
+
+ /**
+ * 杞崲涓篖ong鏁扮粍
+ *
+ * @param split 鍒嗛殧绗
+ * @param str 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Long[] toLongArray(String split, String str)
+ {
+ if (StringUtils.isEmpty(str))
+ {
+ return new Long[] {};
+ }
+ String[] arr = str.split(split);
+ final Long[] longs = new Long[arr.length];
+ for (int i = 0; i < arr.length; i++)
+ {
+ final Long v = toLong(arr[i], null);
+ longs[i] = v;
+ }
+ return longs;
+ }
+
+ /**
+ * 杞崲涓篠tring鏁扮粍
+ *
+ * @param str 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static String[] toStrArray(String str)
+ {
+ return toStrArray(",", str);
+ }
+
+ /**
+ * 杞崲涓篠tring鏁扮粍
+ *
+ * @param split 鍒嗛殧绗
+ * @param str 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static String[] toStrArray(String split, String str)
+ {
+ return str.split(split);
+ }
+
+ /**
+ * 杞崲涓簂ong
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static Long toLong(Object value, Long defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Long)
+ {
+ return (Long) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).longValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ // 鏀寔绉戝璁℃暟娉
+ return new BigDecimal(valueStr.trim()).longValue();
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓簂ong
+ * 濡傛灉缁欏畾鐨勫间负null
锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Long toLong(Object value)
+ {
+ return toLong(value, null);
+ }
+
+ /**
+ * 杞崲涓篸ouble
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static Double toDouble(Object value, Double defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Double)
+ {
+ return (Double) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).doubleValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ // 鏀寔绉戝璁℃暟娉
+ return new BigDecimal(valueStr.trim()).doubleValue();
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓篸ouble
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Double toDouble(Object value)
+ {
+ return toDouble(value, null);
+ }
+
+ /**
+ * 杞崲涓篎loat
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static Float toFloat(Object value, Float defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Float)
+ {
+ return (Float) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).floatValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Float.parseFloat(valueStr.trim());
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓篎loat
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Float toFloat(Object value)
+ {
+ return toFloat(value, null);
+ }
+
+ /**
+ * 杞崲涓篵oolean
+ * String鏀寔鐨勫间负锛歵rue銆乫alse銆亂es銆乷k銆乶o锛1,0 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static Boolean toBool(Object value, Boolean defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Boolean)
+ {
+ return (Boolean) value;
+ }
+ String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ valueStr = valueStr.trim().toLowerCase();
+ switch (valueStr)
+ {
+ case "true":
+ case "yes":
+ case "ok":
+ case "1":
+ return true;
+ case "false":
+ case "no":
+ case "0":
+ return false;
+ default:
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓篵oolean
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static Boolean toBool(Object value)
+ {
+ return toBool(value, null);
+ }
+
+ /**
+ * 杞崲涓篍num瀵硅薄
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ *
+ * @param clazz Enum鐨凜lass
+ * @param value 鍊
+ * @param defaultValue 榛樿鍊
+ * @return Enum
+ */
+ public static > E toEnum(Class clazz, Object value, E defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (clazz.isAssignableFrom(value.getClass()))
+ {
+ @SuppressWarnings("unchecked")
+ E myE = (E) value;
+ return myE;
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Enum.valueOf(clazz, valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓篍num瀵硅薄
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ *
+ * @param clazz Enum鐨凜lass
+ * @param value 鍊
+ * @return Enum
+ */
+ public static > E toEnum(Class clazz, Object value)
+ {
+ return toEnum(clazz, value, null);
+ }
+
+ /**
+ * 杞崲涓築igInteger
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static BigInteger toBigInteger(Object value, BigInteger defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof BigInteger)
+ {
+ return (BigInteger) value;
+ }
+ if (value instanceof Long)
+ {
+ return BigInteger.valueOf((Long) value);
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return new BigInteger(valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓築igInteger
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊null
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static BigInteger toBigInteger(Object value)
+ {
+ return toBigInteger(value, null);
+ }
+
+ /**
+ * 杞崲涓築igDecimal
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊
+ * @return 缁撴灉
+ */
+ public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof BigDecimal)
+ {
+ return (BigDecimal) value;
+ }
+ if (value instanceof Long)
+ {
+ return new BigDecimal((Long) value);
+ }
+ if (value instanceof Double)
+ {
+ return BigDecimal.valueOf((Double) value);
+ }
+ if (value instanceof Integer)
+ {
+ return new BigDecimal((Integer) value);
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return new BigDecimal(valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 杞崲涓築igDecimal
+ * 濡傛灉缁欏畾鐨勫间负绌猴紝鎴栬呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊
+ * 杞崲澶辫触涓嶄細鎶ラ敊
+ *
+ * @param value 琚浆鎹㈢殑鍊
+ * @return 缁撴灉
+ */
+ public static BigDecimal toBigDecimal(Object value)
+ {
+ return toBigDecimal(value, null);
+ }
+
+ /**
+ * 灏嗗璞¤浆涓哄瓧绗︿覆
+ * 1銆丅yte鏁扮粍鍜孊yteBuffer浼氳杞崲涓哄搴斿瓧绗︿覆鐨勬暟缁 2銆佸璞℃暟缁勪細璋冪敤Arrays.toString鏂规硶
+ *
+ * @param obj 瀵硅薄
+ * @return 瀛楃涓
+ */
+ public static String utf8Str(Object obj)
+ {
+ return str(obj, CharsetKit.CHARSET_UTF_8);
+ }
+
+ /**
+ * 灏嗗璞¤浆涓哄瓧绗︿覆
+ * 1銆丅yte鏁扮粍鍜孊yteBuffer浼氳杞崲涓哄搴斿瓧绗︿覆鐨勬暟缁 2銆佸璞℃暟缁勪細璋冪敤Arrays.toString鏂规硶
+ *
+ * @param obj 瀵硅薄
+ * @param charsetName 瀛楃闆
+ * @return 瀛楃涓
+ */
+ public static String str(Object obj, String charsetName)
+ {
+ return str(obj, Charset.forName(charsetName));
+ }
+
+ /**
+ * 灏嗗璞¤浆涓哄瓧绗︿覆
+ * 1銆丅yte鏁扮粍鍜孊yteBuffer浼氳杞崲涓哄搴斿瓧绗︿覆鐨勬暟缁 2銆佸璞℃暟缁勪細璋冪敤Arrays.toString鏂规硶
+ *
+ * @param obj 瀵硅薄
+ * @param charset 瀛楃闆
+ * @return 瀛楃涓
+ */
+ public static String str(Object obj, Charset charset)
+ {
+ if (null == obj)
+ {
+ return null;
+ }
+
+ if (obj instanceof String)
+ {
+ return (String) obj;
+ }
+ else if (obj instanceof byte[] || obj instanceof Byte[])
+ {
+ if (obj instanceof byte[])
+ {
+ return str((byte[]) obj, charset);
+ }
+ else
+ {
+ Byte[] bytes = (Byte[]) obj;
+ int length = bytes.length;
+ byte[] dest = new byte[length];
+ for (int i = 0; i < length; i++)
+ {
+ dest[i] = bytes[i];
+ }
+ return str(dest, charset);
+ }
+ }
+ else if (obj instanceof ByteBuffer)
+ {
+ return str((ByteBuffer) obj, charset);
+ }
+ return obj.toString();
+ }
+
+ /**
+ * 灏哹yte鏁扮粍杞负瀛楃涓
+ *
+ * @param bytes byte鏁扮粍
+ * @param charset 瀛楃闆
+ * @return 瀛楃涓
+ */
+ public static String str(byte[] bytes, String charset)
+ {
+ return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));
+ }
+
+ /**
+ * 瑙g爜瀛楄妭鐮
+ *
+ * @param data 瀛楃涓
+ * @param charset 瀛楃闆嗭紝濡傛灉姝ゅ瓧娈典负绌猴紝鍒欒В鐮佺殑缁撴灉鍙栧喅浜庡钩鍙
+ * @return 瑙g爜鍚庣殑瀛楃涓
+ */
+ public static String str(byte[] data, Charset charset)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+
+ if (null == charset)
+ {
+ return new String(data);
+ }
+ return new String(data, charset);
+ }
+
+ /**
+ * 灏嗙紪鐮佺殑byteBuffer鏁版嵁杞崲涓哄瓧绗︿覆
+ *
+ * @param data 鏁版嵁
+ * @param charset 瀛楃闆嗭紝濡傛灉涓虹┖浣跨敤褰撳墠绯荤粺瀛楃闆
+ * @return 瀛楃涓
+ */
+ public static String str(ByteBuffer data, String charset)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+
+ return str(data, Charset.forName(charset));
+ }
+
+ /**
+ * 灏嗙紪鐮佺殑byteBuffer鏁版嵁杞崲涓哄瓧绗︿覆
+ *
+ * @param data 鏁版嵁
+ * @param charset 瀛楃闆嗭紝濡傛灉涓虹┖浣跨敤褰撳墠绯荤粺瀛楃闆
+ * @return 瀛楃涓
+ */
+ public static String str(ByteBuffer data, Charset charset)
+ {
+ if (null == charset)
+ {
+ charset = Charset.defaultCharset();
+ }
+ return charset.decode(data).toString();
+ }
+
+ // ----------------------------------------------------------------------- 鍏ㄨ鍗婅杞崲
+ /**
+ * 鍗婅杞叏瑙
+ *
+ * @param input String.
+ * @return 鍏ㄨ瀛楃涓.
+ */
+ public static String toSBC(String input)
+ {
+ return toSBC(input, null);
+ }
+
+ /**
+ * 鍗婅杞叏瑙
+ *
+ * @param input String
+ * @param notConvertSet 涓嶆浛鎹㈢殑瀛楃闆嗗悎
+ * @return 鍏ㄨ瀛楃涓.
+ */
+ public static String toSBC(String input, Set notConvertSet)
+ {
+ char[] c = input.toCharArray();
+ for (int i = 0; i < c.length; i++)
+ {
+ if (null != notConvertSet && notConvertSet.contains(c[i]))
+ {
+ // 璺宠繃涓嶆浛鎹㈢殑瀛楃
+ continue;
+ }
+
+ if (c[i] == ' ')
+ {
+ c[i] = '\u3000';
+ }
+ else if (c[i] < '\177')
+ {
+ c[i] = (char) (c[i] + 65248);
+
+ }
+ }
+ return new String(c);
+ }
+
+ /**
+ * 鍏ㄨ杞崐瑙
+ *
+ * @param input String.
+ * @return 鍗婅瀛楃涓
+ */
+ public static String toDBC(String input)
+ {
+ return toDBC(input, null);
+ }
+
+ /**
+ * 鏇挎崲鍏ㄨ涓哄崐瑙
+ *
+ * @param text 鏂囨湰
+ * @param notConvertSet 涓嶆浛鎹㈢殑瀛楃闆嗗悎
+ * @return 鏇挎崲鍚庣殑瀛楃
+ */
+ public static String toDBC(String text, Set notConvertSet)
+ {
+ char[] c = text.toCharArray();
+ for (int i = 0; i < c.length; i++)
+ {
+ if (null != notConvertSet && notConvertSet.contains(c[i]))
+ {
+ // 璺宠繃涓嶆浛鎹㈢殑瀛楃
+ continue;
+ }
+
+ if (c[i] == '\u3000')
+ {
+ c[i] = ' ';
+ }
+ else if (c[i] > '\uFF00' && c[i] < '\uFF5F')
+ {
+ c[i] = (char) (c[i] - 65248);
+ }
+ }
+ return new String(c);
+ }
+
+ /**
+ * 鏁板瓧閲戦澶у啓杞崲 鍏堝啓涓畬鏁寸殑鐒跺悗灏嗗闆舵嬀鏇挎崲鎴愰浂
+ *
+ * @param n 鏁板瓧
+ * @return 涓枃澶у啓鏁板瓧
+ */
+ public static String digitUppercase(double n)
+ {
+ String[] fraction = { "瑙", "鍒" };
+ String[] digit = { "闆", "澹", "璐", "鍙", "鑲", "浼", "闄", "鏌", "鎹", "鐜" };
+ String[][] unit = { { "鍏", "涓", "浜" }, { "", "鎷", "浣", "浠" } };
+
+ String head = n < 0 ? "璐" : "";
+ n = Math.abs(n);
+
+ String s = "";
+ for (int i = 0; i < fraction.length; i++)
+ {
+ // 浼樺寲double璁$畻绮惧害涓㈠け闂
+ BigDecimal nNum = new BigDecimal(n);
+ BigDecimal decimal = new BigDecimal(10);
+ BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN);
+ double d = scale.doubleValue();
+ s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(闆.)+", "");
+ }
+ if (s.length() < 1)
+ {
+ s = "鏁";
+ }
+ int integerPart = (int) Math.floor(n);
+
+ for (int i = 0; i < unit[0].length && integerPart > 0; i++)
+ {
+ String p = "";
+ for (int j = 0; j < unit[1].length && n > 0; j++)
+ {
+ p = digit[integerPart % 10] + unit[1][j] + p;
+ integerPart = integerPart / 10;
+ }
+ s = p.replaceAll("(闆.)*闆$", "").replaceAll("^$", "闆") + unit[0][i] + s;
+ }
+ return head + s.replaceAll("(闆.)*闆跺厓", "鍏").replaceFirst("(闆.)+", "").replaceAll("(闆.)+", "闆").replaceAll("^鏁$", "闆跺厓鏁");
+ }
+}
diff --git a/jing-modules/jing-gen/src/main/resources/vm/java/controller.java.vm b/jing-modules/jing-gen/src/main/resources/vm/java/controller.java.vm
new file mode 100644
index 0000000..b53c6b0
--- /dev/null
+++ b/jing-modules/jing-gen/src/main/resources/vm/java/controller.java.vm
@@ -0,0 +1,116 @@
+package ${packageName}.controller;
+
+import java.util.List;
+import java.io.IOException;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.jing.common.log.annotation.Log;
+import com.jing.common.log.enums.BusinessType;
+import com.jing.common.security.annotation.RequiresPermissions;
+import ${packageName}.domain.${ClassName};
+import ${packageName}.service.I${ClassName}Service;
+import com.jing.common.core.web.controller.BaseController;
+import com.jing.common.core.web.domain.AjaxResult;
+import com.jing.common.core.utils.poi.ExcelUtil;
+#if($table.crud || $table.sub)
+import com.jing.common.core.web.page.TableDataInfo;
+#elseif($table.tree)
+#end
+
+/**
+ * ${functionName}Controller
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+@RestController
+@RequestMapping("/${businessName}")
+public class ${ClassName}Controller extends BaseController
+{
+ @Autowired
+ private I${ClassName}Service ${className}Service;
+
+ /**
+ * 鏌ヨ${functionName}鍒楄〃
+ */
+ @RequiresPermissions("${permissionPrefix}:list")
+ @GetMapping("/list")
+#if($table.crud || $table.sub)
+ public TableDataInfo list(${ClassName} ${className})
+ {
+ startPage();
+ List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
+ return getDataTable(list);
+ }
+#elseif($table.tree)
+ public AjaxResult list(${ClassName} ${className})
+ {
+ List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
+ return success(list);
+ }
+#end
+
+ /**
+ * 瀵煎嚭${functionName}鍒楄〃
+ */
+ @RequiresPermissions("${permissionPrefix}:export")
+ @Log(title = "${functionName}", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, ${ClassName} ${className})
+ {
+ List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
+ ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);
+ util.exportExcel(response, list, "${functionName}鏁版嵁");
+ }
+
+ /**
+ * 鑾峰彇${functionName}璇︾粏淇℃伅
+ */
+ @RequiresPermissions("${permissionPrefix}:query")
+ @GetMapping(value = "/{${pkColumn.javaField}}")
+ public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField})
+ {
+ return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));
+ }
+
+ /**
+ * 鏂板${functionName}
+ */
+ @RequiresPermissions("${permissionPrefix}:add")
+ @Log(title = "${functionName}", businessType = BusinessType.INSERT)
+ @PostMapping
+ public AjaxResult add(@RequestBody ${ClassName} ${className})
+ {
+ return toAjax(${className}Service.insert${ClassName}(${className}));
+ }
+
+ /**
+ * 淇敼${functionName}
+ */
+ @RequiresPermissions("${permissionPrefix}:edit")
+ @Log(title = "${functionName}", businessType = BusinessType.UPDATE)
+ @PutMapping
+ public AjaxResult edit(@RequestBody ${ClassName} ${className})
+ {
+ return toAjax(${className}Service.update${ClassName}(${className}));
+ }
+
+ /**
+ * 鍒犻櫎${functionName}
+ */
+ @RequiresPermissions("${permissionPrefix}:remove")
+ @Log(title = "${functionName}", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{${pkColumn.javaField}s}")
+ public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s)
+ {
+ return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s));
+ }
+}
diff --git a/jing-modules/jing-job/src/main/java/com/jing/job/util/CronUtils.java b/jing-modules/jing-job/src/main/java/com/jing/job/util/CronUtils.java
new file mode 100644
index 0000000..730cafd
--- /dev/null
+++ b/jing-modules/jing-job/src/main/java/com/jing/job/util/CronUtils.java
@@ -0,0 +1,63 @@
+package com.jing.job.util;
+
+import java.text.ParseException;
+import java.util.Date;
+import org.quartz.CronExpression;
+
+/**
+ * cron琛ㄨ揪寮忓伐鍏风被
+ *
+ * @author ruoyi
+ *
+ */
+public class CronUtils
+{
+ /**
+ * 杩斿洖涓涓竷灏斿间唬琛ㄤ竴涓粰瀹氱殑Cron琛ㄨ揪寮忕殑鏈夋晥鎬
+ *
+ * @param cronExpression Cron琛ㄨ揪寮
+ * @return boolean 琛ㄨ揪寮忔槸鍚︽湁鏁
+ */
+ public static boolean isValid(String cronExpression)
+ {
+ return CronExpression.isValidExpression(cronExpression);
+ }
+
+ /**
+ * 杩斿洖涓涓瓧绗︿覆鍊,琛ㄧず璇ユ秷鎭棤鏁圕ron琛ㄨ揪寮忕粰鍑烘湁鏁堟
+ *
+ * @param cronExpression Cron琛ㄨ揪寮
+ * @return String 鏃犳晥鏃惰繑鍥炶〃杈惧紡閿欒鎻忚堪,濡傛灉鏈夋晥杩斿洖null
+ */
+ public static String getInvalidMessage(String cronExpression)
+ {
+ try
+ {
+ new CronExpression(cronExpression);
+ return null;
+ }
+ catch (ParseException pe)
+ {
+ return pe.getMessage();
+ }
+ }
+
+ /**
+ * 杩斿洖涓嬩竴涓墽琛屾椂闂存牴鎹粰瀹氱殑Cron琛ㄨ揪寮
+ *
+ * @param cronExpression Cron琛ㄨ揪寮
+ * @return Date 涓嬫Cron琛ㄨ揪寮忔墽琛屾椂闂
+ */
+ public static Date getNextExecution(String cronExpression)
+ {
+ try
+ {
+ CronExpression cron = new CronExpression(cronExpression);
+ return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis()));
+ }
+ catch (ParseException e)
+ {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ }
+}
diff --git a/jing-ui/src/assets/icons/svg/checkbox.svg b/jing-ui/src/assets/icons/svg/checkbox.svg
new file mode 100644
index 0000000..013fd3a
--- /dev/null
+++ b/jing-ui/src/assets/icons/svg/checkbox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/jing-ui/src/assets/icons/svg/client.svg b/jing-ui/src/assets/icons/svg/client.svg
new file mode 100644
index 0000000..235d634
--- /dev/null
+++ b/jing-ui/src/assets/icons/svg/client.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/jing-ui/src/assets/icons/svg/clipboard.svg b/jing-ui/src/assets/icons/svg/clipboard.svg
new file mode 100644
index 0000000..90923ff
--- /dev/null
+++ b/jing-ui/src/assets/icons/svg/clipboard.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/jing-ui/src/assets/icons/svg/code.svg b/jing-ui/src/assets/icons/svg/code.svg
new file mode 100644
index 0000000..5f9c5ab
--- /dev/null
+++ b/jing-ui/src/assets/icons/svg/code.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/jing-ui/src/assets/icons/svg/color.svg b/jing-ui/src/assets/icons/svg/color.svg
new file mode 100644
index 0000000..44a81aa
--- /dev/null
+++ b/jing-ui/src/assets/icons/svg/color.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/jing-ui/src/directive/module/clipboard.js b/jing-ui/src/directive/module/clipboard.js
new file mode 100644
index 0000000..635315a
--- /dev/null
+++ b/jing-ui/src/directive/module/clipboard.js
@@ -0,0 +1,54 @@
+/**
+* v-clipboard 鏂囧瓧澶嶅埗鍓创
+* Copyright (c) 2021 ruoyi
+*/
+
+import Clipboard from 'clipboard'
+export default {
+ bind(el, binding, vnode) {
+ switch (binding.arg) {
+ case 'success':
+ el._vClipBoard_success = binding.value;
+ break;
+ case 'error':
+ el._vClipBoard_error = binding.value;
+ break;
+ default: {
+ const clipboard = new Clipboard(el, {
+ text: () => binding.value,
+ action: () => binding.arg === 'cut' ? 'cut' : 'copy'
+ });
+ clipboard.on('success', e => {
+ const callback = el._vClipBoard_success;
+ callback && callback(e);
+ });
+ clipboard.on('error', e => {
+ const callback = el._vClipBoard_error;
+ callback && callback(e);
+ });
+ el._vClipBoard = clipboard;
+ }
+ }
+ },
+ update(el, binding) {
+ if (binding.arg === 'success') {
+ el._vClipBoard_success = binding.value;
+ } else if (binding.arg === 'error') {
+ el._vClipBoard_error = binding.value;
+ } else {
+ el._vClipBoard.text = function () { return binding.value; };
+ el._vClipBoard.action = () => binding.arg === 'cut' ? 'cut' : 'copy';
+ }
+ },
+ unbind(el, binding) {
+ if (!el._vClipboard) return
+ if (binding.arg === 'success') {
+ delete el._vClipBoard_success;
+ } else if (binding.arg === 'error') {
+ delete el._vClipBoard_error;
+ } else {
+ el._vClipBoard.destroy();
+ delete el._vClipBoard;
+ }
+ }
+}
diff --git a/jing-ui/src/views/tool/build/CodeTypeDialog.vue b/jing-ui/src/views/tool/build/CodeTypeDialog.vue
new file mode 100644
index 0000000..b5c2e2e
--- /dev/null
+++ b/jing-ui/src/views/tool/build/CodeTypeDialog.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 鍙栨秷
+
+
+ 纭畾
+
+
+
+
+
+