This commit is contained in:
shimu
2024-05-21 11:34:38 +08:00
commit 1c0e4b1bf0
70 changed files with 2077 additions and 0 deletions

2
.browserslistrc Normal file
View File

@@ -0,0 +1,2 @@
> 1%
last 2 versions

9
.editorconfig Normal file
View File

@@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

82
.eslintrc.js Normal file
View File

@@ -0,0 +1,82 @@
module.exports = {
root: true,
env: {
browser: true,
node: true
},
extends: ["plugin:vue/recommended"],
rules: {
// indent: "off",
"vue/max-len": [
"error",
{
code: 360,
template: 360,
comments: 160
}
],
"vue/name-property-casing": [0, "PascalCase" | "kebab-case"],
"vue/require-default-prop": 0,
"vue/html-closing-bracket-newline": [
0,
{
singleline: "never",
multiline: "always"
}
],
"vue/no-side-effects-in-computed-properties": 0,
"vue/singleline-html-element-content-newline": "off",
"vue/attribute-hyphenation": [0, "always" | "never"],
"vue/max-attributes-per-line": [
2,
{
singleline: 10,
multiline: {
max: 1,
allowFirstLine: false
}
}
],
"vue/html-self-closing": [
"error",
{
html: {
void: "any",
normal: "any",
component: "any"
},
svg: "any",
math: "any"
}
],
"vue/script-indent": [
"error",
4,
{
baseIndent: 0,
switchCase: 0,
ignores: []
}
],
"vue/html-indent": [
"error",
4,
{
attribute: 1,
baseIndent: 1,
closeBracket: 0,
alignAttributesVertically: true,
ignores: []
}
]
},
globals: {
Vue: true,
__webpack_public_path__: true
},
plugins: ["vue"],
parserOptions: {
parser: "babel-eslint",
sourceType: "module"
}
};

92
.gitignore vendored Normal file
View File

@@ -0,0 +1,92 @@
.DS_Store
node_modules
dist/
debug/
*.iml
# local env files
.env.local
.env.*.local
.settings/
.vscode/
log/
*.pid
logs/
target/
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
.classpath
.project
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# OSX
#
.DS_Store
# Xcode
#
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
# Android/IntelliJ
#
.idea/
.idea
.gradle
local.properties
*.iml
# node.js
#
node_modules/
npm-debug.log
yarn-error.log
# BUCK
buck-out/
\.buckd/
*.keystore
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
index.android.bundle
index.android.bundle.meta
package-lock.json
yarn.lock

21
README.md Normal file
View File

@@ -0,0 +1,21 @@
# cms
> cms项目
## Scripts
> 脚本
```json
{
"serve": "vue-cli-service serve --open",
"build": "vue-cli-service build --mode=production",
"dev": "npm run serve",
"dist": "vue-cli-service lint && node ./build/index.js",
"lint": "vue-cli-service lint --fix",
"test:unit": "vue-cli-service test:unit",
"pub": "npm publish --registry=http://npm.proxy.zeto.me",
"clean": "npm cache clear --force",
"init": "npm cache clear --force && npm install --registry http://npm.proxy.zeto.me"
}
```

32
iot/package.xml Normal file
View File

@@ -0,0 +1,32 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>customAssembly</id>
<!-- dir -->
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/lib</outputDirectory>
<scope>runtime</scope>
<excludes>
<exclude>${project.groupId}:${project.artifactId}</exclude>
</excludes>
</dependencySet>
<dependencySet>
<outputDirectory>/</outputDirectory>
<includes>
<include>${project.groupId}:${project.artifactId}</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>

117
iot/pom.xml Normal file
View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>iot</artifactId>
<packaging>jar</packaging>
<name>iot</name>
<groupId>com.zeto</groupId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<com.zeto>3.0.0</com.zeto>
</properties>
<dependencies>
<dependency>
<groupId>com.zeto</groupId>
<artifactId>core</artifactId>
<version>${com.zeto}</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.211</version>
</dependency>
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.16.5</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos-sts_api</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.640</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos-sts_api</artifactId>
<version>3.1.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>package.xml</descriptor>
</descriptors>
<outputDirectory>${project.build.directory}/dist/</outputDirectory>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.zeto.${project.name}.Application</mainClass>
</transformer>
</transformers>
<finalName>${project.name}</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,13 @@
package com.zeto.cms;
import com.zeto.Zen;
public class Application {
public static void main(String[] args) {
int listenPort = 7097;
String appName = "iot";
// ZenEnvironment.setMulti(true);
Zen.start(args, appName, listenPort, Application.class);
}
}

View File

@@ -0,0 +1,24 @@
package com.zeto.cms.controller;
import com.zeto.ZenData;
import com.zeto.ZenEngine;
import com.zeto.ZenResult;
import com.zeto.annotation.AccessRole;
import com.zeto.domain.ZenUserTag;
import com.zeto.kit.DateKit;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Inject;
@Slf4j
@AccessRole(ZenUserTag.ADMIN)
public class Activity {
@Inject
private ZenEngine zenEngine;
public ZenResult content(ZenData context) {
ZenResult result = zenEngine.execute("get/activityOutput", context);
return result.put("now", DateKit.now() * 1000).setMessage(null);
}
}

View File

@@ -0,0 +1,5 @@
package com.zeto.cms.helper.login;
// 钉钉登录
public class DingLogin {
}

View File

@@ -0,0 +1,5 @@
package com.zeto.cms.helper.login;
// 企业微信登录
public class WeCom {
}

View File

@@ -0,0 +1,15 @@
package com.zeto.cms.helper.upload;
import java.util.Map;
public interface IUploader {
void put(String path, String content, String contentType);
void remove(String path);
String get(String path);
void refresh(String path);
Map<String, Object> token(String fileName, String target);
}

View File

@@ -0,0 +1,63 @@
package com.zeto.cms.helper.upload;
import com.zeto.ZenEnvironment;
import com.zeto.cms.helper.upload.cos.CosUploader;
import com.zeto.kit.ConfigKit;
import java.util.HashMap;
import java.util.Map;
public class Uploader {
private static IUploader uploader = null;
private static final Map<String, String> contentTypeMap = new HashMap<String, String>() {{
put("js", "application/javascript;charset=utf-8");
put("css", "text/css;charset=utf-8");
put("json", "application/json;charset=utf-8");
put("gif", "image/gif");
put("png", "image/png");
put("jpg", "image/jpeg");
put("woff", "application/font-woff");
put("woff2", "application/font-woff2");
put("otf", "application/x-font-opentype");
put("ttf", "application/x-font-ttf");
put("svg", "image/svg+xml");
put("eot", "application/vnd.ms-fontobject");
}};
private static IUploader i() {
if (Uploader.uploader == null) {
String type = ZenEnvironment.get("cloudType");
if (type.equals("qcloud")) Uploader.uploader = new CosUploader();
}
return Uploader.uploader;
}
public static void put(String path, String content) {
int extIndex = path.lastIndexOf(".");
if (extIndex < 0) return;
String ext = path.substring(extIndex + 1);
if (!Uploader.contentTypeMap.containsKey(ext)) return;
Uploader.i().put(path, content, Uploader.contentTypeMap.get(ext));
Uploader.refresh(path);
}
public static String get(String path) {
return Uploader.i().get(path);
}
public static void remove(String path) {
Uploader.i().remove(path);
Uploader.refresh(path);
}
public static void refresh(String path) {
// 非线上环境无需刷CDN
if (!ZenEnvironment.isOnline()) return;
String webpath = ZenEnvironment.get("cdnHost") + path;
Uploader.i().refresh(webpath);
}
public static Map<String, Object> token(String fileName, String target) {
return Uploader.i().token(fileName, target);
}
}

View File

@@ -0,0 +1,155 @@
package com.zeto.cms.helper.upload.cos;
import com.google.common.base.Strings;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.model.COSObject;
import com.qcloud.cos.model.COSObjectInputStream;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.utils.IOUtils;
import com.qcloud.cos.utils.StringUtils;
import com.tencent.cloud.CosStsClient;
import com.tencent.cloud.Response;
import com.zeto.ZenEnvironment;
import com.zeto.cms.helper.upload.IUploader;
import com.zeto.kit.StringKit;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
@Slf4j
public class CosUploader implements IUploader {
private final String publicBucket;
private final COSClient cosClient;
private final String defaultType = "public";
public CosUploader() {
String secretId = ZenEnvironment.get("bucketAK");
String secretKey = ZenEnvironment.get("bucketSK");
String region = ZenEnvironment.get("bucketRegion");
publicBucket = ZenEnvironment.get("bucketPublic");
// 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region(region));
// 生成cos客户端
this.cosClient = new COSClient(cred, clientConfig);
}
@Override
public void remove(String path) {
}
@Override
public void put(String path, String content, String contentType) {
if (Strings.isNullOrEmpty(content) || Strings.isNullOrEmpty(path)) return;
byte[] contentByteArray = content.getBytes(StringUtils.UTF8);
InputStream contentInput = new ByteArrayInputStream(contentByteArray);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(contentType);
metadata.setContentLength(contentByteArray.length);
PutObjectRequest putObjectRequest = new PutObjectRequest(publicBucket, path, contentInput, metadata);
cosClient.putObject(putObjectRequest);
}
@Override
public String get(String path) {
COSObjectInputStream cosObjectInput = null;
try {
COSObject cosObject = cosClient.getObject(publicBucket, path);
cosObjectInput = cosObject.getObjectContent();
} catch (CosClientException e) {
CosUploader.log.error("uploader", e);
}
// 这里是直接读取,按实际情况来处理
byte[] bytes = null;
try {
bytes = IOUtils.toByteArray(cosObjectInput);
} catch (IOException e) {
CosUploader.log.error("uploader", e);
} finally {
// 用完流之后一定要调用 close()
try {
cosObjectInput.close();
} catch (IOException e) {
CosUploader.log.error("uploader", e);
}
}
return new String(bytes);
}
// 刷新CDN
@Override
public void refresh(String path) {
}
@Override
public Map<String, Object> token(String fileName, String target) {
String secretId = ZenEnvironment.get("bucketAK");
String secretKey = ZenEnvironment.get("bucketSK");
String region = ZenEnvironment.get("bucketRegion");
String domain = ZenEnvironment.get("bucketDomain");
String filepath = this.getPath(fileName);
TreeMap<String, Object> config = new TreeMap<>();
// 替换为您的云 api 密钥 SecretId
config.put("secretId", secretId);
// 替换为您的云 api 密钥 SecretKey
config.put("secretKey", secretKey);
String bucket = defaultType.equals(target) ? publicBucket : ZenEnvironment.get("bucketPrivate");
// 临时密钥有效时长,单位是秒,默认 1800 秒,目前主账号最长 2 小时(即 7200 秒),子账号最长 36 小时(即 129600
int timeout = 1800;
config.put("durationSeconds", timeout);
config.put("bucket", bucket);
// 换成 publicBucket 所在地区
config.put("region", region);
String allowPrefix = filepath.substring(0, 18) + "*";
config.put("allowPrefixes", new String[]{allowPrefix});
String[] allowActions = new String[]{
"name/cos:PutObject",
"name/cos:PostObject"
};
config.put("allowActions", allowActions);
Map<String, Object> result = new HashMap<>();
try {
Response response = CosStsClient.getCredential(config);
// 腾讯云
result.put("type", "cos");
result.put("startTime", response.startTime);
result.put("expiredTime", response.expiredTime);
// 地域地址https://cloud.tencent.com/document/product/436/6224
result.put("pathname", filepath);
result.put("bucket", bucket);
result.put("region", region);
result.put("url", domain + filepath);
result.put("secretId", response.credentials.tmpSecretId);
result.put("secretKey", response.credentials.tmpSecretKey);
result.put("sessionToken", response.credentials.sessionToken);
} catch (IOException e) {
throw new RuntimeException(e);
}
return result;
}
private String getPath(String fileName) {
String ext = StringKit.fileExt(fileName);
String fileId = StringKit.objectId();
return "f01/" + ext + "/" + fileId.substring(0, 2) + "/" + fileId.substring(2) + "." + ext;
}
}

View File

@@ -0,0 +1,4 @@
package com.zeto.cms.helper.upload.oss;
public class OssUploader {
}

View File

@@ -0,0 +1,57 @@
package com.zeto.cms.hooks;
import com.zeto.IZenHook;
import com.zeto.ZenData;
import com.zeto.ZenEngine;
import com.zeto.ZenResult;
import com.zeto.annotation.ZenHook;
import com.zeto.cms.helper.upload.Uploader;
import com.zeto.cms.hooks.domain.PageComponentDO;
import com.zeto.cms.hooks.domain.PageDO;
import com.zeto.driver.JsonKit;
import com.zeto.kit.StringKit;
import org.noear.solon.annotation.Inject;
@ZenHook("patch/activityStatus")
public class ActivityStatusHook implements IZenHook {
private final static String online = "2";
private final static String offline = "3";
@Inject
private ZenEngine zenEngine;
@Override
public ZenResult before(ZenData context) {
String status = context.get("status");
ZenResult result = zenEngine.execute("get/activity", context);
String pathStr = StringKit.objectId();
String path = "/" + pathStr.substring(0, 2) + "/" + pathStr.substring(2);
// 页面上线
if (ActivityStatusHook.online.equals(status)) {
PageDO pageDO = result.get("content", PageDO.class);
Object pageData = result.getObject("data");
pageDO.setData(pageData);
StringBuilder jsResult = new StringBuilder();
for (PageComponentDO componentDO : pageDO.getComponents()) {
String jsSource = "/" + componentDO.getLib() + "/" + componentDO.getName() + ".js";
jsResult.append(Uploader.get(jsSource)).append(";");
}
String pageDataStr = JsonKit.stringify(pageDO);
// 推送数据与js资源
Uploader.put("/jsz" + path + ".json", pageDataStr);
Uploader.put("/jsz" + path + ".js", jsResult.toString());
context.put("output", path);
}
return ZenResult.success();
}
@Override
public void after(ZenData context, ZenResult result) {
String id = context.getId();
String status = context.get("status");
// 页面上线
if (ActivityStatusHook.offline.equals(status)) {
//todo: 完成cdn下线
}
}
}

View File

@@ -0,0 +1,21 @@
package com.zeto.cms.hooks;
import com.zeto.IZenHook;
import com.zeto.ZenData;
import com.zeto.ZenResult;
import com.zeto.annotation.ZenHook;
import com.zeto.cms.helper.upload.Uploader;
import java.util.Map;
@ZenHook("zetoUploadHook")
public class ZetoUploadHook implements IZenHook {
@Override
public ZenResult before(ZenData context) {
IZenHook.super.before(context);
String fileName = context.get("filename");
String target = context.get("target");
Map<String, Object> data = Uploader.token(fileName, target);
return ZenResult.success().setData(data);
}
}

View File

@@ -0,0 +1,13 @@
package com.zeto.cms.hooks.domain;
import lombok.Data;
import java.util.Map;
@Data
public class PageComponentDO {
private String name;
private String id;
private String lib;
private Map<String, String> meta;
}

View File

@@ -0,0 +1,13 @@
package com.zeto.cms.hooks.domain;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class PageDO {
private List<PageComponentDO> components;
private int counter;
private Object data;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"columns":[{"defaultValue":"","describe":"编号","length":24,"name":"id","required":false,"type":2},{"defaultValue":"","describe":"文章标题","length":200,"name":"title","required":false,"type":2},{"defaultValue":"","describe":"文章分类","length":24,"name":"category_id","required":false,"type":2},{"code":"articleType","defaultValue":"","describe":"文章类型","length":1,"name":"type","required":false,"type":1},{"defaultValue":"","describe":"文章内容","length":0,"name":"content","required":false,"type":10},{"defaultValue":"","describe":"是否支持评论","length":0,"name":"commentable","required":false,"type":1},{"defaultValue":"","describe":"创建时间","length":0,"name":"create_gmt","required":false,"type":6},{"defaultValue":"","describe":"更新时间","length":0,"name":"update_gmt","required":false,"type":6},{"defaultValue":"","describe":"图片列表","length":0,"name":"pictures","required":false,"type":12},{"defaultValue":"","describe":"创建者","length":24,"name":"uid","required":false,"type":2},{"defaultValue":"","describe":"创建者","length":50,"name":"author","required":false,"type":2},{"defaultValue":"","describe":"来源","length":200,"name":"from","required":false,"type":2}],"indices":[],"name":"article"},{"columns":[{"defaultValue":"","describe":"编号","length":24,"name":"id","required":false,"type":2},{"defaultValue":"","describe":"分类标题","length":20,"name":"title","required":false,"type":2},{"defaultValue":"","describe":"分类描述","length":200,"name":"describe","required":false,"type":2},{"defaultValue":"","describe":"父级id","length":24,"name":"parent_id","required":false,"type":2},{"defaultValue":"","describe":"创建时间","length":0,"name":"create_gmt","required":false,"type":6},{"defaultValue":"","describe":"更新时间","length":0,"name":"update_gmt","required":false,"type":6}],"indices":[],"name":"category"},{"columns":[{"defaultValue":"","describe":"编号","length":24,"name":"id","required":false,"type":2},{"defaultValue":"","describe":"页面标题","length":50,"name":"title","required":false,"type":2},{"defaultValue":"","describe":"页面路径","length":50,"name":"path","required":false,"type":2},{"code":"pageType","defaultValue":"","describe":"页面类型","length":1,"name":"type","required":false,"type":1},{"defaultValue":"","describe":"所属站点","length":24,"name":"site_id","required":false,"type":2},{"defaultValue":"","describe":"描述内容","length":0,"name":"content","required":false,"type":12},{"code":"pageStatus","defaultValue":"","describe":"页面状态","length":1,"name":"status","required":false,"type":1},{"defaultValue":"","describe":"创建时间","length":0,"name":"create_gmt","required":false,"type":6},{"defaultValue":"","describe":"更新时间","length":0,"name":"update_gmt","required":false,"type":6},{"defaultValue":"","describe":"页面数据","length":0,"name":"data","required":false,"type":12},{"defaultValue":"","describe":"js path输出ID","length":200,"name":"output","required":false,"type":2}],"indices":[],"name":"activity"},{"columns":[{"defaultValue":"","describe":"站点名称","length":50,"name":"title","required":false,"type":2},{"defaultValue":"","describe":"描述信息","length":300,"name":"describe","required":false,"type":2},{"defaultValue":"","describe":"站点域名","length":50,"name":"domain","required":false,"type":2},{"defaultValue":"","describe":"备案信息","length":200,"name":"record","required":false,"type":2},{"defaultValue":"","describe":"编号","length":24,"name":"id","required":false,"type":2},{"defaultValue":"","describe":"创建时间","length":0,"name":"create_gmt","required":false,"type":6},{"defaultValue":"","describe":"更新时间","length":0,"name":"update_gmt","required":false,"type":6}],"indices":[{"columns":["domain"],"index":"Unique"}],"name":"site"},{"columns":[{"defaultValue":"","describe":"页面标题","length":50,"name":"title","required":false,"type":2},{"defaultValue":"","describe":"页面路径","length":50,"name":"path","required":false,"type":2},{"defaultValue":"","describe":"平台类型","length":0,"name":"type","required":false,"type":1},{"defaultValue":"","describe":"所属站点","length":24,"name":"site_id","required":false,"type":2},{"defaultValue":"","describe":"网站内容","length":0,"name":"content","required":false,"type":4},{"code":"pageStatus","defaultValue":"","describe":"状态","length":0,"name":"status","required":false,"type":1},{"defaultValue":"","describe":"模版ID","length":24,"name":"template_id","required":false,"type":2},{"defaultValue":"","describe":"编号","length":24,"name":"id","required":false,"type":2},{"defaultValue":"","describe":"创建时间","length":0,"name":"create_gmt","required":false,"type":6},{"defaultValue":"","describe":"更新时间","length":0,"name":"update_gmt","required":false,"type":6}],"indices":[{"columns":["path"],"index":"Unique"}],"name":"page"}]

View File

@@ -0,0 +1,93 @@
{
"columns": [
{
"defaultValue": "",
"describe": "编号",
"length": 24,
"name": "id",
"required": false,
"type": 2
},
{
"defaultValue": "",
"describe": "昵称",
"length": 50,
"name": "nick",
"required": false,
"type": 2
},
{
"defaultValue": "",
"describe": "登录名",
"length": 24,
"name": "username",
"required": false,
"type": 2
},
{
"defaultValue": "",
"describe": "联系电话",
"length": 1,
"name": "mobile",
"required": false,
"type": 2
},
{
"defaultValue": "",
"describe": "账号密码",
"length": 200,
"name": "pwd",
"required": false,
"type": 2
},
{
"defaultValue": "",
"describe": "三方唯一ID",
"length": 50,
"name": "union_id",
"required": false,
"type": 2
},
{
"defaultValue": "",
"describe": "基础标签",
"length": 0,
"name": "tag",
"required": false,
"type": 1
},
{
"defaultValue": "",
"describe": "用户邮箱",
"length": 50,
"name": "email",
"required": false,
"type": 2
},{
"defaultValue": "",
"describe": "动态密钥",
"length": 200,
"name": "ukey",
"required": false,
"type": 2
},
{
"defaultValue": "",
"describe": "创建时间",
"length": 0,
"name": "create_gmt",
"required": false,
"type": 6
},
{
"defaultValue": "",
"describe": "更新时间",
"length": 0,
"name": "update_gmt",
"required": false,
"type": 6
}
],
"indices": [],
"name": "user"
}

View File

@@ -0,0 +1 @@
v2.0.0-20240102

3
vue/.npmrc Normal file
View File

@@ -0,0 +1,3 @@
registry=https://registry.npmmirror.com/
@zen:registry=https://git.proxy.yimiyisu.com/api/packages/sinbo/npm/
save-dev=true

8
vue/jsconfig.json Normal file
View File

@@ -0,0 +1,8 @@
{
"modules": [],
"compilerOptions": {
"module": "commonjs",
"target": "es6"
},
"exclude": ["node_modules"]
}

98
vue/package.json Normal file
View File

@@ -0,0 +1,98 @@
{
"name": "iot",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "webpack-dev-server --mode=development",
"dist": "npm run lint && webpack --mode=production",
"deploy": "npm run dist && node ./release/cos.js",
"prepare": "cd .. && husky install",
"init": "yarn && npm run prepare",
"lint": "eslint --fix --ext .js,.vue ./src"
},
"dependencies": {
"core-js": "^3.6.5"
},
"devDependencies": {
"@babel/core": "^7.23.5",
"@babel/plugin-syntax-jsx": "^7.23.3",
"@babel/plugin-transform-runtime": "^7.17.0",
"@babel/preset-env": "^7.23.5",
"@vue/babel-plugin-jsx": "^1.1.5",
"@vue/babel-preset-app": "^5.0.8",
"@vue/compiler-sfc": "^3.4.15",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.4",
"cos-nodejs-sdk-v5": "^2.11.6",
"css-loader": "^3.5.3",
"eslint": "^7.28.0",
"eslint-plugin-vue": "^8.4.1",
"fs-extra": "^10.0.0",
"husky": "^7.0.4",
"lint-staged": "^12.3.4",
"pako": "^2.0.4",
"prettier": "^2.5.1",
"prismjs": "^1.22.0",
"sass": "^1.49.7",
"sass-loader": "^12.4.0",
"simple-git": "^3.1.1",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.1",
"vue": "^3.4.21",
"vue-loader": "^17.3.1",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.2",
"@zen/app-plugin": "^0.2.1"
},
"eslintIgnore": [
"public/*",
"dist/*"
],
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"plugins": [
"vue"
],
"parserOptions": {
"parser": "babel-eslint",
"sourceType": "module"
},
"globals": {
"zen": true,
"$": true,
"Vue": true,
"__webpack_public_path__": true
},
"rules": {
"no-useless-escape": 0,
"no-debugger": 0,
"vue/multi-word-component-names": 0,
"no-case-declaration": 0,
"vue/no-mutating-props": 0
}
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"pre-push": "cd vue && npm run lint"
}
},
"lint-staged": {
"*.{js,jsx,vue}": [
"cd vue && npm run lint"
]
},
"browserslist": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}

28
vue/public/design.html Normal file
View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome,IE=edge" />
<meta name="HandheldFriendly" content="true" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, user-scalable=no, minimal-ui, viewport-fit=cover" />
<meta name="renderer" content="webkit" />
<meta name="msapplication-tap-highlight" content="no" />
<title>CMS</title>
<script>
var ZenEnv = 'LOCAL_DEV';
</script>
<script src="//b.ebus.vip/zeto/v5.1.3/zen.dev.js"></script>
<link rel="stylesheet" type="text/css" href="//b.ebus.vip/zeto/v5.1.3/zen.css">
<script>
zen.host = 'http://127.0.0.1:7057';
</script>
</head>
<body>
<script src="/design.js"></script>
</body>
</html>

28
vue/public/index.html Normal file
View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome,IE=edge" />
<meta name="HandheldFriendly" content="true" />
<meta name="format-detection" content="telephone=no,email=no" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, user-scalable=no, minimal-ui, viewport-fit=cover" />
<meta name="renderer" content="webkit" />
<meta name="msapplication-tap-highlight" content="no" />
<title>CMS</title>
<script>
var ZenEnv = 'LOCAL_DEV';
</script>
<script src="//b.ebus.vip/zeto/v5.1.3/zen.dev.js"></script>
<link rel="stylesheet" type="text/css" href="//b.ebus.vip/zeto/v5.1.3/zen.css">
<script>
zen.host = 'http://127.0.0.1:7057';
</script>
</head>
<body>
<script src="/app.js"></script>
</body>
</html>

1
vue/public/lib/cos-auth.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
vue/public/lib/cos-js-sdk-v5.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

80
vue/release/cos.js Normal file
View File

@@ -0,0 +1,80 @@
const os = require("os");
const simpleGit = require("simple-git");
const pako = require("pako");
const GIT = simpleGit("./");
const CWD = process.cwd();
const fs = require("fs");
const { join, dirname } = require("path");
const packageFile = JSON.parse(fs.readFileSync("./package.json"));
const config = JSON.parse(fs.readFileSync(join(os.homedir(), ".cos.json")));
const domain = "//a.zeto.me/";
const COS = require("cos-nodejs-sdk-v5");
function findRootDir(dir) {
if (dir === "/") {
return "/";
}
if (fs.existsSync(dir, "package.json")) {
return dir;
}
return findRootDir(dirname(dir));
}
const ROOT = findRootDir(CWD);
const DIST_DIR = join(ROOT, "dist");
const LIB_DIR = join(ROOT, "public", "lib");
const client = new COS({
SecretId: config.id,
SecretKey: config.key,
});
function send(dir, output) {
let files = fs.readdirSync(dir);
files.forEach((item) => {
if (item.indexOf(".") === 0 || item.indexOf(".html") > -1) {
return;
}
let fpath = join(dir, item);
let stat = fs.statSync(fpath);
if (stat.isDirectory()) {
send(fpath, join(output, item));
}
if (stat.isFile()) {
let target = join(output, item).replace(/\\/gi, "/");
let cosTarget = {
Bucket: config.bucket /* 必须 */,
Region: config.region /* 必须 */,
Key: target /* 必须 */,
StorageClass: "STANDARD",
};
let isJS = target.indexOf(".js") > -1;
if (isJS || target.indexOf(".css") > -1) {
cosTarget.Headers = {
"Content-Encoding": "gzip",
"Content-Type": isJS
? "application/javascript"
: "text/css",
};
cosTarget.Body = Buffer.from(
pako.gzip(fs.readFileSync(fpath, "utf8"))
);
} else {
cosTarget.Body = fs.createReadStream(fpath);
}
client.putObject(cosTarget, (err, data) => {
if (err) {
return console.log(err, data);
}
console.log(domain + target);
});
}
});
}
GIT.branchLocal((err, branch) => {
let name = packageFile.name,
version = branch.current;
send(DIST_DIR, `${name}/${version}`);
if (fs.existsSync(LIB_DIR)) {
send(LIB_DIR, `${name}/${version}/lib`);
}
});

51
vue/release/deploy.js Normal file
View File

@@ -0,0 +1,51 @@
const os = require("os");
const simpleGit = require("simple-git");
const GIT = simpleGit("./");
const fs = require("fs");
const { join } = require("path");
const packageFile = JSON.parse(fs.readFileSync("./package.json"));
const config = JSON.parse(fs.readFileSync(join(os.homedir(), ".cos.json")));
const domain = "//a.ebus.vip/";
const COS = require("cos-nodejs-sdk-v5");
const client = new COS({
SecretId: config.id,
SecretKey: config.key,
});
function send(dir, output) {
let files = fs.readdirSync(dir);
files.forEach((item) => {
if (item.indexOf(".") === 0 || item.indexOf(".html") > -1) {
return;
}
let fpath = join(dir, item);
let stat = fs.statSync(fpath);
if (stat.isDirectory()) {
send(fpath, join(output, item));
}
if (stat.isFile()) {
let target = join(output, item).replace(/\\/gi, "/");
client.putObject(
{
Bucket: config.bucket /* 必须 */,
Region: config.region /* 必须 */,
Key: target /* 必须 */,
StorageClass: "STANDARD",
Body: fs.createReadStream(fpath), // 上传文件对象
},
(err, data) => {
if (err) {
return console.log(err, data);
}
console.log(domain + target);
}
);
// client.putObject(join(output, item), fpath)
}
});
}
GIT.branchLocal((err, branch) => {
let name = packageFile.name,
version = branch.current;
send(join(__dirname, "../dist"), `${name}/${version}`);
});

6
vue/src/app.js Normal file
View File

@@ -0,0 +1,6 @@
import Console from "./console/index.vue";
import Routes from "./pages/routes";
const dict = require("./pages/dict.json");
__webpack_public_path__ = zen.path("iot");
zen.setup({ com: Console, routes: Routes, dict });

12
vue/src/console/index.vue Normal file
View File

@@ -0,0 +1,12 @@
<template>
<z-console :menus="data" title="社区智慧安全系统" />
</template>
<script>
export default {
data() {
return {};
},
created() { },
};
</script>

View File

@@ -0,0 +1,48 @@
export default {
title: "文章分类",
entitys: [
{ name: "id", label: "编号" },
{ name: "title", label: "分类标题" },
{ name: "describe", label: "分类描述" },
{ name: "parentId", label: "父级id" },
{ name: "createGmt", label: "创建时间", type: "date" },
{ name: "updateGmt", label: "更新时间", type: "date" },
],
columns: ["id", "title", "describe", "createGmt", "updateGmt"],
condition: ["title"],
slots: {
header$() {
return (
<>
<z-action
label="新建分类"
fields={["title", "describe"]}
url="/do/put/category"
/>
</>
);
},
action$({ row }) {
return (
<>
<z-action
label="编辑"
mode="wicket"
fields={["title", "describe"]}
link
data={row}
url="/do/patch/category"
/>
<z-action
label="删除"
mode="confirm"
link
data={row}
url="/do/delete/category"
title="确定删除该分类吗?"
/>
</>
);
},
},
};

View File

@@ -0,0 +1 @@
{"table":"category","blocks":[],"counter":6787,"basic":{"title":"文章分类","selectable":0,"showIndex":0,"compact":0,"size":"","url":"/do/select/category","actions":[{"label":"新建分类","mode":"wicket","type":"primary","url":"/do/put/category","name":"add","from":null,"fields":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"describe","name":"describe","width":null,"rule":{},"block":null,"blockType":null}],"_id":6787}]},"columns":[{"id":"id","name":"id","width":null,"rule":{},"block":null,"blockType":null},{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"describe","name":"describe","width":null,"rule":{},"block":null,"blockType":null},{"id":"createGmt","name":"createGmt","width":null,"rule":{},"block":null,"blockType":null},{"id":"updateGmt","name":"updateGmt","width":null,"rule":{},"block":null,"blockType":null}],"tabs":{"code":null,"defaultVal":null,"list":[],"keyword":null},"condition":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null}],"conditionLimit":null,"actions":[{"label":"编辑","mode":"wicket","type":"text","url":"/do/patch/category","name":"J_6786","from":null,"fields":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"describe","name":"describe","width":null,"rule":{},"block":null,"blockType":null}],"_id":6788},{"label":"删除","mode":"confirm","type":"text","url":"/do/delete/category","params":["id"],"tip":"确定删除该分类吗?","_id":6789}],"_id":6789}

View File

@@ -0,0 +1,16 @@
<template>
<z-table name="6625cc13b7d97458478b8517" url="/do/select/category">
</z-table>
</template>
<script>
import configs from './.lowcode/configs';
export default {
name: 'page-category',
provide: { configs },
data() {
return {}
},
}
</script>

View File

@@ -0,0 +1,4 @@
export default {
'article/category': () => import( /* webpackChunkName: "pages/article/category" */ "./category/category.vue"),
'article/list': () => import( /* webpackChunkName: "pages/article/list" */ "./list/list.vue")
};

View File

@@ -0,0 +1,25 @@
export default {
title: "文章列表",
tabs: {"code":"articleType","list":[],"keyword":"type"},
entitys: [{"name":"id","label":"编号"},{"name":"title","label":"文章标题"},{"name":"categoryId","label":"文章分类"},{"name":"type","label":"文章类型","code":"articleType"},{"name":"content","label":"文章内容","type":"editor"},{"name":"commentable","label":"是否支持评论","type":"number"},{"name":"createGmt","label":"创建时间","type":"date"},{"name":"updateGmt","label":"更新时间","type":"date"},{"name":"pictures","label":"图片列表"},{"name":"uid","label":"创建者"},{"name":"author","label":"创建者"},{"name":"from","label":"来源"}],
columns: ["id","title","type","uid","updateGmt","createGmt"],
condition: ["title","categoryId"],
slots: {
header$() {
return (
<>
<z-action label='新增文章' mode='drawer' fields={["title","categoryId","type","content","commentable","pictures","author","from"]} url='/do/put/article' />
</>
)
},
action$({ row }) {
return (
<>
<z-action label='编辑' mode='drawer' fields={["title","categoryId","type","content","commentable","author","from","pictures"]} link data={row} url='/do/patch/article' title='编辑文章' />
<z-action label='删除' link data={row} url='/do/delete/article' title='确定删除该文章吗?' />
</>
)
}
}
}

View File

@@ -0,0 +1 @@
{"table":"article","blocks":[],"counter":6786,"basic":{"title":"文章列表","selectable":0,"showIndex":0,"compact":0,"size":"","url":"/do/select/article","actions":[{"label":"新增文章","mode":"drawer","type":"primary","title":null,"params":null,"width":null,"from":null,"actions":[],"_id":6787,"url":"/do/put/article","fields":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"categoryId","name":"categoryId","width":null,"rule":{},"block":null,"blockType":null},{"id":"type","name":"type","width":null,"rule":{},"block":null,"blockType":null},{"id":"content","name":"content","width":null,"rule":{},"block":null,"blockType":null},{"id":"commentable","name":"commentable","width":null,"rule":{},"block":null,"blockType":null},{"id":"pictures","name":"pictures","width":null,"rule":{},"block":null,"blockType":null},{"id":"author","name":"author","width":null,"rule":{},"block":null,"blockType":null},{"id":"from","name":"from","width":null,"rule":{},"block":null,"blockType":null}]}]},"columns":[{"id":"id","name":"id","width":null,"rule":{},"block":null,"blockType":null},{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"type","name":"type","width":null,"rule":{},"block":null,"blockType":null},{"id":"uid","name":"uid","width":null,"rule":{},"block":null,"blockType":null},{"id":"updateGmt","name":"updateGmt","width":null,"rule":{},"block":null,"blockType":null},{"id":"createGmt","name":"createGmt","width":null,"rule":{},"block":null,"blockType":null}],"tabs":{"code":"articleType","defaultVal":null,"list":[],"keyword":"type"},"condition":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"categoryId","name":"categoryId","width":null,"rule":{},"block":null,"blockType":null}],"conditionLimit":null,"actions":[{"label":"编辑","mode":"drawer","type":"text","title":"编辑文章","params":null,"width":null,"from":null,"actions":[],"_id":6788,"url":"/do/patch/article","fields":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"categoryId","name":"categoryId","width":null,"rule":{},"block":null,"blockType":null},{"id":"type","name":"type","width":null,"rule":{},"block":null,"blockType":null},{"id":"content","name":"content","width":null,"rule":{},"block":null,"blockType":null},{"id":"commentable","name":"commentable","width":null,"rule":{},"block":null,"blockType":null},{"id":"author","name":"author","width":null,"rule":{},"block":null,"blockType":null},{"id":"from","name":"from","width":null,"rule":{},"block":null,"blockType":null},{"id":"pictures","name":"pictures","width":null,"rule":{},"block":null,"blockType":null}]},{"label":"删除","mode":"confirm","type":"text","url":"/do/delete/article","params":["id"],"tip":"确定删除该文章吗?","_id":6789}],"_id":6789}

View File

@@ -0,0 +1,16 @@
<template>
<z-table name="6625cc33b7d97458478b8518" url="/do/select/article">
</z-table>
</template>
<script>
import configs from './.lowcode/configs';
export default {
name: 'page-list',
provide: { configs },
data() {
return {}
},
}
</script>

1
vue/src/pages/dict.json Normal file
View File

@@ -0,0 +1 @@
[{"key":"articleType","title":"文章类型","type":1,"content":[{"value":1,"label":"普通图文","color":"#C71585"},{"value":2,"label":"商品","color":"#D40001"}]},{"key":"pageType","title":"页面类型","type":1,"content":[{"value":1,"label":"PC端页面","color":"#F8D03F"},{"value":2,"label":"无线端页面","color":"#C36EB5"},{"value":3,"label":"跨端页面","color":"#8F6B43"}]},{"key":"pageStatus","title":"页面状态","type":1,"content":[{"value":1,"label":"待发布","color":"#666666"},{"value":2,"label":"已发布","color":"#559B7B"},{"value":3,"label":"已下线","color":"#D40001"}]}]

11
vue/src/pages/index.js Normal file
View File

@@ -0,0 +1,11 @@
import article from "./article/index";
import material from "./material/index";
import page from "./page/index";
import system from "./system/index";
export default {
...article,
...material,
...page,
...system,
};

View File

@@ -0,0 +1,4 @@
export default {
'material/picture': () => import( /* webpackChunkName: "pages/material/picture" */ "./picture/picture.vue"),
'material/video': () => import( /* webpackChunkName: "pages/material/video" */ "./video/video.vue")
};

View File

@@ -0,0 +1,88 @@
export default {
title: "图片中心",
entitys: [
{ name: "id", label: "编号" },
{ name: "name", type: "input", label: "名称" },
{ name: "nick", label: "昵称" },
{ name: "ukey", label: "密钥" },
{ name: "createUid", type: "input", label: "创建人" },
{
name: "status",
type: "switch",
label: "状态",
url: "/app/updateStatus.do",
},
{
name: "config",
type: "map",
default: {},
fields: [
{ name: "api", label: "接口地址", type: "input" },
{ name: "version", label: "资源版本", type: "input" },
],
},
],
columns: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
condtion: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
slots: {
header() {
return (
<>
<el-button>Default</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">测试</el-button>
<el-button type="warning">这里是按钮</el-button>
<el-button type="danger">Danger</el-button>
<z-action
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
url="/do/put/member"
label="添加"
title="hello"
/>
</>
);
},
action$({ row }) {
return (
<>
<z-action
link
mode="drawer"
title={row.nick + "侧滑菜单"}
label="侧滑"
/>
<z-action
link
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
data={row}
url="/do/patch/member"
title={"编辑" + row.nick}
label="编辑"
/>
<z-action
link
mode="confirm"
title="确定删除吗?"
data={row}
url="/do/delete/member"
label="删除"
/>
</>
);
},
},
};

View File

@@ -0,0 +1 @@
{"table":"picture","blocks":[],"counter":6786,"basic":{"title":"图片中心","selectable":0,"showIndex":0,"compact":0,"size":"","url":"/do/select/site","actions":[]},"columns":[],"tabs":{"code":null,"defaultVal":null,"list":[],"keyword":null},"condition":[],"conditionLimit":null,"actions":[],"_id":6786}

View File

@@ -0,0 +1,16 @@
<template>
<z-table name="6625cd28b7d97458478b8519" url="/do/select/picture" mocked>
</z-table>
</template>
<script>
import configs from './.lowcode/configs';
export default {
name: 'page-picture',
provide: { configs },
data() {
return {}
},
}
</script>

View File

@@ -0,0 +1,88 @@
export default {
title: "视频编辑器",
entitys: [
{ name: "id", label: "编号" },
{ name: "name", type: "input", label: "名称" },
{ name: "nick", label: "昵称" },
{ name: "ukey", label: "密钥" },
{ name: "createUid", type: "input", label: "创建人" },
{
name: "status",
type: "switch",
label: "状态",
url: "/app/updateStatus.do",
},
{
name: "config",
type: "map",
default: {},
fields: [
{ name: "api", label: "接口地址", type: "input" },
{ name: "version", label: "资源版本", type: "input" },
],
},
],
columns: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
condtion: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
slots: {
header() {
return (
<>
<el-button>Default</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">测试</el-button>
<el-button type="warning">这里是按钮</el-button>
<el-button type="danger">Danger</el-button>
<z-action
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
url="/do/put/member"
label="添加"
title="hello"
/>
</>
);
},
action$({ row }) {
return (
<>
<z-action
link
mode="drawer"
title={row.nick + "侧滑菜单"}
label="侧滑"
/>
<z-action
link
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
data={row}
url="/do/patch/member"
title={"编辑" + row.nick}
label="编辑"
/>
<z-action
link
mode="confirm"
title="确定删除吗?"
data={row}
url="/do/delete/member"
label="删除"
/>
</>
);
},
},
};

View File

@@ -0,0 +1 @@
{"table":"video","blocks":[],"counter":6786,"basic":{"title":"视频编辑器","selectable":0,"showIndex":0,"compact":0,"size":"","url":"/do/select/site","actions":[]},"columns":[],"tabs":{"code":null,"defaultVal":null,"list":[],"keyword":null},"condition":[],"conditionLimit":null,"actions":[],"_id":6786}

View File

@@ -0,0 +1,16 @@
<template>
<z-table name="6625cd8eb7d97458478b851a" url="/do/select/video" mocked>
</z-table>
</template>
<script>
import configs from './.lowcode/configs';
export default {
name: 'page-video',
provide: { configs },
data() {
return {}
},
}
</script>

View File

@@ -0,0 +1,26 @@
export default {
title: "活动页列表",
tabs: {"code":"pageStatus","list":[],"keyword":"status"},
entitys: [{"name":"id","label":"编号"},{"name":"title","label":"页面标题"},{"name":"path","label":"页面路径"},{"name":"type","label":"页面类型","code":"pageType"},{"name":"siteId","label":"所属站点"},{"name":"content","label":"描述内容"},{"name":"status","label":"页面状态","code":"pageStatus"},{"name":"createGmt","label":"创建时间","type":"date"},{"name":"updateGmt","label":"更新时间","type":"date"},{"name":"data","label":"页面数据"}],
columns: ["id","title","path","type","status"],
condition: ["title","type"],
slots: {
header$() {
return (
<>
<z-action label='新建活动页' mode='wicket' fields={["title","path","type","siteId"]} url='/do/put/activity' />
</>
)
},
action$({ row }) {
return (
<>
<z-action label='编辑' mode='wicket' fields={["title"]} link data={row} url='/do/patch/activity' />
<z-action label='装修' mode='link' href={`/design.html?id=${row.id}`} link data={row} />
<z-action label='删除' mode='confirm' link data={row} url='/do/delete/activity' title='确定删除吗?' />
</>
)
}
}
}

View File

@@ -0,0 +1 @@
{"table":"activity","blocks":[],"counter":6786,"basic":{"title":"活动页列表","selectable":0,"showIndex":0,"compact":0,"size":"","url":"/do/select/activity","actions":[{"label":"新建活动页","mode":"wicket","type":"primary","url":"/do/put/activity","name":"add","fields":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"path","name":"path","width":null,"rule":{},"block":null,"blockType":null},{"id":"type","name":"type","width":null,"rule":{},"block":null,"blockType":null},{"id":"siteId","name":"siteId","width":null,"rule":{},"block":null,"blockType":null}],"_id":6787}]},"columns":[{"id":"id","name":"id","width":null,"rule":{},"block":null,"blockType":null},{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"path","name":"path","width":null,"rule":{},"block":null,"blockType":null},{"id":"type","name":"type","width":null,"rule":{},"block":null,"blockType":null},{"id":"status","name":"status","width":null,"rule":{},"block":null,"blockType":null}],"tabs":{"code":"pageStatus","defaultVal":null,"list":[],"keyword":"status"},"condition":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"type","name":"type","width":null,"rule":{},"block":null,"blockType":null}],"conditionLimit":null,"actions":[{"label":"编辑","mode":"wicket","type":"text","url":"/do/patch/activity","name":"edit","fields":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null}],"_id":6788},{"label":"装修","mode":"link","type":"text","href":"/design.html","params":["id"],"_id":6789},{"label":"删除","mode":"confirm","type":"text","url":"/do/delete/activity","params":["id"],"tip":"确定删除吗?","_id":6790}],"_id":6790}

View File

@@ -0,0 +1,16 @@
<template>
<z-table name="6625cba8b7d97458478b8515" url="/do/select/activity">
</z-table>
</template>
<script>
import configs from './.lowcode/configs';
export default {
name: 'page-activity',
provide: { configs },
data() {
return {}
},
}
</script>

View File

@@ -0,0 +1,4 @@
export default {
'page/activity': () => import( /* webpackChunkName: "pages/page/activity" */ "./activity/activity.vue"),
'page/source': () => import( /* webpackChunkName: "pages/page/source" */ "./source/source.vue")
};

View File

@@ -0,0 +1,24 @@
export default {
title: "源码页面",
entitys: [{"name":"title","label":"页面标题"},{"name":"path","label":"页面路径"},{"name":"type","label":"平台类型","type":"number"},{"name":"siteId","label":"所属站点"},{"name":"content","label":"网站内容","type":"textarea"},{"name":"status","label":"状态","code":"pageStatus"},{"name":"templateId","label":"模版ID"},{"name":"id","label":"编号"},{"name":"createGmt","label":"创建时间","type":"date"},{"name":"updateGmt","label":"更新时间","type":"date"}],
columns: ["id","title","path","updateGmt","createGmt"],
condition: [],
slots: {
header$() {
return (
<>
<z-action label='创建页面' mode='wicket' fields={["title","path","content"]} url='/do/put/page' />
</>
)
},
action$({ row }) {
return (
<>
<z-action label='编辑' mode='wicket' fields={["title","content"]} from='/do/get/page' link data={row} url='/do/patch/page' />
<z-action label='删除' mode='confirm' link data={row} url='/do/delete/page' title='确定删除该页面吗?' />
</>
)
}
}
}

View File

@@ -0,0 +1 @@
{"table":"page","blocks":[],"counter":6786,"basic":{"title":"源码页面","selectable":0,"showIndex":0,"compact":0,"size":"","url":"/do/select/page","actions":[{"label":"创建页面","mode":"wicket","type":"primary","url":"/do/put/page","name":"add","fields":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"path","name":"path","width":null,"rule":{},"block":null,"blockType":null},{"id":"content","name":"content","width":null,"rule":{},"block":null,"blockType":null}],"_id":6787}]},"columns":[{"id":"id","name":"id","width":null,"rule":{},"block":null,"blockType":null},{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"path","name":"path","width":null,"rule":{},"block":null,"blockType":null},{"id":"updateGmt","name":"updateGmt","width":null,"rule":{},"block":null,"blockType":null},{"id":"createGmt","name":"createGmt","width":null,"rule":{},"block":null,"blockType":null}],"tabs":{"code":null,"defaultVal":null,"list":[],"keyword":null},"condition":[],"conditionLimit":null,"actions":[{"label":"编辑","mode":"wicket","type":"text","url":"/do/patch/page","name":"edit","fields":[{"id":"title","name":"title","width":null,"rule":{},"block":null,"blockType":null},{"id":"content","name":"content","width":null,"rule":{},"block":null,"blockType":null}],"_id":6788,"from":"/do/get/page"},{"label":"删除","mode":"confirm","type":"text","url":"/do/delete/page","params":["id"],"tip":"确定删除该页面吗?","_id":6789}],"_id":6789}

View File

@@ -0,0 +1,16 @@
<template>
<z-table name="6625cbbbb7d97458478b8516" url="/do/select/page">
</z-table>
</template>
<script>
import configs from './.lowcode/configs';
export default {
name: 'page-source',
provide: { configs },
data() {
return {}
},
}
</script>

18
vue/src/pages/routes.js Normal file
View File

@@ -0,0 +1,18 @@
import pages from "./index";
let routes = [{ path: "/", redirect: "/welcome" }];
let isExist;
Object.keys(pages).forEach((pagePath) => {
isExist = false;
for (let index = 0; index < routes.length; index++) {
const route = routes[index];
if (route.path === "/" + pagePath) {
isExist = true;
break;
}
}
if (!isExist) {
routes.push({ path: "/" + pagePath, component: pages[pagePath] });
}
});
export default routes;

View File

@@ -0,0 +1,88 @@
export default {
title: "组件管理",
entitys: [
{ name: "id", label: "编号" },
{ name: "name", type: "input", label: "名称" },
{ name: "nick", label: "昵称" },
{ name: "ukey", label: "密钥" },
{ name: "createUid", type: "input", label: "创建人" },
{
name: "status",
type: "switch",
label: "状态",
url: "/app/updateStatus.do",
},
{
name: "config",
type: "map",
default: {},
fields: [
{ name: "api", label: "接口地址", type: "input" },
{ name: "version", label: "资源版本", type: "input" },
],
},
],
columns: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
condtion: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
slots: {
header() {
return (
<>
<el-button>Default</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">测试</el-button>
<el-button type="warning">这里是按钮</el-button>
<el-button type="danger">Danger</el-button>
<z-action
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
url="/do/put/member"
label="添加"
title="hello"
/>
</>
);
},
action$({ row }) {
return (
<>
<z-action
link
mode="drawer"
title={row.nick + "侧滑菜单"}
label="侧滑"
/>
<z-action
link
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
data={row}
url="/do/patch/member"
title={"编辑" + row.nick}
label="编辑"
/>
<z-action
link
mode="confirm"
title="确定删除吗?"
data={row}
url="/do/delete/member"
label="删除"
/>
</>
);
},
},
};

View File

@@ -0,0 +1 @@
{"table":"components","blocks":[],"counter":6786,"basic":{"title":"组件管理","selectable":0,"showIndex":0,"compact":0,"size":"","url":"/do/select/site","actions":[]},"columns":[],"tabs":{"code":null,"defaultVal":null,"list":[],"keyword":null},"condition":[],"conditionLimit":null,"actions":[],"_id":6786}

View File

@@ -0,0 +1,16 @@
<template>
<z-table name="6625ce33b7d97458478b851b" url="/do/select/components" mocked>
</z-table>
</template>
<script>
import configs from './.lowcode/configs';
export default {
name: 'page-components',
provide: { configs },
data() {
return {}
},
}
</script>

View File

@@ -0,0 +1,88 @@
export default {
title: "环境配置",
entitys: [
{ name: "id", label: "编号" },
{ name: "name", type: "input", label: "名称" },
{ name: "nick", label: "昵称" },
{ name: "ukey", label: "密钥" },
{ name: "createUid", type: "input", label: "创建人" },
{
name: "status",
type: "switch",
label: "状态",
url: "/app/updateStatus.do",
},
{
name: "config",
type: "map",
default: {},
fields: [
{ name: "api", label: "接口地址", type: "input" },
{ name: "version", label: "资源版本", type: "input" },
],
},
],
columns: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
condtion: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
slots: {
header() {
return (
<>
<el-button>Default</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">测试</el-button>
<el-button type="warning">这里是按钮</el-button>
<el-button type="danger">Danger</el-button>
<z-action
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
url="/do/put/member"
label="添加"
title="hello"
/>
</>
);
},
action$({ row }) {
return (
<>
<z-action
link
mode="drawer"
title={row.nick + "侧滑菜单"}
label="侧滑"
/>
<z-action
link
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
data={row}
url="/do/patch/member"
title={"编辑" + row.nick}
label="编辑"
/>
<z-action
link
mode="confirm"
title="确定删除吗?"
data={row}
url="/do/delete/member"
label="删除"
/>
</>
);
},
},
};

View File

@@ -0,0 +1 @@
{"table":"env","blocks":[],"counter":6786,"basic":{"title":"环境配置","selectable":0,"showIndex":0,"compact":0,"size":"","url":"/do/select/site","actions":[]},"columns":[],"tabs":{"code":null,"defaultVal":null,"list":[],"keyword":null},"condition":[],"conditionLimit":null,"actions":[],"_id":6786}

16
vue/src/pages/system/env/env.vue vendored Normal file
View File

@@ -0,0 +1,16 @@
<template>
<z-table name="6625cf58b7d97458478b851c" url="/do/select/env" mocked>
</z-table>
</template>
<script>
import configs from './.lowcode/configs';
export default {
name: 'page-env',
provide: { configs },
data() {
return {}
},
}
</script>

View File

@@ -0,0 +1,5 @@
export default {
'system/components': () => import( /* webpackChunkName: "pages/system/components" */ "./components/components.vue"),
'system/env': () => import( /* webpackChunkName: "pages/system/env" */ "./env/env.vue"),
'system/site': () => import( /* webpackChunkName: "pages/system/site" */ "./site/site.vue")
};

View File

@@ -0,0 +1,88 @@
export default {
title: "站点管理",
entitys: [
{ name: "id", label: "编号" },
{ name: "name", type: "input", label: "名称" },
{ name: "nick", label: "昵称" },
{ name: "ukey", label: "密钥" },
{ name: "createUid", type: "input", label: "创建人" },
{
name: "status",
type: "switch",
label: "状态",
url: "/app/updateStatus.do",
},
{
name: "config",
type: "map",
default: {},
fields: [
{ name: "api", label: "接口地址", type: "input" },
{ name: "version", label: "资源版本", type: "input" },
],
},
],
columns: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
condtion: ["id", "createUid", "nick", "unionid", "dingId", "ukey"],
slots: {
header() {
return (
<>
<el-button>Default</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">测试</el-button>
<el-button type="warning">这里是按钮</el-button>
<el-button type="danger">Danger</el-button>
<z-action
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
url="/do/put/member"
label="添加"
title="hello"
/>
</>
);
},
action$({ row }) {
return (
<>
<z-action
link
mode="drawer"
title={row.nick + "侧滑菜单"}
label="侧滑"
/>
<z-action
link
fields={[
"id",
"createUid",
"nick",
"unionid",
"dingId",
"ukey",
]}
data={row}
url="/do/patch/member"
title={"编辑" + row.nick}
label="编辑"
/>
<z-action
link
mode="confirm"
title="确定删除吗?"
data={row}
url="/do/delete/member"
label="删除"
/>
</>
);
},
},
};

View File

@@ -0,0 +1 @@
{"table":"site","blocks":[],"counter":6786,"basic":{"title":"站点管理","selectable":0,"showIndex":0,"compact":0,"size":"","url":"/do/select/site","actions":[]},"columns":[],"tabs":{"code":null,"defaultVal":null,"list":[],"keyword":null},"condition":[],"conditionLimit":null,"actions":[],"_id":6786}

View File

@@ -0,0 +1,16 @@
<template>
<z-table name="6625cf7cb7d97458478b851d" url="/do/select/site" mocked>
</z-table>
</template>
<script>
import configs from './.lowcode/configs';
export default {
name: 'page-site',
provide: { configs },
data() {
return {}
},
}
</script>

156
vue/webpack.config.js Normal file
View File

@@ -0,0 +1,156 @@
const TerserPlugin = require("terser-webpack-plugin"),
{ VueLoaderPlugin } = require("vue-loader"),
path = require("path"),
fs = require("fs-extra");
// const ZenAppPlugin = require("@zen/app-plugin");
const MiddleWare = require("@zen/app-plugin/middleware");
function optimization(mode) {
if (mode === "production") {
return {
splitChunks: false,
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: undefined,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
// Deprecated
output: null,
format: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
}),
],
};
}
return {};
}
var webpackConfig = {
entry: {},
output: {
filename: "[name].js",
},
watchOptions: {
// , "**/*.json"
ignored: ["node_modules", "dist", "debug"],
poll: 300,
},
externals: {
vue: "Vue",
"router-view": "VueRouter",
"element-plus": "ElementPlus",
},
plugins: [new VueLoaderPlugin()],
resolve: {
alias: {
"@util": path.resolve(__dirname, "src/util"),
"@store": path.resolve(
__dirname,
"src/design/engine/store/index.js"
),
},
extensions: [".js", ".vue", ".jsx", ".json"],
},
module: {
noParse: /Vue|jquery/,
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
presets: [
[
"@vue/app",
{
modules: "commonjs",
loose: true,
useBuiltIns: "entry",
},
],
],
plugins: ["@babel/plugin-syntax-jsx"],
},
},
},
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader", // translates CSS into CommonJS
{
loader: "sass-loader",
options: {
implementation: require("sass"),
},
},
],
},
],
},
};
let basename,
file,
i,
len,
sourceList,
vuePath = path.resolve(__dirname);
sourceList = fs.readdirSync(path.resolve(vuePath, "src"));
for (i = 0, len = sourceList.length; i < len; i++) {
file = sourceList[i];
if (file.indexOf(".js") === -1) {
continue;
}
basename = path.basename(file);
basename = basename.substr(0, basename.length - 3);
webpackConfig.entry[basename] = path.resolve(vuePath, "src", file);
}
module.exports = (env, argv) => {
let mode = argv.mode;
webpackConfig.mode = mode;
webpackConfig.optimization = optimization(mode);
if (mode === "development") {
webpackConfig.cache = { type: "memory" };
webpackConfig.devServer = {
open: true,
hot: false,
client: false,
host: "127.0.0.1",
allowedHosts: "all",
onAfterSetupMiddleware: MiddleWare,
static: {
directory: path.join(vuePath, "public"),
},
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
},
};
// webpackConfig.plugins.push(new ZenAppPlugin());
} else {
webpackConfig.output.clean = true;
webpackConfig.output.path = path.join(vuePath, "dist");
}
return webpackConfig;
};