're_infra'
This commit is contained in:
parent
e75d2f1810
commit
ee828ec4a7
20
src/api/infra/apiAccessLog.js
Normal file
20
src/api/infra/apiAccessLog.js
Normal file
@ -0,0 +1,20 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获得API 访问日志分页
|
||||
export function getApiAccessLogPage(query) {
|
||||
return request({
|
||||
url: '/infra/api-access-log/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导出API 访问日志 Excel
|
||||
export function exportApiAccessLogExcel(query) {
|
||||
return request({
|
||||
url: '/infra/api-access-log/export-excel',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
28
src/api/infra/apiErrorLog.js
Normal file
28
src/api/infra/apiErrorLog.js
Normal file
@ -0,0 +1,28 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 更新 API 错误日志的处理状态
|
||||
export function updateApiErrorLogProcess(id, processStatus) {
|
||||
return request({
|
||||
url: '/infra/api-error-log/update-status?id=' + id + '&processStatus=' + processStatus,
|
||||
method: 'put',
|
||||
})
|
||||
}
|
||||
|
||||
// 获得API 错误日志分页
|
||||
export function getApiErrorLogPage(query) {
|
||||
return request({
|
||||
url: '/infra/api-error-log/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导出API 错误日志 Excel
|
||||
export function exportApiErrorLogExcel(query) {
|
||||
return request({
|
||||
url: '/infra/api-error-log/export-excel',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
90
src/api/infra/codegen.js
Normal file
90
src/api/infra/codegen.js
Normal file
@ -0,0 +1,90 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获得表定义分页
|
||||
export function getCodegenTablePage(query) {
|
||||
return request({
|
||||
url: '/infra/codegen/table/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 获得表和字段的明细
|
||||
export function getCodegenDetail(tableId) {
|
||||
return request({
|
||||
url: '/infra/codegen/detail?tableId=' + tableId,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 修改代码生成信息
|
||||
export function updateCodegen(data) {
|
||||
return request({
|
||||
url: '/infra/codegen/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 基于数据库的表结构,同步数据库的表和字段定义
|
||||
export function syncCodegenFromDB(tableId) {
|
||||
return request({
|
||||
url: '/infra/codegen/sync-from-db?tableId=' + tableId,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 基于 SQL 建表语句,同步数据库的表和字段定义
|
||||
export function syncCodegenFromSQL(tableId, sql) {
|
||||
return request({
|
||||
url: '/infra/codegen/sync-from-sql?tableId=' + tableId,
|
||||
method: 'put',
|
||||
headers:{
|
||||
'Content-type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
data: 'tableId=' + tableId + "&sql=" + sql,
|
||||
})
|
||||
}
|
||||
|
||||
// 预览生成代码
|
||||
export function previewCodegen(tableId) {
|
||||
return request({
|
||||
url: '/infra/codegen/preview?tableId=' + tableId,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 下载生成代码
|
||||
export function downloadCodegen(tableId) {
|
||||
return request({
|
||||
url: '/infra/codegen/download?tableId=' + tableId,
|
||||
method: 'get',
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得表定义分页
|
||||
export function getSchemaTableList(query) {
|
||||
return request({
|
||||
url: '/infra/codegen/db/table/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 基于数据库的表结构,创建代码生成器的表定义
|
||||
export function createCodegenList(data) {
|
||||
return request({
|
||||
url: '/infra/codegen/create-list',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除数据库的表和字段定义
|
||||
export function deleteCodegen(tableId) {
|
||||
return request({
|
||||
url: '/infra/codegen/delete?tableId=' + tableId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
62
src/api/infra/config.js
Normal file
62
src/api/infra/config.js
Normal file
@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询参数列表
|
||||
export function listConfig(query) {
|
||||
return request({
|
||||
url: '/infra/config/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询参数详细
|
||||
export function getConfig(configId) {
|
||||
return request({
|
||||
url: '/infra/config/get?id=' + configId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 根据参数键名查询参数值
|
||||
export function getConfigKey(configKey) {
|
||||
return request({
|
||||
url: '/infra/config/get-value-by-key?key=' + configKey,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增参数配置
|
||||
export function addConfig(data) {
|
||||
return request({
|
||||
url: '/infra/config/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改参数配置
|
||||
export function updateConfig(data) {
|
||||
return request({
|
||||
url: '/infra/config/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除参数配置
|
||||
export function delConfig(configId) {
|
||||
return request({
|
||||
url: '/infra/config/delete?id=' + configId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出参数
|
||||
export function exportConfig(query) {
|
||||
return request({
|
||||
url: '/infra/config/export',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
43
src/api/infra/dataSourceConfig.js
Normal file
43
src/api/infra/dataSourceConfig.js
Normal file
@ -0,0 +1,43 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 创建数据源配置
|
||||
export function createDataSourceConfig(data) {
|
||||
return request({
|
||||
url: '/infra/data-source-config/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新数据源配置
|
||||
export function updateDataSourceConfig(data) {
|
||||
return request({
|
||||
url: '/infra/data-source-config/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除数据源配置
|
||||
export function deleteDataSourceConfig(id) {
|
||||
return request({
|
||||
url: '/infra/data-source-config/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得数据源配置
|
||||
export function getDataSourceConfig(id) {
|
||||
return request({
|
||||
url: '/infra/data-source-config/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得数据源配置列表
|
||||
export function getDataSourceConfigList() {
|
||||
return request({
|
||||
url: '/infra/data-source-config/list',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
26
src/api/infra/dbDoc.js
Normal file
26
src/api/infra/dbDoc.js
Normal file
@ -0,0 +1,26 @@
|
||||
// 导出参数
|
||||
import request from "@/utils/request";
|
||||
|
||||
export function exportHtml() {
|
||||
return request({
|
||||
url: '/infra/db-doc/export-html',
|
||||
method: 'get',
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
export function exportWord() {
|
||||
return request({
|
||||
url: '/infra/db-doc/export-word',
|
||||
method: 'get',
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
export function exportMarkdown() {
|
||||
return request({
|
||||
url: '/infra/db-doc/export-markdown',
|
||||
method: 'get',
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
18
src/api/infra/file.js
Normal file
18
src/api/infra/file.js
Normal file
@ -0,0 +1,18 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 删除文件
|
||||
export function deleteFile(id) {
|
||||
return request({
|
||||
url: '/infra/file/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得文件分页
|
||||
export function getFilePage(query) {
|
||||
return request({
|
||||
url: '/infra/file/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
59
src/api/infra/fileConfig.js
Normal file
59
src/api/infra/fileConfig.js
Normal file
@ -0,0 +1,59 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 创建文件配置
|
||||
export function createFileConfig(data) {
|
||||
return request({
|
||||
url: '/infra/file-config/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新文件配置
|
||||
export function updateFileConfig(data) {
|
||||
return request({
|
||||
url: '/infra/file-config/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新文件配置为主配置
|
||||
export function updateFileConfigMaster(id) {
|
||||
return request({
|
||||
url: '/infra/file-config/update-master?id=' + id,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 删除文件配置
|
||||
export function deleteFileConfig(id) {
|
||||
return request({
|
||||
url: '/infra/file-config/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得文件配置
|
||||
export function getFileConfig(id) {
|
||||
return request({
|
||||
url: '/infra/file-config/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得文件配置分页
|
||||
export function getFileConfigPage(query) {
|
||||
return request({
|
||||
url: '/infra/file-config/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function testFileConfig(id) {
|
||||
return request({
|
||||
url: '/infra/file-config/test?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
82
src/api/infra/job.js
Normal file
82
src/api/infra/job.js
Normal file
@ -0,0 +1,82 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询定时任务调度列表
|
||||
export function listJob(query) {
|
||||
return request({
|
||||
url: '/infra/job/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询定时任务调度详细
|
||||
export function getJob(jobId) {
|
||||
return request({
|
||||
url: '/infra/job/get?id=' + jobId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增定时任务调度
|
||||
export function addJob(data) {
|
||||
return request({
|
||||
url: '/infra/job/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改定时任务调度
|
||||
export function updateJob(data) {
|
||||
return request({
|
||||
url: '/infra/job/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除定时任务调度
|
||||
export function delJob(jobId) {
|
||||
return request({
|
||||
url: '/infra/job/delete?id=' + jobId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出定时任务调度
|
||||
export function exportJob(query) {
|
||||
return request({
|
||||
url: '/infra/job/export-excel',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// 任务状态修改
|
||||
export function updateJobStatus(jobId, status) {
|
||||
return request({
|
||||
url: '/infra/job/update-status',
|
||||
method: 'put',
|
||||
headers:{
|
||||
'Content-type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
data: 'id=' + jobId + "&status=" + status,
|
||||
})
|
||||
}
|
||||
|
||||
// 定时任务立即执行一次
|
||||
export function runJob(jobId) {
|
||||
return request({
|
||||
url: '/infra/job/trigger?id=' + jobId,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得定时任务的下 n 次执行时间
|
||||
export function getJobNextTimes(jobId) {
|
||||
return request({
|
||||
url: '/infra/job/get_next_times?id=' + jobId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
28
src/api/infra/jobLog.js
Normal file
28
src/api/infra/jobLog.js
Normal file
@ -0,0 +1,28 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获得定时任务
|
||||
export function getJobLog(id) {
|
||||
return request({
|
||||
url: '/infra/job-log/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得定时任务分页
|
||||
export function getJobLogPage(query) {
|
||||
return request({
|
||||
url: '/infra/job-log/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导出定时任务 Excel
|
||||
export function exportJobLogExcel(query) {
|
||||
return request({
|
||||
url: '/infra/job-log/export-excel',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
9
src/api/infra/redis.js
Normal file
9
src/api/infra/redis.js
Normal file
@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询缓存详细
|
||||
export function getCache() {
|
||||
return request({
|
||||
url: '/infra/redis/get-monitor-info',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
54
src/api/infra/testDemo.js
Normal file
54
src/api/infra/testDemo.js
Normal file
@ -0,0 +1,54 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 创建字典类型
|
||||
export function createTestDemo(data) {
|
||||
return request({
|
||||
url: '/infra/test-demo/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新字典类型
|
||||
export function updateTestDemo(data) {
|
||||
return request({
|
||||
url: '/infra/test-demo/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除字典类型
|
||||
export function deleteTestDemo(id) {
|
||||
return request({
|
||||
url: '/infra/test-demo/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得字典类型
|
||||
export function getTestDemo(id) {
|
||||
return request({
|
||||
url: '/infra/test-demo/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得字典类型分页
|
||||
export function getTestDemoPage(query) {
|
||||
return request({
|
||||
url: '/infra/test-demo/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导出字典类型 Excel
|
||||
export function exportTestDemoExcel(query) {
|
||||
return request({
|
||||
url: '/infra/test-demo/export-excel',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
160
src/components/Crontab/day.vue
Normal file
160
src/components/Crontab/day.vue
Normal file
@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<el-form size="small">
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
日,允许的通配符[, - * ? / L W]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
不指定
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="1" :max="30" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="31" /> 日
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="1" :max="30" /> 号开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="31 - average01 || 1" /> 日执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="5">
|
||||
每月
|
||||
<el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="6">
|
||||
本月最后一天
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="7">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||
<el-option v-for="item in 31" :key="item" :value="item">{{item}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
radioValue: 1,
|
||||
workday: 1,
|
||||
cycle01: 1,
|
||||
cycle02: 2,
|
||||
average01: 1,
|
||||
average02: 1,
|
||||
checkboxList: [],
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-day',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
('day rachange');
|
||||
if (this.radioValue !== 2 && this.cron.week !== '?') {
|
||||
this.$emit('update', 'week', '?', 'day')
|
||||
}
|
||||
|
||||
switch (this.radioValue) {
|
||||
case 1:
|
||||
this.$emit('update', 'day', '*');
|
||||
break;
|
||||
case 2:
|
||||
this.$emit('update', 'day', '?');
|
||||
break;
|
||||
case 3:
|
||||
this.$emit('update', 'day', this.cycleTotal);
|
||||
break;
|
||||
case 4:
|
||||
this.$emit('update', 'day', this.averageTotal);
|
||||
break;
|
||||
case 5:
|
||||
this.$emit('update', 'day', this.workday + 'W');
|
||||
break;
|
||||
case 6:
|
||||
this.$emit('update', 'day', 'L');
|
||||
break;
|
||||
case 7:
|
||||
this.$emit('update', 'day', this.checkboxString);
|
||||
break;
|
||||
}
|
||||
('day rachange end');
|
||||
},
|
||||
// 周期两个值变化时
|
||||
cycleChange() {
|
||||
if (this.radioValue === '3') {
|
||||
this.$emit('update', 'day', this.cycleTotal);
|
||||
}
|
||||
},
|
||||
// 平均两个值变化时
|
||||
averageChange() {
|
||||
if (this.radioValue === '4') {
|
||||
this.$emit('update', 'day', this.averageTotal);
|
||||
}
|
||||
},
|
||||
// 最近工作日值变化时
|
||||
workdayChange() {
|
||||
if (this.radioValue === '5') {
|
||||
this.$emit('update', 'day', this.workdayCheck + 'W');
|
||||
}
|
||||
},
|
||||
// checkbox值变化时
|
||||
checkboxChange() {
|
||||
if (this.radioValue === '7') {
|
||||
this.$emit('update', 'day', this.checkboxString);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'radioValue': 'radioChange',
|
||||
'cycleTotal': 'cycleChange',
|
||||
'averageTotal': 'averageChange',
|
||||
'workdayCheck': 'workdayChange',
|
||||
'checkboxString': 'checkboxChange',
|
||||
},
|
||||
computed: {
|
||||
// 计算两个周期值
|
||||
cycleTotal: function () {
|
||||
const cycle01 = this.checkNum(this.cycle01, 1, 30)
|
||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 31, 31)
|
||||
return cycle01 + '-' + cycle02;
|
||||
},
|
||||
// 计算平均用到的值
|
||||
averageTotal: function () {
|
||||
const average01 = this.checkNum(this.average01, 1, 30)
|
||||
const average02 = this.checkNum(this.average02, 1, 31 - average01 || 0)
|
||||
return average01 + '/' + average02;
|
||||
},
|
||||
// 计算工作日格式
|
||||
workdayCheck: function () {
|
||||
return this.checkNum(this.workday, 1, 31);
|
||||
},
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str === '' ? '*' : str;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
114
src/components/Crontab/hour.vue
Normal file
114
src/components/Crontab/hour.vue
Normal file
@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<el-form size="small">
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
小时,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="0" :max="22" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> 小时
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="0" :max="22" /> 小时开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="23 - average01 || 0" /> 小时执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||
<el-option v-for="item in 24" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
radioValue: 1,
|
||||
cycle01: 0,
|
||||
cycle02: 1,
|
||||
average01: 0,
|
||||
average02: 1,
|
||||
checkboxList: [],
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-hour',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
switch (this.radioValue) {
|
||||
case 1:
|
||||
this.$emit('update', 'hour', '*')
|
||||
break;
|
||||
case 2:
|
||||
this.$emit('update', 'hour', this.cycleTotal);
|
||||
break;
|
||||
case 3:
|
||||
this.$emit('update', 'hour', this.averageTotal);
|
||||
break;
|
||||
case 4:
|
||||
this.$emit('update', 'hour', this.checkboxString);
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 周期两个值变化时
|
||||
cycleChange() {
|
||||
if (this.radioValue === '2') {
|
||||
this.$emit('update', 'hour', this.cycleTotal);
|
||||
}
|
||||
},
|
||||
// 平均两个值变化时
|
||||
averageChange() {
|
||||
if (this.radioValue === '3') {
|
||||
this.$emit('update', 'hour', this.averageTotal);
|
||||
}
|
||||
},
|
||||
// checkbox值变化时
|
||||
checkboxChange() {
|
||||
if (this.radioValue === '4') {
|
||||
this.$emit('update', 'hour', this.checkboxString);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'radioValue': 'radioChange',
|
||||
'cycleTotal': 'cycleChange',
|
||||
'averageTotal': 'averageChange',
|
||||
'checkboxString': 'checkboxChange'
|
||||
},
|
||||
computed: {
|
||||
// 计算两个周期值
|
||||
cycleTotal: function () {
|
||||
const cycle01 = this.checkNum(this.cycle01, 0, 22)
|
||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23)
|
||||
return cycle01 + '-' + cycle02;
|
||||
},
|
||||
// 计算平均用到的值
|
||||
averageTotal: function () {
|
||||
const average01 = this.checkNum(this.average01, 0, 22)
|
||||
const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0)
|
||||
return average01 + '/' + average02;
|
||||
},
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str === '' ? '*' : str;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
430
src/components/Crontab/index.vue
Normal file
430
src/components/Crontab/index.vue
Normal file
@ -0,0 +1,430 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="秒" v-if="shouldHide('second')">
|
||||
<CrontabSecond
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronsecond"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="分钟" v-if="shouldHide('min')">
|
||||
<CrontabMin
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronmin"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="小时" v-if="shouldHide('hour')">
|
||||
<CrontabHour
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronhour"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="日" v-if="shouldHide('day')">
|
||||
<CrontabDay
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronday"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="月" v-if="shouldHide('month')">
|
||||
<CrontabMonth
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronmonth"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="周" v-if="shouldHide('week')">
|
||||
<CrontabWeek
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronweek"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="年" v-if="shouldHide('year')">
|
||||
<CrontabYear
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronyear"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="popup-main">
|
||||
<div class="popup-result">
|
||||
<p class="title">时间表达式</p>
|
||||
<table>
|
||||
<thead>
|
||||
<th v-for="item of tabTitles" width="40" :key="item">{{item}}</th>
|
||||
<th>Cron 表达式</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<td>
|
||||
<span>{{crontabValueObj.second}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{crontabValueObj.min}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{crontabValueObj.hour}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{crontabValueObj.day}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{crontabValueObj.month}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{crontabValueObj.week}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{crontabValueObj.year}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{crontabValueString}}</span>
|
||||
</td>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<CrontabResult :ex="crontabValueString"></CrontabResult>
|
||||
|
||||
<div class="pop_btn">
|
||||
<el-button size="small" type="primary" @click="submitFill">确定</el-button>
|
||||
<el-button size="small" type="warning" @click="clearCron">重置</el-button>
|
||||
<el-button size="small" @click="hidePopup">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CrontabSecond from "./second.vue";
|
||||
import CrontabMin from "./min.vue";
|
||||
import CrontabHour from "./hour.vue";
|
||||
import CrontabDay from "./day.vue";
|
||||
import CrontabMonth from "./month.vue";
|
||||
import CrontabWeek from "./week.vue";
|
||||
import CrontabYear from "./year.vue";
|
||||
import CrontabResult from "./result.vue";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
|
||||
tabActive: 0,
|
||||
myindex: 0,
|
||||
crontabValueObj: {
|
||||
second: "*",
|
||||
min: "*",
|
||||
hour: "*",
|
||||
day: "*",
|
||||
month: "*",
|
||||
week: "?",
|
||||
year: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
name: "vcrontab",
|
||||
props: ["expression", "hideComponent"],
|
||||
methods: {
|
||||
shouldHide(key) {
|
||||
return !(this.hideComponent && this.hideComponent.includes(key));
|
||||
|
||||
},
|
||||
resolveExp() {
|
||||
// 反解析 表达式
|
||||
if (this.expression) {
|
||||
let arr = this.expression.split(" ");
|
||||
if (arr.length >= 6) {
|
||||
//6 位以上是合法表达式
|
||||
let obj = {
|
||||
second: arr[0],
|
||||
min: arr[1],
|
||||
hour: arr[2],
|
||||
day: arr[3],
|
||||
month: arr[4],
|
||||
week: arr[5],
|
||||
year: arr[6] ? arr[6] : "",
|
||||
};
|
||||
this.crontabValueObj = {
|
||||
...obj,
|
||||
};
|
||||
for (let i in obj) {
|
||||
if (obj[i]) this.changeRadio(i, obj[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 没有传入的表达式 则还原
|
||||
this.clearCron();
|
||||
}
|
||||
},
|
||||
// tab切换值
|
||||
tabCheck(index) {
|
||||
this.tabActive = index;
|
||||
},
|
||||
// 由子组件触发,更改表达式组成的字段值
|
||||
updateCrontabValue(name, value, from) {
|
||||
"updateCrontabValue", name, value, from;
|
||||
this.crontabValueObj[name] = value;
|
||||
if (from && from !== name) {
|
||||
console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
|
||||
this.changeRadio(name, value);
|
||||
}
|
||||
},
|
||||
// 赋值到组件
|
||||
changeRadio(name, value) {
|
||||
let arr = ["second", "min", "hour", "month"],
|
||||
refName = "cron" + name,
|
||||
insValue;
|
||||
|
||||
if (!this.$refs[refName]) return;
|
||||
|
||||
if (arr.includes(name)) {
|
||||
if (value === "*") {
|
||||
insValue = 1;
|
||||
} else if (value.indexOf("-") > -1) {
|
||||
let indexArr = value.split("-");
|
||||
isNaN(indexArr[0])
|
||||
? (this.$refs[refName].cycle01 = 0)
|
||||
: (this.$refs[refName].cycle01 = indexArr[0]);
|
||||
this.$refs[refName].cycle02 = indexArr[1];
|
||||
insValue = 2;
|
||||
} else if (value.indexOf("/") > -1) {
|
||||
let indexArr = value.split("/");
|
||||
isNaN(indexArr[0])
|
||||
? (this.$refs[refName].average01 = 0)
|
||||
: (this.$refs[refName].average01 = indexArr[0]);
|
||||
this.$refs[refName].average02 = indexArr[1];
|
||||
insValue = 3;
|
||||
} else {
|
||||
insValue = 4;
|
||||
this.$refs[refName].checkboxList = value.split(",");
|
||||
}
|
||||
} else if (name === "day") {
|
||||
if (value === "*") {
|
||||
insValue = 1;
|
||||
} else if (value === "?") {
|
||||
insValue = 2;
|
||||
} else if (value.indexOf("-") > -1) {
|
||||
let indexArr = value.split("-");
|
||||
isNaN(indexArr[0])
|
||||
? (this.$refs[refName].cycle01 = 0)
|
||||
: (this.$refs[refName].cycle01 = indexArr[0]);
|
||||
this.$refs[refName].cycle02 = indexArr[1];
|
||||
insValue = 3;
|
||||
} else if (value.indexOf("/") > -1) {
|
||||
let indexArr = value.split("/");
|
||||
isNaN(indexArr[0])
|
||||
? (this.$refs[refName].average01 = 0)
|
||||
: (this.$refs[refName].average01 = indexArr[0]);
|
||||
this.$refs[refName].average02 = indexArr[1];
|
||||
insValue = 4;
|
||||
} else if (value.indexOf("W") > -1) {
|
||||
let indexArr = value.split("W");
|
||||
isNaN(indexArr[0])
|
||||
? (this.$refs[refName].workday = 0)
|
||||
: (this.$refs[refName].workday = indexArr[0]);
|
||||
insValue = 5;
|
||||
} else if (value === "L") {
|
||||
insValue = 6;
|
||||
} else {
|
||||
this.$refs[refName].checkboxList = value.split(",");
|
||||
insValue = 7;
|
||||
}
|
||||
} else if (name === "week") {
|
||||
if (value === "*") {
|
||||
insValue = 1;
|
||||
} else if (value === "?") {
|
||||
insValue = 2;
|
||||
} else if (value.indexOf("-") > -1) {
|
||||
let indexArr = value.split("-");
|
||||
isNaN(indexArr[0])
|
||||
? (this.$refs[refName].cycle01 = 0)
|
||||
: (this.$refs[refName].cycle01 = indexArr[0]);
|
||||
this.$refs[refName].cycle02 = indexArr[1];
|
||||
insValue = 3;
|
||||
} else if (value.indexOf("#") > -1) {
|
||||
let indexArr = value.split("#");
|
||||
isNaN(indexArr[0])
|
||||
? (this.$refs[refName].average01 = 1)
|
||||
: (this.$refs[refName].average01 = indexArr[0]);
|
||||
this.$refs[refName].average02 = indexArr[1];
|
||||
insValue = 4;
|
||||
} else if (value.indexOf("L") > -1) {
|
||||
let indexArr = value.split("L");
|
||||
isNaN(indexArr[0])
|
||||
? (this.$refs[refName].weekday = 1)
|
||||
: (this.$refs[refName].weekday = indexArr[0]);
|
||||
insValue = 5;
|
||||
} else {
|
||||
this.$refs[refName].checkboxList = value.split(",");
|
||||
insValue = 6;
|
||||
}
|
||||
} else if (name === "year") {
|
||||
if (value === "") {
|
||||
insValue = 1;
|
||||
} else if (value === "*") {
|
||||
insValue = 2;
|
||||
} else if (value.indexOf("-") > -1) {
|
||||
insValue = 3;
|
||||
} else if (value.indexOf("/") > -1) {
|
||||
insValue = 4;
|
||||
} else {
|
||||
this.$refs[refName].checkboxList = value.split(",");
|
||||
insValue = 5;
|
||||
}
|
||||
}
|
||||
this.$refs[refName].radioValue = insValue;
|
||||
},
|
||||
// 表单选项的子组件校验数字格式(通过-props传递)
|
||||
checkNumber(value, minLimit, maxLimit) {
|
||||
// 检查必须为整数
|
||||
value = Math.floor(value);
|
||||
if (value < minLimit) {
|
||||
value = minLimit;
|
||||
} else if (value > maxLimit) {
|
||||
value = maxLimit;
|
||||
}
|
||||
return value;
|
||||
},
|
||||
// 隐藏弹窗
|
||||
hidePopup() {
|
||||
this.$emit("hide");
|
||||
},
|
||||
// 填充表达式
|
||||
submitFill() {
|
||||
this.$emit("fill", this.crontabValueString);
|
||||
this.hidePopup();
|
||||
},
|
||||
clearCron() {
|
||||
// 还原选择项
|
||||
("准备还原");
|
||||
this.crontabValueObj = {
|
||||
second: "*",
|
||||
min: "*",
|
||||
hour: "*",
|
||||
day: "*",
|
||||
month: "*",
|
||||
week: "?",
|
||||
year: "",
|
||||
};
|
||||
for (let j in this.crontabValueObj) {
|
||||
this.changeRadio(j, this.crontabValueObj[j]);
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
crontabValueString: function() {
|
||||
let obj = this.crontabValueObj;
|
||||
let str =
|
||||
obj.second +
|
||||
" " +
|
||||
obj.min +
|
||||
" " +
|
||||
obj.hour +
|
||||
" " +
|
||||
obj.day +
|
||||
" " +
|
||||
obj.month +
|
||||
" " +
|
||||
obj.week +
|
||||
(obj.year === "" ? "" : " " + obj.year);
|
||||
return str;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
CrontabSecond,
|
||||
CrontabMin,
|
||||
CrontabHour,
|
||||
CrontabDay,
|
||||
CrontabMonth,
|
||||
CrontabWeek,
|
||||
CrontabYear,
|
||||
CrontabResult,
|
||||
},
|
||||
watch: {
|
||||
expression: "resolveExp",
|
||||
hideComponent(value) {
|
||||
// 隐藏部分组件
|
||||
},
|
||||
},
|
||||
mounted: function() {
|
||||
this.resolveExp();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.pop_btn {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.popup-main {
|
||||
position: relative;
|
||||
margin: 10px auto;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.popup-title {
|
||||
overflow: hidden;
|
||||
line-height: 34px;
|
||||
padding-top: 6px;
|
||||
background: #f2f2f2;
|
||||
}
|
||||
.popup-result {
|
||||
box-sizing: border-box;
|
||||
line-height: 24px;
|
||||
margin: 25px auto;
|
||||
padding: 15px 10px 10px;
|
||||
border: 1px solid #ccc;
|
||||
position: relative;
|
||||
}
|
||||
.popup-result .title {
|
||||
position: absolute;
|
||||
top: -28px;
|
||||
left: 50%;
|
||||
width: 140px;
|
||||
font-size: 14px;
|
||||
margin-left: -70px;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
background: #fff;
|
||||
}
|
||||
.popup-result table {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.popup-result table span {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-family: arial;
|
||||
line-height: 30px;
|
||||
height: 30px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e8e8e8;
|
||||
}
|
||||
.popup-result-scroll {
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
height: 10em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
116
src/components/Crontab/min.vue
Normal file
116
src/components/Crontab/min.vue
Normal file
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<el-form size="small">
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
分钟,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="0" :max="58" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 分钟
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 分钟执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
radioValue: 1,
|
||||
cycle01: 1,
|
||||
cycle02: 2,
|
||||
average01: 0,
|
||||
average02: 1,
|
||||
checkboxList: [],
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-min',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
switch (this.radioValue) {
|
||||
case 1:
|
||||
this.$emit('update', 'min', '*', 'min');
|
||||
break;
|
||||
case 2:
|
||||
this.$emit('update', 'min', this.cycleTotal, 'min');
|
||||
break;
|
||||
case 3:
|
||||
this.$emit('update', 'min', this.averageTotal, 'min');
|
||||
break;
|
||||
case 4:
|
||||
this.$emit('update', 'min', this.checkboxString, 'min');
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 周期两个值变化时
|
||||
cycleChange() {
|
||||
if (this.radioValue === '2') {
|
||||
this.$emit('update', 'min', this.cycleTotal, 'min');
|
||||
}
|
||||
},
|
||||
// 平均两个值变化时
|
||||
averageChange() {
|
||||
if (this.radioValue === '3') {
|
||||
this.$emit('update', 'min', this.averageTotal, 'min');
|
||||
}
|
||||
},
|
||||
// checkbox值变化时
|
||||
checkboxChange() {
|
||||
if (this.radioValue === '4') {
|
||||
this.$emit('update', 'min', this.checkboxString, 'min');
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
watch: {
|
||||
'radioValue': 'radioChange',
|
||||
'cycleTotal': 'cycleChange',
|
||||
'averageTotal': 'averageChange',
|
||||
'checkboxString': 'checkboxChange',
|
||||
},
|
||||
computed: {
|
||||
// 计算两个周期值
|
||||
cycleTotal: function () {
|
||||
const cycle01 = this.checkNum(this.cycle01, 0, 58)
|
||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
|
||||
return cycle01 + '-' + cycle02;
|
||||
},
|
||||
// 计算平均用到的值
|
||||
averageTotal: function () {
|
||||
const average01 = this.checkNum(this.average01, 0, 58)
|
||||
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
|
||||
return average01 + '/' + average02;
|
||||
},
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str === '' ? '*' : str;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
114
src/components/Crontab/month.vue
Normal file
114
src/components/Crontab/month.vue
Normal file
@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<el-form size='small'>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
月,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="1" :max="11" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="12" /> 月
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="1" :max="11" /> 月开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="12 - average01 || 0" /> 月月执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||
<el-option v-for="item in 12" :key="item" :value="item">{{item}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
radioValue: 1,
|
||||
cycle01: 1,
|
||||
cycle02: 2,
|
||||
average01: 1,
|
||||
average02: 1,
|
||||
checkboxList: [],
|
||||
checkNum: this.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-month',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
switch (this.radioValue) {
|
||||
case 1:
|
||||
this.$emit('update', 'month', '*');
|
||||
break;
|
||||
case 2:
|
||||
this.$emit('update', 'month', this.cycleTotal);
|
||||
break;
|
||||
case 3:
|
||||
this.$emit('update', 'month', this.averageTotal);
|
||||
break;
|
||||
case 4:
|
||||
this.$emit('update', 'month', this.checkboxString);
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 周期两个值变化时
|
||||
cycleChange() {
|
||||
if (this.radioValue === '2') {
|
||||
this.$emit('update', 'month', this.cycleTotal);
|
||||
}
|
||||
},
|
||||
// 平均两个值变化时
|
||||
averageChange() {
|
||||
if (this.radioValue === '3') {
|
||||
this.$emit('update', 'month', this.averageTotal);
|
||||
}
|
||||
},
|
||||
// checkbox值变化时
|
||||
checkboxChange() {
|
||||
if (this.radioValue === '4') {
|
||||
this.$emit('update', 'month', this.checkboxString);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'radioValue': 'radioChange',
|
||||
'cycleTotal': 'cycleChange',
|
||||
'averageTotal': 'averageChange',
|
||||
'checkboxString': 'checkboxChange'
|
||||
},
|
||||
computed: {
|
||||
// 计算两个周期值
|
||||
cycleTotal: function () {
|
||||
const cycle01 = this.checkNum(this.cycle01, 1, 11)
|
||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 12)
|
||||
return cycle01 + '-' + cycle02;
|
||||
},
|
||||
// 计算平均用到的值
|
||||
averageTotal: function () {
|
||||
const average01 = this.checkNum(this.average01, 1, 11)
|
||||
const average02 = this.checkNum(this.average02, 1, 12 - average01 || 0)
|
||||
return average01 + '/' + average02;
|
||||
},
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str === '' ? '*' : str;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
559
src/components/Crontab/result.vue
Normal file
559
src/components/Crontab/result.vue
Normal file
@ -0,0 +1,559 @@
|
||||
<template>
|
||||
<div class="popup-result">
|
||||
<p class="title">最近5次运行时间</p>
|
||||
<ul class="popup-result-scroll">
|
||||
<template v-if='isShow'>
|
||||
<li v-for='item in resultList' :key="item">{{item}}</li>
|
||||
</template>
|
||||
<li v-else>计算结果中...</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dayRule: '',
|
||||
dayRuleSup: '',
|
||||
dateArr: [],
|
||||
resultList: [],
|
||||
isShow: false
|
||||
}
|
||||
},
|
||||
name: 'crontab-result',
|
||||
methods: {
|
||||
// 表达式值变化时,开始去计算结果
|
||||
expressionChange() {
|
||||
|
||||
// 计算开始-隐藏结果
|
||||
this.isShow = false;
|
||||
// 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
|
||||
let ruleArr = this.$options.propsData.ex.split(' ');
|
||||
// 用于记录进入循环的次数
|
||||
let nums = 0;
|
||||
// 用于暂时存符号时间规则结果的数组
|
||||
let resultArr = [];
|
||||
// 获取当前时间精确至[年、月、日、时、分、秒]
|
||||
let nTime = new Date();
|
||||
let nYear = nTime.getFullYear();
|
||||
let nMonth = nTime.getMonth() + 1;
|
||||
let nDay = nTime.getDate();
|
||||
let nHour = nTime.getHours();
|
||||
let nMin = nTime.getMinutes();
|
||||
let nSecond = nTime.getSeconds();
|
||||
// 根据规则获取到近100年可能年数组、月数组等等
|
||||
this.getSecondArr(ruleArr[0]);
|
||||
this.getMinArr(ruleArr[1]);
|
||||
this.getHourArr(ruleArr[2]);
|
||||
this.getDayArr(ruleArr[3]);
|
||||
this.getMonthArr(ruleArr[4]);
|
||||
this.getWeekArr(ruleArr[5]);
|
||||
this.getYearArr(ruleArr[6], nYear);
|
||||
// 将获取到的数组赋值-方便使用
|
||||
let sDate = this.dateArr[0];
|
||||
let mDate = this.dateArr[1];
|
||||
let hDate = this.dateArr[2];
|
||||
let DDate = this.dateArr[3];
|
||||
let MDate = this.dateArr[4];
|
||||
let YDate = this.dateArr[5];
|
||||
// 获取当前时间在数组中的索引
|
||||
let sIdx = this.getIndex(sDate, nSecond);
|
||||
let mIdx = this.getIndex(mDate, nMin);
|
||||
let hIdx = this.getIndex(hDate, nHour);
|
||||
let DIdx = this.getIndex(DDate, nDay);
|
||||
let MIdx = this.getIndex(MDate, nMonth);
|
||||
let YIdx = this.getIndex(YDate, nYear);
|
||||
// 重置月日时分秒的函数(后面用的比较多)
|
||||
const resetSecond = function () {
|
||||
sIdx = 0;
|
||||
nSecond = sDate[sIdx]
|
||||
}
|
||||
const resetMin = function () {
|
||||
mIdx = 0;
|
||||
nMin = mDate[mIdx]
|
||||
resetSecond();
|
||||
}
|
||||
const resetHour = function () {
|
||||
hIdx = 0;
|
||||
nHour = hDate[hIdx]
|
||||
resetMin();
|
||||
}
|
||||
const resetDay = function () {
|
||||
DIdx = 0;
|
||||
nDay = DDate[DIdx]
|
||||
resetHour();
|
||||
}
|
||||
const resetMonth = function () {
|
||||
MIdx = 0;
|
||||
nMonth = MDate[MIdx]
|
||||
resetDay();
|
||||
}
|
||||
// 如果当前年份不为数组中当前值
|
||||
if (nYear !== YDate[YIdx]) {
|
||||
resetMonth();
|
||||
}
|
||||
// 如果当前月份不为数组中当前值
|
||||
if (nMonth !== MDate[MIdx]) {
|
||||
resetDay();
|
||||
}
|
||||
// 如果当前“日”不为数组中当前值
|
||||
if (nDay !== DDate[DIdx]) {
|
||||
resetHour();
|
||||
}
|
||||
// 如果当前“时”不为数组中当前值
|
||||
if (nHour !== hDate[hIdx]) {
|
||||
resetMin();
|
||||
}
|
||||
// 如果当前“分”不为数组中当前值
|
||||
if (nMin !== mDate[mIdx]) {
|
||||
resetSecond();
|
||||
}
|
||||
|
||||
// 循环年份数组
|
||||
goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
|
||||
let YY = YDate[Yi];
|
||||
// 如果到达最大值时
|
||||
if (nMonth > MDate[MDate.length - 1]) {
|
||||
resetMonth();
|
||||
continue;
|
||||
}
|
||||
// 循环月份数组
|
||||
goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
|
||||
// 赋值、方便后面运算
|
||||
let MM = MDate[Mi];
|
||||
MM = MM < 10 ? '0' + MM : MM;
|
||||
// 如果到达最大值时
|
||||
if (nDay > DDate[DDate.length - 1]) {
|
||||
resetDay();
|
||||
if (Mi === MDate.length - 1) {
|
||||
resetMonth();
|
||||
continue goYear;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// 循环日期数组
|
||||
goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
|
||||
// 赋值、方便后面运算
|
||||
let DD = DDate[Di];
|
||||
let thisDD = DD < 10 ? '0' + DD : DD;
|
||||
|
||||
// 如果到达最大值时
|
||||
if (nHour > hDate[hDate.length - 1]) {
|
||||
resetHour();
|
||||
if (Di === DDate.length - 1) {
|
||||
resetDay();
|
||||
if (Mi === MDate.length - 1) {
|
||||
resetMonth();
|
||||
continue goYear;
|
||||
}
|
||||
continue goMonth;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 判断日期的合法性,不合法的话也是跳出当前循环
|
||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') {
|
||||
resetDay();
|
||||
continue goMonth;
|
||||
}
|
||||
// 如果日期规则中有值时
|
||||
if (this.dayRule === 'lastDay') {
|
||||
// 如果不是合法日期则需要将前将日期调到合法日期即月末最后一天
|
||||
|
||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||
DD--;
|
||||
|
||||
thisDD = DD < 10 ? '0' + DD : DD;
|
||||
}
|
||||
}
|
||||
} else if (this.dayRule === 'workDay') {
|
||||
// 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||
DD--;
|
||||
thisDD = DD < 10 ? '0' + DD : DD;
|
||||
}
|
||||
}
|
||||
// 获取达到条件的日期是星期X
|
||||
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
|
||||
// 当星期日时
|
||||
if (thisWeek === 1) {
|
||||
// 先找下一个日,并判断是否为月底
|
||||
DD++;
|
||||
thisDD = DD < 10 ? '0' + DD : DD;
|
||||
// 判断下一日已经不是合法日期
|
||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||
DD -= 3;
|
||||
}
|
||||
} else if (thisWeek === 7) {
|
||||
// 当星期6时只需判断不是1号就可进行操作
|
||||
if (this.dayRuleSup !== 1) {
|
||||
DD--;
|
||||
} else {
|
||||
DD += 2;
|
||||
}
|
||||
}
|
||||
} else if (this.dayRule === 'weekDay') {
|
||||
// 如果指定了是星期几
|
||||
// 获取当前日期是属于星期几
|
||||
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
|
||||
// 校验当前星期是否在星期池(dayRuleSup)中
|
||||
if (this.dayRuleSup.indexOf(thisWeek) < 0) {
|
||||
// 如果到达最大值时
|
||||
if (Di === DDate.length - 1) {
|
||||
resetDay();
|
||||
if (Mi === MDate.length - 1) {
|
||||
resetMonth();
|
||||
continue goYear;
|
||||
}
|
||||
continue goMonth;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else if (this.dayRule === 'assWeek') {
|
||||
// 如果指定了是第几周的星期几
|
||||
// 获取每月1号是属于星期几
|
||||
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
|
||||
if (this.dayRuleSup[1] >= thisWeek) {
|
||||
DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1;
|
||||
} else {
|
||||
DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1;
|
||||
}
|
||||
} else if (this.dayRule === 'lastWeek') {
|
||||
// 如果指定了每月最后一个星期几
|
||||
// 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||
DD--;
|
||||
thisDD = DD < 10 ? '0' + DD : DD;
|
||||
}
|
||||
}
|
||||
// 获取月末最后一天是星期几
|
||||
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
|
||||
// 找到要求中最近的那个星期几
|
||||
if (this.dayRuleSup < thisWeek) {
|
||||
DD -= thisWeek - this.dayRuleSup;
|
||||
} else if (this.dayRuleSup > thisWeek) {
|
||||
DD -= 7 - (this.dayRuleSup - thisWeek)
|
||||
}
|
||||
}
|
||||
// 判断时间值是否小于10置换成“05”这种格式
|
||||
DD = DD < 10 ? '0' + DD : DD;
|
||||
|
||||
// 循环“时”数组
|
||||
goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
|
||||
let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi]
|
||||
|
||||
// 如果到达最大值时
|
||||
if (nMin > mDate[mDate.length - 1]) {
|
||||
resetMin();
|
||||
if (hi === hDate.length - 1) {
|
||||
resetHour();
|
||||
if (Di === DDate.length - 1) {
|
||||
resetDay();
|
||||
if (Mi === MDate.length - 1) {
|
||||
resetMonth();
|
||||
continue goYear;
|
||||
}
|
||||
continue goMonth;
|
||||
}
|
||||
continue goDay;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// 循环"分"数组
|
||||
goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
|
||||
let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi];
|
||||
|
||||
// 如果到达最大值时
|
||||
if (nSecond > sDate[sDate.length - 1]) {
|
||||
resetSecond();
|
||||
if (mi === mDate.length - 1) {
|
||||
resetMin();
|
||||
if (hi === hDate.length - 1) {
|
||||
resetHour();
|
||||
if (Di === DDate.length - 1) {
|
||||
resetDay();
|
||||
if (Mi === MDate.length - 1) {
|
||||
resetMonth();
|
||||
continue goYear;
|
||||
}
|
||||
continue goMonth;
|
||||
}
|
||||
continue goDay;
|
||||
}
|
||||
continue goHour;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// 循环"秒"数组
|
||||
goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
|
||||
let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si];
|
||||
// 添加当前时间(时间合法性在日期循环时已经判断)
|
||||
if (MM !== '00' && DD !== '00') {
|
||||
resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
|
||||
nums++;
|
||||
}
|
||||
// 如果条数满了就退出循环
|
||||
if (nums === 5) break goYear;
|
||||
// 如果到达最大值时
|
||||
if (si === sDate.length - 1) {
|
||||
resetSecond();
|
||||
if (mi === mDate.length - 1) {
|
||||
resetMin();
|
||||
if (hi === hDate.length - 1) {
|
||||
resetHour();
|
||||
if (Di === DDate.length - 1) {
|
||||
resetDay();
|
||||
if (Mi === MDate.length - 1) {
|
||||
resetMonth();
|
||||
continue goYear;
|
||||
}
|
||||
continue goMonth;
|
||||
}
|
||||
continue goDay;
|
||||
}
|
||||
continue goHour;
|
||||
}
|
||||
continue goMin;
|
||||
}
|
||||
} //goSecond
|
||||
} //goMin
|
||||
}//goHour
|
||||
}//goDay
|
||||
}//goMonth
|
||||
}
|
||||
// 判断100年内的结果条数
|
||||
if (resultArr.length === 0) {
|
||||
this.resultList = ['没有达到条件的结果!'];
|
||||
} else {
|
||||
this.resultList = resultArr;
|
||||
if (resultArr.length !== 5) {
|
||||
this.resultList.push('最近100年内只有上面' + resultArr.length + '条结果!')
|
||||
}
|
||||
}
|
||||
// 计算完成-显示结果
|
||||
this.isShow = true;
|
||||
|
||||
|
||||
},
|
||||
// 用于计算某位数字在数组中的索引
|
||||
getIndex(arr, value) {
|
||||
if (value <= arr[0] || value > arr[arr.length - 1]) {
|
||||
return 0;
|
||||
} else {
|
||||
for (let i = 0; i < arr.length - 1; i++) {
|
||||
if (value > arr[i] && value <= arr[i + 1]) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取"年"数组
|
||||
getYearArr(rule, year) {
|
||||
this.dateArr[5] = this.getOrderArr(year, year + 100);
|
||||
if (rule !== undefined) {
|
||||
if (rule.indexOf('-') >= 0) {
|
||||
this.dateArr[5] = this.getCycleArr(rule, year + 100, false)
|
||||
} else if (rule.indexOf('/') >= 0) {
|
||||
this.dateArr[5] = this.getAverageArr(rule, year + 100)
|
||||
} else if (rule !== '*') {
|
||||
this.dateArr[5] = this.getAssignArr(rule)
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取"月"数组
|
||||
getMonthArr(rule) {
|
||||
this.dateArr[4] = this.getOrderArr(1, 12);
|
||||
if (rule.indexOf('-') >= 0) {
|
||||
this.dateArr[4] = this.getCycleArr(rule, 12, false)
|
||||
} else if (rule.indexOf('/') >= 0) {
|
||||
this.dateArr[4] = this.getAverageArr(rule, 12)
|
||||
} else if (rule !== '*') {
|
||||
this.dateArr[4] = this.getAssignArr(rule)
|
||||
}
|
||||
},
|
||||
// 获取"日"数组-主要为日期规则
|
||||
getWeekArr(rule) {
|
||||
// 只有当日期规则的两个值均为“”时则表达日期是有选项的
|
||||
if (this.dayRule === '' && this.dayRuleSup === '') {
|
||||
if (rule.indexOf('-') >= 0) {
|
||||
this.dayRule = 'weekDay';
|
||||
this.dayRuleSup = this.getCycleArr(rule, 7, false)
|
||||
} else if (rule.indexOf('#') >= 0) {
|
||||
this.dayRule = 'assWeek';
|
||||
let matchRule = rule.match(/[0-9]/g);
|
||||
this.dayRuleSup = [Number(matchRule[1]), Number(matchRule[0])];
|
||||
this.dateArr[3] = [1];
|
||||
if (this.dayRuleSup[1] === 7) {
|
||||
this.dayRuleSup[1] = 0;
|
||||
}
|
||||
} else if (rule.indexOf('L') >= 0) {
|
||||
this.dayRule = 'lastWeek';
|
||||
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
|
||||
this.dateArr[3] = [31];
|
||||
if (this.dayRuleSup === 7) {
|
||||
this.dayRuleSup = 0;
|
||||
}
|
||||
} else if (rule !== '*' && rule !== '?') {
|
||||
this.dayRule = 'weekDay';
|
||||
this.dayRuleSup = this.getAssignArr(rule)
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取"日"数组-少量为日期规则
|
||||
getDayArr(rule) {
|
||||
this.dateArr[3] = this.getOrderArr(1, 31);
|
||||
this.dayRule = '';
|
||||
this.dayRuleSup = '';
|
||||
if (rule.indexOf('-') >= 0) {
|
||||
this.dateArr[3] = this.getCycleArr(rule, 31, false)
|
||||
this.dayRuleSup = 'null';
|
||||
} else if (rule.indexOf('/') >= 0) {
|
||||
this.dateArr[3] = this.getAverageArr(rule, 31)
|
||||
this.dayRuleSup = 'null';
|
||||
} else if (rule.indexOf('W') >= 0) {
|
||||
this.dayRule = 'workDay';
|
||||
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
|
||||
this.dateArr[3] = [this.dayRuleSup];
|
||||
} else if (rule.indexOf('L') >= 0) {
|
||||
this.dayRule = 'lastDay';
|
||||
this.dayRuleSup = 'null';
|
||||
this.dateArr[3] = [31];
|
||||
} else if (rule !== '*' && rule !== '?') {
|
||||
this.dateArr[3] = this.getAssignArr(rule)
|
||||
this.dayRuleSup = 'null';
|
||||
} else if (rule === '*') {
|
||||
this.dayRuleSup = 'null';
|
||||
}
|
||||
},
|
||||
// 获取"时"数组
|
||||
getHourArr(rule) {
|
||||
this.dateArr[2] = this.getOrderArr(0, 23);
|
||||
if (rule.indexOf('-') >= 0) {
|
||||
this.dateArr[2] = this.getCycleArr(rule, 24, true)
|
||||
} else if (rule.indexOf('/') >= 0) {
|
||||
this.dateArr[2] = this.getAverageArr(rule, 23)
|
||||
} else if (rule !== '*') {
|
||||
this.dateArr[2] = this.getAssignArr(rule)
|
||||
}
|
||||
},
|
||||
// 获取"分"数组
|
||||
getMinArr(rule) {
|
||||
this.dateArr[1] = this.getOrderArr(0, 59);
|
||||
if (rule.indexOf('-') >= 0) {
|
||||
this.dateArr[1] = this.getCycleArr(rule, 60, true)
|
||||
} else if (rule.indexOf('/') >= 0) {
|
||||
this.dateArr[1] = this.getAverageArr(rule, 59)
|
||||
} else if (rule !== '*') {
|
||||
this.dateArr[1] = this.getAssignArr(rule)
|
||||
}
|
||||
},
|
||||
// 获取"秒"数组
|
||||
getSecondArr(rule) {
|
||||
this.dateArr[0] = this.getOrderArr(0, 59);
|
||||
if (rule.indexOf('-') >= 0) {
|
||||
this.dateArr[0] = this.getCycleArr(rule, 60, true)
|
||||
} else if (rule.indexOf('/') >= 0) {
|
||||
this.dateArr[0] = this.getAverageArr(rule, 59)
|
||||
} else if (rule !== '*') {
|
||||
this.dateArr[0] = this.getAssignArr(rule)
|
||||
}
|
||||
},
|
||||
// 根据传进来的min-max返回一个顺序的数组
|
||||
getOrderArr(min, max) {
|
||||
let arr = [];
|
||||
for (let i = min; i <= max; i++) {
|
||||
arr.push(i);
|
||||
}
|
||||
return arr;
|
||||
},
|
||||
// 根据规则中指定的零散值返回一个数组
|
||||
getAssignArr(rule) {
|
||||
let arr = [];
|
||||
let assiginArr = rule.split(',');
|
||||
for (let i = 0; i < assiginArr.length; i++) {
|
||||
arr[i] = Number(assiginArr[i])
|
||||
}
|
||||
arr.sort(this.compare)
|
||||
return arr;
|
||||
},
|
||||
// 根据一定算术规则计算返回一个数组
|
||||
getAverageArr(rule, limit) {
|
||||
let arr = [];
|
||||
let agArr = rule.split('/');
|
||||
let min = Number(agArr[0]);
|
||||
let step = Number(agArr[1]);
|
||||
while (min <= limit) {
|
||||
arr.push(min);
|
||||
min += step;
|
||||
}
|
||||
return arr;
|
||||
},
|
||||
// 根据规则返回一个具有周期性的数组
|
||||
getCycleArr(rule, limit, status) {
|
||||
// status--表示是否从0开始(则从1开始)
|
||||
let arr = [];
|
||||
let cycleArr = rule.split('-');
|
||||
let min = Number(cycleArr[0]);
|
||||
let max = Number(cycleArr[1]);
|
||||
if (min > max) {
|
||||
max += limit;
|
||||
}
|
||||
for (let i = min; i <= max; i++) {
|
||||
let add = 0;
|
||||
if (status === false && i % limit === 0) {
|
||||
add = limit;
|
||||
}
|
||||
arr.push(Math.round(i % limit + add))
|
||||
}
|
||||
arr.sort(this.compare)
|
||||
return arr;
|
||||
},
|
||||
// 比较数字大小(用于Array.sort)
|
||||
compare(value1, value2) {
|
||||
if (value2 - value1 > 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
// 格式化日期格式如:2017-9-19 18:04:33
|
||||
formatDate(value, type) {
|
||||
// 计算日期相关值
|
||||
let time = typeof value == 'number' ? new Date(value) : value;
|
||||
let Y = time.getFullYear();
|
||||
let M = time.getMonth() + 1;
|
||||
let D = time.getDate();
|
||||
let h = time.getHours();
|
||||
let m = time.getMinutes();
|
||||
let s = time.getSeconds();
|
||||
let week = time.getDay();
|
||||
// 如果传递了type的话
|
||||
if (type === undefined) {
|
||||
return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D) + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
||||
} else if (type === 'week') {
|
||||
// 在quartz中 1为星期日
|
||||
return week + 1;
|
||||
}
|
||||
},
|
||||
// 检查日期是否存在
|
||||
checkDate(value) {
|
||||
let time = new Date(value);
|
||||
let format = this.formatDate(time)
|
||||
return value === format;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'ex': 'expressionChange'
|
||||
},
|
||||
props: ['ex'],
|
||||
mounted: function () {
|
||||
// 初始化 获取一次结果
|
||||
this.expressionChange();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
117
src/components/Crontab/second.vue
Normal file
117
src/components/Crontab/second.vue
Normal file
@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<el-form size="small">
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
秒,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="0" :max="58" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 秒
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="0" :max="58" /> 秒开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 秒执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
radioValue: 1,
|
||||
cycle01: 1,
|
||||
cycle02: 2,
|
||||
average01: 0,
|
||||
average02: 1,
|
||||
checkboxList: [],
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-second',
|
||||
props: ['check', 'radioParent'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
switch (this.radioValue) {
|
||||
case 1:
|
||||
this.$emit('update', 'second', '*', 'second');
|
||||
break;
|
||||
case 2:
|
||||
this.$emit('update', 'second', this.cycleTotal);
|
||||
break;
|
||||
case 3:
|
||||
this.$emit('update', 'second', this.averageTotal);
|
||||
break;
|
||||
case 4:
|
||||
this.$emit('update', 'second', this.checkboxString);
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 周期两个值变化时
|
||||
cycleChange() {
|
||||
if (this.radioValue === '2') {
|
||||
this.$emit('update', 'second', this.cycleTotal);
|
||||
}
|
||||
},
|
||||
// 平均两个值变化时
|
||||
averageChange() {
|
||||
if (this.radioValue === '3') {
|
||||
this.$emit('update', 'second', this.averageTotal);
|
||||
}
|
||||
},
|
||||
// checkbox值变化时
|
||||
checkboxChange() {
|
||||
if (this.radioValue === '4') {
|
||||
this.$emit('update', 'second', this.checkboxString);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'radioValue': 'radioChange',
|
||||
'cycleTotal': 'cycleChange',
|
||||
'averageTotal': 'averageChange',
|
||||
'checkboxString': 'checkboxChange',
|
||||
radioParent() {
|
||||
this.radioValue = this.radioParent
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算两个周期值
|
||||
cycleTotal: function () {
|
||||
const cycle01 = this.checkNum(this.cycle01, 0, 58)
|
||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
|
||||
return cycle01 + '-' + cycle02;
|
||||
},
|
||||
// 计算平均用到的值
|
||||
averageTotal: function () {
|
||||
const average01 = this.checkNum(this.average01, 0, 58)
|
||||
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
|
||||
return average01 + '/' + average02;
|
||||
},
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str === '' ? '*' : str;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
202
src/components/Crontab/week.vue
Normal file
202
src/components/Crontab/week.vue
Normal file
@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<el-form size='small'>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
周,允许的通配符[, - * ? / L #]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
不指定
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
周期从星期
|
||||
<el-select clearable v-model="cycle01">
|
||||
<el-option
|
||||
v-for="(item,index) of weekList"
|
||||
:key="index"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
:disabled="item.key === 1"
|
||||
>{{item.value}}</el-option>
|
||||
</el-select>
|
||||
-
|
||||
<el-select clearable v-model="cycle02">
|
||||
<el-option
|
||||
v-for="(item,index) of weekList"
|
||||
:key="index"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
:disabled="item.key < cycle01 && item.key !== 1"
|
||||
>{{item.value}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
第
|
||||
<el-input-number v-model='average01' :min="1" :max="4" /> 周的星期
|
||||
<el-select clearable v-model="average02">
|
||||
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="5">
|
||||
本月最后一个星期
|
||||
<el-select clearable v-model="weekday">
|
||||
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="6">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="String(item.key)">{{item.value}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
radioValue: 2,
|
||||
weekday: 2,
|
||||
cycle01: 2,
|
||||
cycle02: 3,
|
||||
average01: 1,
|
||||
average02: 2,
|
||||
checkboxList: [],
|
||||
weekList: [
|
||||
{
|
||||
key: 2,
|
||||
value: '星期一'
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
value: '星期二'
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
value: '星期三'
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
value: '星期四'
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
value: '星期五'
|
||||
},
|
||||
{
|
||||
key: 7,
|
||||
value: '星期六'
|
||||
},
|
||||
{
|
||||
key: 1,
|
||||
value: '星期日'
|
||||
}
|
||||
],
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-week',
|
||||
props: ['check', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
if (this.radioValue !== 2 && this.cron.day !== '?') {
|
||||
this.$emit('update', 'day', '?', 'week');
|
||||
}
|
||||
switch (this.radioValue) {
|
||||
case 1:
|
||||
this.$emit('update', 'week', '*');
|
||||
break;
|
||||
case 2:
|
||||
this.$emit('update', 'week', '?');
|
||||
break;
|
||||
case 3:
|
||||
this.$emit('update', 'week', this.cycleTotal);
|
||||
break;
|
||||
case 4:
|
||||
this.$emit('update', 'week', this.averageTotal);
|
||||
break;
|
||||
case 5:
|
||||
this.$emit('update', 'week', this.weekdayCheck + 'L');
|
||||
break;
|
||||
case 6:
|
||||
this.$emit('update', 'week', this.checkboxString);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// 周期两个值变化时
|
||||
cycleChange() {
|
||||
if (this.radioValue === '3') {
|
||||
this.$emit('update', 'week', this.cycleTotal);
|
||||
}
|
||||
},
|
||||
// 平均两个值变化时
|
||||
averageChange() {
|
||||
if (this.radioValue === '4') {
|
||||
this.$emit('update', 'week', this.averageTotal);
|
||||
}
|
||||
},
|
||||
// 最近工作日值变化时
|
||||
weekdayChange() {
|
||||
if (this.radioValue === '5') {
|
||||
this.$emit('update', 'week', this.weekday + 'L');
|
||||
}
|
||||
},
|
||||
// checkbox值变化时
|
||||
checkboxChange() {
|
||||
if (this.radioValue === '6') {
|
||||
this.$emit('update', 'week', this.checkboxString);
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'radioValue': 'radioChange',
|
||||
'cycleTotal': 'cycleChange',
|
||||
'averageTotal': 'averageChange',
|
||||
'weekdayCheck': 'weekdayChange',
|
||||
'checkboxString': 'checkboxChange',
|
||||
},
|
||||
computed: {
|
||||
// 计算两个周期值
|
||||
cycleTotal: function () {
|
||||
this.cycle01 = this.checkNum(this.cycle01, 1, 7)
|
||||
this.cycle02 = this.checkNum(this.cycle02, 1, 7)
|
||||
return this.cycle01 + '-' + this.cycle02;
|
||||
},
|
||||
// 计算平均用到的值
|
||||
averageTotal: function () {
|
||||
this.average01 = this.checkNum(this.average01, 1, 4)
|
||||
this.average02 = this.checkNum(this.average02, 1, 7)
|
||||
return this.average02 + '#' + this.average01;
|
||||
},
|
||||
// 最近的工作日(格式)
|
||||
weekdayCheck: function () {
|
||||
this.weekday = this.checkNum(this.weekday, 1, 7)
|
||||
return this.weekday;
|
||||
},
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str === '' ? '*' : str;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
131
src/components/Crontab/year.vue
Normal file
131
src/components/Crontab/year.vue
Normal file
@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<el-form size="small">
|
||||
<el-form-item>
|
||||
<el-radio :label="1" v-model='radioValue'>
|
||||
不填,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio :label="2" v-model='radioValue'>
|
||||
每年
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio :label="3" v-model='radioValue'>
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min='fullYear' :max="2098" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : fullYear + 1" :max="2099" />
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio :label="4" v-model='radioValue'>
|
||||
从
|
||||
<el-input-number v-model='average01' :min='fullYear' :max="2098"/> 年开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="2099 - average01 || fullYear" /> 年执行一次
|
||||
</el-radio>
|
||||
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio :label="5" v-model='radioValue'>
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple>
|
||||
<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
fullYear: 0,
|
||||
radioValue: 1,
|
||||
cycle01: 0,
|
||||
cycle02: 0,
|
||||
average01: 0,
|
||||
average02: 1,
|
||||
checkboxList: [],
|
||||
checkNum: this.$options.propsData.check
|
||||
}
|
||||
},
|
||||
name: 'crontab-year',
|
||||
props: ['check', 'month', 'cron'],
|
||||
methods: {
|
||||
// 单选按钮值变化时
|
||||
radioChange() {
|
||||
switch (this.radioValue) {
|
||||
case 1:
|
||||
this.$emit('update', 'year', '');
|
||||
break;
|
||||
case 2:
|
||||
this.$emit('update', 'year', '*');
|
||||
break;
|
||||
case 3:
|
||||
this.$emit('update', 'year', this.cycleTotal);
|
||||
break;
|
||||
case 4:
|
||||
this.$emit('update', 'year', this.averageTotal);
|
||||
break;
|
||||
case 5:
|
||||
this.$emit('update', 'year', this.checkboxString);
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 周期两个值变化时
|
||||
cycleChange() {
|
||||
if (this.radioValue === '3') {
|
||||
this.$emit('update', 'year', this.cycleTotal);
|
||||
}
|
||||
},
|
||||
// 平均两个值变化时
|
||||
averageChange() {
|
||||
if (this.radioValue === '4') {
|
||||
this.$emit('update', 'year', this.averageTotal);
|
||||
}
|
||||
},
|
||||
// checkbox值变化时
|
||||
checkboxChange() {
|
||||
if (this.radioValue === '5') {
|
||||
this.$emit('update', 'year', this.checkboxString);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'radioValue': 'radioChange',
|
||||
'cycleTotal': 'cycleChange',
|
||||
'averageTotal': 'averageChange',
|
||||
'checkboxString': 'checkboxChange'
|
||||
},
|
||||
computed: {
|
||||
// 计算两个周期值
|
||||
cycleTotal: function () {
|
||||
const cycle01 = this.checkNum(this.cycle01, this.fullYear, 2098)
|
||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : this.fullYear + 1, 2099)
|
||||
return cycle01 + '-' + cycle02;
|
||||
},
|
||||
// 计算平均用到的值
|
||||
averageTotal: function () {
|
||||
const average01 = this.checkNum(this.average01, this.fullYear, 2098)
|
||||
const average02 = this.checkNum(this.average02, 1, 2099 - average01 || this.fullYear)
|
||||
return average01 + '/' + average02;
|
||||
},
|
||||
// 计算勾选的checkbox值合集
|
||||
checkboxString: function () {
|
||||
let str = this.checkboxList.join();
|
||||
return str;
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
// 仅获取当前年份
|
||||
this.fullYear = Number(new Date().getFullYear());
|
||||
this.cycle01 = this.fullYear
|
||||
this.average01 = this.fullYear
|
||||
}
|
||||
}
|
||||
</script>
|
630
src/components/generator/config.js
Normal file
630
src/components/generator/config.js
Normal file
@ -0,0 +1,630 @@
|
||||
// 表单属性【右面板】
|
||||
export const formConf = {
|
||||
formRef: 'elForm',
|
||||
formModel: 'formData',
|
||||
size: 'medium',
|
||||
labelPosition: 'right',
|
||||
labelWidth: 100,
|
||||
formRules: 'rules',
|
||||
gutter: 15,
|
||||
disabled: false,
|
||||
span: 24,
|
||||
formBtns: true
|
||||
}
|
||||
|
||||
// 输入型组件 【左面板】
|
||||
export const inputComponents = [
|
||||
{
|
||||
// 组件的自定义配置
|
||||
__config__: {
|
||||
label: '单行文本',
|
||||
labelWidth: null,
|
||||
showLabel: true,
|
||||
changeTag: true,
|
||||
tag: 'el-input',
|
||||
tagIcon: 'input',
|
||||
defaultValue: undefined,
|
||||
required: true,
|
||||
layout: 'colFormItem',
|
||||
span: 24,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/input',
|
||||
// 正则校验规则
|
||||
regList: []
|
||||
},
|
||||
// 组件的插槽属性
|
||||
__slot__: {
|
||||
prepend: '',
|
||||
append: ''
|
||||
},
|
||||
// 其余的为可直接写在组件标签上的属性
|
||||
placeholder: '请输入',
|
||||
style: { width: '100%' },
|
||||
clearable: true,
|
||||
'prefix-icon': '',
|
||||
'suffix-icon': '',
|
||||
maxlength: null,
|
||||
'show-word-limit': false,
|
||||
readonly: false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '多行文本',
|
||||
labelWidth: null,
|
||||
showLabel: true,
|
||||
tag: 'el-input',
|
||||
tagIcon: 'textarea',
|
||||
defaultValue: undefined,
|
||||
required: true,
|
||||
layout: 'colFormItem',
|
||||
span: 24,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/input'
|
||||
},
|
||||
type: 'textarea',
|
||||
placeholder: '请输入',
|
||||
autosize: {
|
||||
minRows: 4,
|
||||
maxRows: 4
|
||||
},
|
||||
style: { width: '100%' },
|
||||
maxlength: null,
|
||||
'show-word-limit': false,
|
||||
readonly: false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '密码',
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
changeTag: true,
|
||||
tag: 'el-input',
|
||||
tagIcon: 'password',
|
||||
defaultValue: undefined,
|
||||
layout: 'colFormItem',
|
||||
span: 24,
|
||||
required: true,
|
||||
regList: [],
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/input'
|
||||
},
|
||||
__slot__: {
|
||||
prepend: '',
|
||||
append: ''
|
||||
},
|
||||
placeholder: '请输入',
|
||||
'show-password': true,
|
||||
style: { width: '100%' },
|
||||
clearable: true,
|
||||
'prefix-icon': '',
|
||||
'suffix-icon': '',
|
||||
maxlength: null,
|
||||
'show-word-limit': false,
|
||||
readonly: false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '计数器',
|
||||
showLabel: true,
|
||||
changeTag: true,
|
||||
labelWidth: null,
|
||||
tag: 'el-input-number',
|
||||
tagIcon: 'number',
|
||||
defaultValue: undefined,
|
||||
span: 24,
|
||||
layout: 'colFormItem',
|
||||
required: true,
|
||||
regList: [],
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/input-number'
|
||||
},
|
||||
placeholder: '',
|
||||
min: undefined,
|
||||
max: undefined,
|
||||
step: 1,
|
||||
'step-strictly': false,
|
||||
precision: undefined,
|
||||
'controls-position': '',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '编辑器',
|
||||
showLabel: true,
|
||||
changeTag: true,
|
||||
labelWidth: null,
|
||||
tag: 'tinymce',
|
||||
tagIcon: 'rich-text',
|
||||
defaultValue: null,
|
||||
span: 24,
|
||||
layout: 'colFormItem',
|
||||
required: true,
|
||||
regList: [],
|
||||
document: 'http://tinymce.ax-z.cn'
|
||||
},
|
||||
placeholder: '请输入',
|
||||
height: 300, // 编辑器高度
|
||||
branding: false // 隐藏右下角品牌烙印
|
||||
}
|
||||
]
|
||||
|
||||
// 选择型组件 【左面板】
|
||||
export const selectComponents = [
|
||||
{
|
||||
__config__: {
|
||||
label: '下拉选择',
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
tag: 'el-select',
|
||||
tagIcon: 'select',
|
||||
layout: 'colFormItem',
|
||||
span: 24,
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/select'
|
||||
},
|
||||
__slot__: {
|
||||
options: [{
|
||||
label: '选项一',
|
||||
value: 1
|
||||
}, {
|
||||
label: '选项二',
|
||||
value: 2
|
||||
}]
|
||||
},
|
||||
placeholder: '请选择',
|
||||
style: { width: '100%' },
|
||||
clearable: true,
|
||||
disabled: false,
|
||||
filterable: false,
|
||||
multiple: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '级联选择',
|
||||
url: 'https://www.fastmock.site/mock/f8d7a54fb1e60561e2f720d5a810009d/fg/cascaderList',
|
||||
method: 'get',
|
||||
dataPath: 'list',
|
||||
dataConsumer: 'options',
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
tag: 'el-cascader',
|
||||
tagIcon: 'cascader',
|
||||
layout: 'colFormItem',
|
||||
defaultValue: [],
|
||||
dataType: 'dynamic',
|
||||
span: 24,
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/cascader'
|
||||
},
|
||||
options: [{
|
||||
id: 1,
|
||||
value: 1,
|
||||
label: '选项1',
|
||||
children: [{
|
||||
id: 2,
|
||||
value: 2,
|
||||
label: '选项1-1'
|
||||
}]
|
||||
}],
|
||||
placeholder: '请选择',
|
||||
style: { width: '100%' },
|
||||
props: {
|
||||
props: {
|
||||
multiple: false,
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
children: 'children'
|
||||
}
|
||||
},
|
||||
'show-all-levels': true,
|
||||
disabled: false,
|
||||
clearable: true,
|
||||
filterable: false,
|
||||
separator: '/'
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '单选框组',
|
||||
labelWidth: null,
|
||||
showLabel: true,
|
||||
tag: 'el-radio-group',
|
||||
tagIcon: 'radio',
|
||||
changeTag: true,
|
||||
defaultValue: undefined,
|
||||
layout: 'colFormItem',
|
||||
span: 24,
|
||||
optionType: 'default',
|
||||
regList: [],
|
||||
required: true,
|
||||
border: false,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/radio'
|
||||
},
|
||||
__slot__: {
|
||||
options: [{
|
||||
label: '选项一',
|
||||
value: 1
|
||||
}, {
|
||||
label: '选项二',
|
||||
value: 2
|
||||
}]
|
||||
},
|
||||
style: {},
|
||||
size: 'medium',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '多选框组',
|
||||
tag: 'el-checkbox-group',
|
||||
tagIcon: 'checkbox',
|
||||
defaultValue: [],
|
||||
span: 24,
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
layout: 'colFormItem',
|
||||
optionType: 'default',
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
border: false,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/checkbox'
|
||||
},
|
||||
__slot__: {
|
||||
options: [{
|
||||
label: '选项一',
|
||||
value: 1
|
||||
}, {
|
||||
label: '选项二',
|
||||
value: 2
|
||||
}]
|
||||
},
|
||||
style: {},
|
||||
size: 'medium',
|
||||
min: null,
|
||||
max: null,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '开关',
|
||||
tag: 'el-switch',
|
||||
tagIcon: 'switch',
|
||||
defaultValue: false,
|
||||
span: 24,
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
layout: 'colFormItem',
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/switch'
|
||||
},
|
||||
style: {},
|
||||
disabled: false,
|
||||
'active-text': '',
|
||||
'inactive-text': '',
|
||||
'active-color': null,
|
||||
'inactive-color': null,
|
||||
'active-value': true,
|
||||
'inactive-value': false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '滑块',
|
||||
tag: 'el-slider',
|
||||
tagIcon: 'slider',
|
||||
defaultValue: null,
|
||||
span: 24,
|
||||
showLabel: true,
|
||||
layout: 'colFormItem',
|
||||
labelWidth: null,
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/slider'
|
||||
},
|
||||
disabled: false,
|
||||
min: 0,
|
||||
max: 100,
|
||||
step: 1,
|
||||
'show-stops': false,
|
||||
range: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '时间选择',
|
||||
tag: 'el-time-picker',
|
||||
tagIcon: 'time',
|
||||
defaultValue: null,
|
||||
span: 24,
|
||||
showLabel: true,
|
||||
layout: 'colFormItem',
|
||||
labelWidth: null,
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
|
||||
},
|
||||
placeholder: '请选择',
|
||||
style: { width: '100%' },
|
||||
disabled: false,
|
||||
clearable: true,
|
||||
'picker-options': {
|
||||
selectableRange: '00:00:00-23:59:59'
|
||||
},
|
||||
format: 'HH:mm:ss',
|
||||
'value-format': 'HH:mm:ss'
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '时间范围',
|
||||
tag: 'el-time-picker',
|
||||
tagIcon: 'time-range',
|
||||
span: 24,
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
layout: 'colFormItem',
|
||||
defaultValue: null,
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
|
||||
},
|
||||
style: { width: '100%' },
|
||||
disabled: false,
|
||||
clearable: true,
|
||||
'is-range': true,
|
||||
'range-separator': '至',
|
||||
'start-placeholder': '开始时间',
|
||||
'end-placeholder': '结束时间',
|
||||
format: 'HH:mm:ss',
|
||||
'value-format': 'HH:mm:ss'
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '日期选择',
|
||||
tag: 'el-date-picker',
|
||||
tagIcon: 'date',
|
||||
defaultValue: null,
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
span: 24,
|
||||
layout: 'colFormItem',
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
|
||||
},
|
||||
placeholder: '请选择',
|
||||
type: 'date',
|
||||
style: { width: '100%' },
|
||||
disabled: false,
|
||||
clearable: true,
|
||||
format: 'yyyy-MM-dd',
|
||||
'value-format': 'yyyy-MM-dd',
|
||||
readonly: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '日期范围',
|
||||
tag: 'el-date-picker',
|
||||
tagIcon: 'date-range',
|
||||
defaultValue: null,
|
||||
span: 24,
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
required: true,
|
||||
layout: 'colFormItem',
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
|
||||
},
|
||||
style: { width: '100%' },
|
||||
type: 'daterange',
|
||||
'range-separator': '至',
|
||||
'start-placeholder': '开始日期',
|
||||
'end-placeholder': '结束日期',
|
||||
disabled: false,
|
||||
clearable: true,
|
||||
format: 'yyyy-MM-dd',
|
||||
'value-format': 'yyyy-MM-dd',
|
||||
readonly: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '评分',
|
||||
tag: 'el-rate',
|
||||
tagIcon: 'rate',
|
||||
defaultValue: 0,
|
||||
span: 24,
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
layout: 'colFormItem',
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/rate'
|
||||
},
|
||||
style: {},
|
||||
max: 5,
|
||||
'allow-half': false,
|
||||
'show-text': false,
|
||||
'show-score': false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '颜色选择',
|
||||
tag: 'el-color-picker',
|
||||
tagIcon: 'color',
|
||||
span: 24,
|
||||
defaultValue: null,
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
layout: 'colFormItem',
|
||||
required: true,
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/color-picker'
|
||||
},
|
||||
'show-alpha': false,
|
||||
'color-format': '',
|
||||
disabled: false,
|
||||
size: 'medium'
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '上传',
|
||||
tag: 'el-upload',
|
||||
tagIcon: 'upload',
|
||||
layout: 'colFormItem',
|
||||
defaultValue: null,
|
||||
showLabel: true,
|
||||
labelWidth: null,
|
||||
required: true,
|
||||
span: 24,
|
||||
showTip: false,
|
||||
buttonText: '点击上传',
|
||||
regList: [],
|
||||
changeTag: true,
|
||||
fileSize: 2,
|
||||
sizeUnit: 'MB',
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/upload'
|
||||
},
|
||||
__slot__: {
|
||||
'list-type': true
|
||||
},
|
||||
// action: process.env.VUE_APP_BASE_API + "/admin-api/infra/file/upload", // 请求地址
|
||||
action: '/infra/file/upload', // 请求地址
|
||||
disabled: false,
|
||||
accept: '',
|
||||
name: 'file',
|
||||
'auto-upload': true,
|
||||
'list-type': 'text',
|
||||
multiple: false
|
||||
}
|
||||
]
|
||||
|
||||
// 布局型组件 【左面板】
|
||||
export const layoutComponents = [
|
||||
{
|
||||
__config__: {
|
||||
layout: 'rowFormItem',
|
||||
tagIcon: 'row',
|
||||
label: '行容器',
|
||||
layoutTree: true,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/layout#row-attributes'
|
||||
},
|
||||
type: 'default',
|
||||
justify: 'start',
|
||||
align: 'top'
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
label: '按钮',
|
||||
showLabel: true,
|
||||
changeTag: true,
|
||||
labelWidth: null,
|
||||
tag: 'el-button',
|
||||
tagIcon: 'button',
|
||||
span: 24,
|
||||
layout: 'colFormItem',
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/button'
|
||||
},
|
||||
__slot__: {
|
||||
default: '主要按钮'
|
||||
},
|
||||
type: 'primary',
|
||||
icon: 'el-icon-search',
|
||||
round: false,
|
||||
size: 'medium',
|
||||
plain: false,
|
||||
circle: false,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
__config__: {
|
||||
layout: 'colFormItem',
|
||||
tagIcon: 'table',
|
||||
tag: 'el-table',
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/table',
|
||||
span: 24,
|
||||
formId: 101,
|
||||
renderKey: 1595761764203,
|
||||
componentName: 'row101',
|
||||
showLabel: true,
|
||||
changeTag: true,
|
||||
labelWidth: null,
|
||||
label: '表格[开发中]',
|
||||
dataType: 'dynamic',
|
||||
method: 'get',
|
||||
dataPath: 'list',
|
||||
dataConsumer: 'data',
|
||||
url: 'https://www.fastmock.site/mock/f8d7a54fb1e60561e2f720d5a810009d/fg/tableData',
|
||||
children: [{
|
||||
__config__: {
|
||||
layout: 'raw',
|
||||
tag: 'el-table-column',
|
||||
renderKey: 15957617660153
|
||||
},
|
||||
prop: 'date',
|
||||
label: '日期'
|
||||
}, {
|
||||
__config__: {
|
||||
layout: 'raw',
|
||||
tag: 'el-table-column',
|
||||
renderKey: 15957617660152
|
||||
},
|
||||
prop: 'address',
|
||||
label: '地址'
|
||||
}, {
|
||||
__config__: {
|
||||
layout: 'raw',
|
||||
tag: 'el-table-column',
|
||||
renderKey: 15957617660151
|
||||
},
|
||||
prop: 'name',
|
||||
label: '名称'
|
||||
}, {
|
||||
__config__: {
|
||||
layout: 'raw',
|
||||
tag: 'el-table-column',
|
||||
renderKey: 1595774496335,
|
||||
children: [
|
||||
{
|
||||
__config__: {
|
||||
label: '按钮',
|
||||
tag: 'el-button',
|
||||
tagIcon: 'button',
|
||||
layout: 'raw',
|
||||
renderKey: 1595779809901
|
||||
},
|
||||
__slot__: {
|
||||
default: '主要按钮'
|
||||
},
|
||||
type: 'primary',
|
||||
icon: 'el-icon-search',
|
||||
round: false,
|
||||
size: 'medium'
|
||||
}
|
||||
]
|
||||
},
|
||||
label: '操作'
|
||||
}]
|
||||
},
|
||||
data: [],
|
||||
directives: [{
|
||||
name: 'loading',
|
||||
value: true
|
||||
}],
|
||||
border: true,
|
||||
type: 'default',
|
||||
justify: 'start',
|
||||
align: 'top'
|
||||
}
|
||||
]
|
18
src/components/generator/css.js
Normal file
18
src/components/generator/css.js
Normal file
@ -0,0 +1,18 @@
|
||||
const styles = {
|
||||
'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}',
|
||||
'el-upload': '.el-upload__tip{line-height: 1.2;}'
|
||||
}
|
||||
|
||||
function addCss(cssList, el) {
|
||||
const css = styles[el.__config__.tag]
|
||||
css && cssList.indexOf(css) === -1 && cssList.push(css)
|
||||
if (el.__config__.children) {
|
||||
el.__config__.children.forEach(el2 => addCss(cssList, el2))
|
||||
}
|
||||
}
|
||||
|
||||
export function makeUpCss(conf) {
|
||||
const cssList = []
|
||||
conf.fields.forEach(el => addCss(cssList, el))
|
||||
return cssList.join('\n')
|
||||
}
|
37
src/components/generator/drawingDefalut.js
Normal file
37
src/components/generator/drawingDefalut.js
Normal file
@ -0,0 +1,37 @@
|
||||
export default [
|
||||
{
|
||||
__config__: {
|
||||
label: '单行文本',
|
||||
labelWidth: null,
|
||||
showLabel: true,
|
||||
changeTag: true,
|
||||
tag: 'el-input',
|
||||
tagIcon: 'input',
|
||||
defaultValue: undefined,
|
||||
required: true,
|
||||
layout: 'colFormItem',
|
||||
span: 24,
|
||||
document: 'https://element.eleme.cn/#/zh-CN/component/input',
|
||||
// 正则校验规则
|
||||
regList: [{
|
||||
pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
|
||||
message: '手机号格式错误'
|
||||
}]
|
||||
},
|
||||
// 组件的插槽属性
|
||||
__slot__: {
|
||||
prepend: '',
|
||||
append: ''
|
||||
},
|
||||
__vModel__: 'mobile',
|
||||
placeholder: '请输入手机号',
|
||||
style: { width: '100%' },
|
||||
clearable: true,
|
||||
'prefix-icon': 'el-icon-mobile',
|
||||
'suffix-icon': '',
|
||||
maxlength: 11,
|
||||
'show-word-limit': true,
|
||||
readonly: false,
|
||||
disabled: false
|
||||
}
|
||||
]
|
399
src/components/generator/html.js
Normal file
399
src/components/generator/html.js
Normal file
@ -0,0 +1,399 @@
|
||||
/* eslint-disable max-len */
|
||||
import ruleTrigger from './ruleTrigger'
|
||||
|
||||
let confGlobal
|
||||
let someSpanIsNot24
|
||||
|
||||
export function dialogWrapper(str) {
|
||||
return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Titile">
|
||||
${str}
|
||||
<div slot="footer">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="handelConfirm">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>`
|
||||
}
|
||||
|
||||
export function vueTemplate(str) {
|
||||
return `<template>
|
||||
<div>
|
||||
${str}
|
||||
</div>
|
||||
</template>`
|
||||
}
|
||||
|
||||
export function vueScript(str) {
|
||||
return `<script>
|
||||
${str}
|
||||
</script>`
|
||||
}
|
||||
|
||||
export function cssStyle(cssStr) {
|
||||
return `<style>
|
||||
${cssStr}
|
||||
</style>`
|
||||
}
|
||||
|
||||
function buildFormTemplate(scheme, child, type) {
|
||||
let labelPosition = ''
|
||||
if (scheme.labelPosition !== 'right') {
|
||||
labelPosition = `label-position="${scheme.labelPosition}"`
|
||||
}
|
||||
const disabled = scheme.disabled ? `:disabled="${scheme.disabled}"` : ''
|
||||
let str = `<el-form ref="${scheme.formRef}" :model="${scheme.formModel}" :rules="${scheme.formRules}" size="${scheme.size}" ${disabled} label-width="${scheme.labelWidth}px" ${labelPosition}>
|
||||
${child}
|
||||
${buildFromBtns(scheme, type)}
|
||||
</el-form>`
|
||||
if (someSpanIsNot24) {
|
||||
str = `<el-row :gutter="${scheme.gutter}">
|
||||
${str}
|
||||
</el-row>`
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
function buildFromBtns(scheme, type) {
|
||||
let str = ''
|
||||
if (scheme.formBtns && type === 'file') {
|
||||
str = `<el-form-item size="large">
|
||||
<el-button type="primary" @click="submitForm">提交</el-button>
|
||||
<el-button @click="resetForm">重置</el-button>
|
||||
</el-form-item>`
|
||||
if (someSpanIsNot24) {
|
||||
str = `<el-col :span="24">
|
||||
${str}
|
||||
</el-col>`
|
||||
}
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
// span不为24的用el-col包裹
|
||||
function colWrapper(scheme, str) {
|
||||
if (someSpanIsNot24 || scheme.__config__.span !== 24) {
|
||||
return `<el-col :span="${scheme.__config__.span}">
|
||||
${str}
|
||||
</el-col>`
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
const layouts = {
|
||||
colFormItem(scheme) {
|
||||
const config = scheme.__config__
|
||||
let labelWidth = ''
|
||||
let label = `label="${config.label}"`
|
||||
if (config.labelWidth && config.labelWidth !== confGlobal.labelWidth) {
|
||||
labelWidth = `label-width="${config.labelWidth}px"`
|
||||
}
|
||||
if (config.showLabel === false) {
|
||||
labelWidth = 'label-width="0"'
|
||||
label = ''
|
||||
}
|
||||
const required = !ruleTrigger[config.tag] && config.required ? 'required' : ''
|
||||
const tagDom = tags[config.tag] ? tags[config.tag](scheme) : null
|
||||
let str = `<el-form-item ${labelWidth} ${label} prop="${scheme.__vModel__}" ${required}>
|
||||
${tagDom}
|
||||
</el-form-item>`
|
||||
str = colWrapper(scheme, str)
|
||||
return str
|
||||
},
|
||||
rowFormItem(scheme) {
|
||||
const config = scheme.__config__
|
||||
const type = scheme.type === 'default' ? '' : `type="${scheme.type}"`
|
||||
const justify = scheme.type === 'default' ? '' : `justify="${scheme.justify}"`
|
||||
const align = scheme.type === 'default' ? '' : `align="${scheme.align}"`
|
||||
const gutter = scheme.gutter ? `:gutter="${scheme.gutter}"` : ''
|
||||
const children = config.children.map(el => layouts[el.__config__.layout](el))
|
||||
let str = `<el-row ${type} ${justify} ${align} ${gutter}>
|
||||
${children.join('\n')}
|
||||
</el-row>`
|
||||
str = colWrapper(scheme, str)
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
const tags = {
|
||||
'el-button': el => {
|
||||
const {
|
||||
tag, disabled
|
||||
} = attrBuilder(el)
|
||||
const type = el.type ? `type="${el.type}"` : ''
|
||||
const icon = el.icon ? `icon="${el.icon}"` : ''
|
||||
const round = el.round ? 'round' : ''
|
||||
const size = el.size ? `size="${el.size}"` : ''
|
||||
const plain = el.plain ? 'plain' : ''
|
||||
const circle = el.circle ? 'circle' : ''
|
||||
let child = buildElButtonChild(el)
|
||||
|
||||
if (child) child = `\n${child}\n` // 换行
|
||||
return `<${tag} ${type} ${icon} ${round} ${size} ${plain} ${disabled} ${circle}>${child}</${tag}>`
|
||||
},
|
||||
'el-input': el => {
|
||||
const {
|
||||
tag, disabled, vModel, clearable, placeholder, width
|
||||
} = attrBuilder(el)
|
||||
const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : ''
|
||||
const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : ''
|
||||
const readonly = el.readonly ? 'readonly' : ''
|
||||
const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : ''
|
||||
const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : ''
|
||||
const showPassword = el['show-password'] ? 'show-password' : ''
|
||||
const type = el.type ? `type="${el.type}"` : ''
|
||||
const autosize = el.autosize && el.autosize.minRows
|
||||
? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"`
|
||||
: ''
|
||||
let child = buildElInputChild(el)
|
||||
|
||||
if (child) child = `\n${child}\n` // 换行
|
||||
return `<${tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${tag}>`
|
||||
},
|
||||
'el-input-number': el => {
|
||||
const {
|
||||
tag, disabled, vModel, placeholder
|
||||
} = attrBuilder(el)
|
||||
const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : ''
|
||||
const min = el.min ? `:min='${el.min}'` : ''
|
||||
const max = el.max ? `:max='${el.max}'` : ''
|
||||
const step = el.step ? `:step='${el.step}'` : ''
|
||||
const stepStrictly = el['step-strictly'] ? 'step-strictly' : ''
|
||||
const precision = el.precision ? `:precision='${el.precision}'` : ''
|
||||
|
||||
return `<${tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${tag}>`
|
||||
},
|
||||
'el-select': el => {
|
||||
const {
|
||||
tag, disabled, vModel, clearable, placeholder, width
|
||||
} = attrBuilder(el)
|
||||
const filterable = el.filterable ? 'filterable' : ''
|
||||
const multiple = el.multiple ? 'multiple' : ''
|
||||
let child = buildElSelectChild(el)
|
||||
|
||||
if (child) child = `\n${child}\n` // 换行
|
||||
return `<${tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${tag}>`
|
||||
},
|
||||
'el-radio-group': el => {
|
||||
const { tag, disabled, vModel } = attrBuilder(el)
|
||||
const size = `size="${el.size}"`
|
||||
let child = buildElRadioGroupChild(el)
|
||||
|
||||
if (child) child = `\n${child}\n` // 换行
|
||||
return `<${tag} ${vModel} ${size} ${disabled}>${child}</${tag}>`
|
||||
},
|
||||
'el-checkbox-group': el => {
|
||||
const { tag, disabled, vModel } = attrBuilder(el)
|
||||
const size = `size="${el.size}"`
|
||||
const min = el.min ? `:min="${el.min}"` : ''
|
||||
const max = el.max ? `:max="${el.max}"` : ''
|
||||
let child = buildElCheckboxGroupChild(el)
|
||||
|
||||
if (child) child = `\n${child}\n` // 换行
|
||||
return `<${tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${tag}>`
|
||||
},
|
||||
'el-switch': el => {
|
||||
const { tag, disabled, vModel } = attrBuilder(el)
|
||||
const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : ''
|
||||
const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : ''
|
||||
const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : ''
|
||||
const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : ''
|
||||
const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : ''
|
||||
const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : ''
|
||||
|
||||
return `<${tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${tag}>`
|
||||
},
|
||||
'el-cascader': el => {
|
||||
const {
|
||||
tag, disabled, vModel, clearable, placeholder, width
|
||||
} = attrBuilder(el)
|
||||
const options = el.options ? `:options="${el.__vModel__}Options"` : ''
|
||||
const props = el.props ? `:props="${el.__vModel__}Props"` : ''
|
||||
const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"'
|
||||
const filterable = el.filterable ? 'filterable' : ''
|
||||
const separator = el.separator === '/' ? '' : `separator="${el.separator}"`
|
||||
|
||||
return `<${tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${tag}>`
|
||||
},
|
||||
'el-slider': el => {
|
||||
const { tag, disabled, vModel } = attrBuilder(el)
|
||||
const min = el.min ? `:min='${el.min}'` : ''
|
||||
const max = el.max ? `:max='${el.max}'` : ''
|
||||
const step = el.step ? `:step='${el.step}'` : ''
|
||||
const range = el.range ? 'range' : ''
|
||||
const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : ''
|
||||
|
||||
return `<${tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${tag}>`
|
||||
},
|
||||
'el-time-picker': el => {
|
||||
const {
|
||||
tag, disabled, vModel, clearable, placeholder, width
|
||||
} = attrBuilder(el)
|
||||
const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
|
||||
const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
|
||||
const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
|
||||
const isRange = el['is-range'] ? 'is-range' : ''
|
||||
const format = el.format ? `format="${el.format}"` : ''
|
||||
const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
|
||||
const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : ''
|
||||
|
||||
return `<${tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${tag}>`
|
||||
},
|
||||
'el-date-picker': el => {
|
||||
const {
|
||||
tag, disabled, vModel, clearable, placeholder, width
|
||||
} = attrBuilder(el)
|
||||
const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
|
||||
const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
|
||||
const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
|
||||
const format = el.format ? `format="${el.format}"` : ''
|
||||
const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
|
||||
const type = el.type === 'date' ? '' : `type="${el.type}"`
|
||||
const readonly = el.readonly ? 'readonly' : ''
|
||||
|
||||
return `<${tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${tag}>`
|
||||
},
|
||||
'el-rate': el => {
|
||||
const { tag, disabled, vModel } = attrBuilder(el)
|
||||
const max = el.max ? `:max='${el.max}'` : ''
|
||||
const allowHalf = el['allow-half'] ? 'allow-half' : ''
|
||||
const showText = el['show-text'] ? 'show-text' : ''
|
||||
const showScore = el['show-score'] ? 'show-score' : ''
|
||||
|
||||
return `<${tag} ${vModel} ${max} ${allowHalf} ${showText} ${showScore} ${disabled}></${tag}>`
|
||||
},
|
||||
'el-color-picker': el => {
|
||||
const { tag, disabled, vModel } = attrBuilder(el)
|
||||
const size = `size="${el.size}"`
|
||||
const showAlpha = el['show-alpha'] ? 'show-alpha' : ''
|
||||
const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : ''
|
||||
|
||||
return `<${tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${tag}>`
|
||||
},
|
||||
'el-upload': el => {
|
||||
const { tag } = el.__config__
|
||||
const disabled = el.disabled ? ':disabled=\'true\'' : ''
|
||||
const action = el.action ? `:action="${el.__vModel__}Action"` : ''
|
||||
const multiple = el.multiple ? 'multiple' : ''
|
||||
const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : ''
|
||||
const accept = el.accept ? `accept="${el.accept}"` : ''
|
||||
const name = el.name !== 'file' ? `name="${el.name}"` : ''
|
||||
const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : ''
|
||||
const beforeUpload = `:before-upload="${el.__vModel__}BeforeUpload"`
|
||||
const fileList = `:file-list="${el.__vModel__}fileList"`
|
||||
const ref = `ref="${el.__vModel__}"`
|
||||
let child = buildElUploadChild(el)
|
||||
|
||||
if (child) child = `\n${child}\n` // 换行
|
||||
return `<${tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${tag}>`
|
||||
},
|
||||
tinymce: el => {
|
||||
const { tag, vModel, placeholder } = attrBuilder(el)
|
||||
const height = el.height ? `:height="${el.height}"` : ''
|
||||
const branding = el.branding ? `:branding="${el.branding}"` : ''
|
||||
return `<${tag} ${vModel} ${placeholder} ${height} ${branding}></${tag}>`
|
||||
}
|
||||
}
|
||||
|
||||
function attrBuilder(el) {
|
||||
return {
|
||||
tag: el.__config__.tag,
|
||||
vModel: `v-model="${confGlobal.formModel}.${el.__vModel__}"`,
|
||||
clearable: el.clearable ? 'clearable' : '',
|
||||
placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '',
|
||||
width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '',
|
||||
disabled: el.disabled ? ':disabled=\'true\'' : ''
|
||||
}
|
||||
}
|
||||
|
||||
// el-buttin 子级
|
||||
function buildElButtonChild(scheme) {
|
||||
const children = []
|
||||
const slot = scheme.__slot__ || {}
|
||||
if (slot.default) {
|
||||
children.push(slot.default)
|
||||
}
|
||||
return children.join('\n')
|
||||
}
|
||||
|
||||
// el-input 子级
|
||||
function buildElInputChild(scheme) {
|
||||
const children = []
|
||||
const slot = scheme.__slot__
|
||||
if (slot && slot.prepend) {
|
||||
children.push(`<template slot="prepend">${slot.prepend}</template>`)
|
||||
}
|
||||
if (slot && slot.append) {
|
||||
children.push(`<template slot="append">${slot.append}</template>`)
|
||||
}
|
||||
return children.join('\n')
|
||||
}
|
||||
|
||||
// el-select 子级
|
||||
function buildElSelectChild(scheme) {
|
||||
const children = []
|
||||
const slot = scheme.__slot__
|
||||
if (slot && slot.options && slot.options.length) {
|
||||
children.push(`<el-option v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`)
|
||||
}
|
||||
return children.join('\n')
|
||||
}
|
||||
|
||||
// el-radio-group 子级
|
||||
function buildElRadioGroupChild(scheme) {
|
||||
const children = []
|
||||
const slot = scheme.__slot__
|
||||
const config = scheme.__config__
|
||||
if (slot && slot.options && slot.options.length) {
|
||||
const tag = config.optionType === 'button' ? 'el-radio-button' : 'el-radio'
|
||||
const border = config.border ? 'border' : ''
|
||||
children.push(`<${tag} v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`)
|
||||
}
|
||||
return children.join('\n')
|
||||
}
|
||||
|
||||
// el-checkbox-group 子级
|
||||
function buildElCheckboxGroupChild(scheme) {
|
||||
const children = []
|
||||
const slot = scheme.__slot__
|
||||
const config = scheme.__config__
|
||||
if (slot && slot.options && slot.options.length) {
|
||||
const tag = config.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox'
|
||||
const border = config.border ? 'border' : ''
|
||||
children.push(`<${tag} v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`)
|
||||
}
|
||||
return children.join('\n')
|
||||
}
|
||||
|
||||
// el-upload 子级
|
||||
function buildElUploadChild(scheme) {
|
||||
const list = []
|
||||
const config = scheme.__config__
|
||||
if (scheme['list-type'] === 'picture-card') list.push('<i class="el-icon-plus"></i>')
|
||||
else list.push(`<el-button size="small" type="primary" icon="el-icon-upload">${config.buttonText}</el-button>`)
|
||||
if (config.showTip) list.push(`<div slot="tip" class="el-upload__tip">只能上传不超过 ${config.fileSize}${config.sizeUnit} 的${scheme.accept}文件</div>`)
|
||||
return list.join('\n')
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装html代码。【入口函数】
|
||||
* @param {Object} formConfig 整个表单配置
|
||||
* @param {String} type 生成类型,文件或弹窗等
|
||||
*/
|
||||
export function makeUpHtml(formConfig, type) {
|
||||
const htmlList = []
|
||||
confGlobal = formConfig
|
||||
// 判断布局是否都沾满了24个栅格,以备后续简化代码结构
|
||||
someSpanIsNot24 = formConfig.fields.some(item => item.__config__.span !== 24)
|
||||
// 遍历渲染每个组件成html
|
||||
formConfig.fields.forEach(el => {
|
||||
htmlList.push(layouts[el.__config__.layout](el))
|
||||
})
|
||||
const htmlStr = htmlList.join('\n')
|
||||
// 将组件代码放进form标签
|
||||
let temp = buildFormTemplate(formConfig, htmlStr, type)
|
||||
// dialog标签包裹代码
|
||||
if (type === 'dialog') {
|
||||
temp = dialogWrapper(temp)
|
||||
}
|
||||
confGlobal = null
|
||||
return temp
|
||||
}
|
271
src/components/generator/js.js
Normal file
271
src/components/generator/js.js
Normal file
@ -0,0 +1,271 @@
|
||||
import { isArray } from 'util'
|
||||
import { exportDefault, titleCase, deepClone } from '@/utils'
|
||||
import ruleTrigger from './ruleTrigger'
|
||||
|
||||
const units = {
|
||||
KB: '1024',
|
||||
MB: '1024 / 1024',
|
||||
GB: '1024 / 1024 / 1024'
|
||||
}
|
||||
let confGlobal
|
||||
const inheritAttrs = {
|
||||
file: '',
|
||||
dialog: 'inheritAttrs: false,'
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装js 【入口函数】
|
||||
* @param {Object} formConfig 整个表单配置
|
||||
* @param {String} type 生成类型,文件或弹窗等
|
||||
*/
|
||||
export function makeUpJs(formConfig, type) {
|
||||
confGlobal = formConfig = deepClone(formConfig)
|
||||
const dataList = []
|
||||
const ruleList = []
|
||||
const optionsList = []
|
||||
const propsList = []
|
||||
const methodList = mixinMethod(type)
|
||||
const uploadVarList = []
|
||||
const created = []
|
||||
|
||||
formConfig.fields.forEach(el => {
|
||||
buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created)
|
||||
})
|
||||
|
||||
const script = buildexport(
|
||||
formConfig,
|
||||
type,
|
||||
dataList.join('\n'),
|
||||
ruleList.join('\n'),
|
||||
optionsList.join('\n'),
|
||||
uploadVarList.join('\n'),
|
||||
propsList.join('\n'),
|
||||
methodList.join('\n'),
|
||||
created.join('\n')
|
||||
)
|
||||
confGlobal = null
|
||||
return script
|
||||
}
|
||||
|
||||
// 构建组件属性
|
||||
function buildAttributes(scheme, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created) {
|
||||
const config = scheme.__config__
|
||||
const slot = scheme.__slot__
|
||||
buildData(scheme, dataList)
|
||||
buildRules(scheme, ruleList)
|
||||
|
||||
// 特殊处理options属性
|
||||
if (scheme.options || (slot && slot.options && slot.options.length)) {
|
||||
buildOptions(scheme, optionsList)
|
||||
if (config.dataType === 'dynamic') {
|
||||
const model = `${scheme.__vModel__}Options`
|
||||
const options = titleCase(model)
|
||||
const methodName = `get${options}`
|
||||
buildOptionMethod(methodName, model, methodList, scheme)
|
||||
callInCreated(methodName, created)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理props
|
||||
if (scheme.props && scheme.props.props) {
|
||||
buildProps(scheme, propsList)
|
||||
}
|
||||
|
||||
// 处理el-upload的action
|
||||
if (scheme.action && config.tag === 'el-upload') {
|
||||
uploadVarList.push(
|
||||
`${scheme.__vModel__}Action: '${scheme.action}',
|
||||
${scheme.__vModel__}fileList: [],`
|
||||
)
|
||||
methodList.push(buildBeforeUpload(scheme))
|
||||
// 非自动上传时,生成手动上传的函数
|
||||
if (!scheme['auto-upload']) {
|
||||
methodList.push(buildSubmitUpload(scheme))
|
||||
}
|
||||
}
|
||||
|
||||
// 构建子级组件属性
|
||||
if (config.children) {
|
||||
config.children.forEach(item => {
|
||||
buildAttributes(item, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 在Created调用函数
|
||||
function callInCreated(methodName, created) {
|
||||
created.push(`this.${methodName}()`)
|
||||
}
|
||||
|
||||
// 混入处理函数
|
||||
function mixinMethod(type) {
|
||||
const list = []; const
|
||||
minxins = {
|
||||
file: confGlobal.formBtns ? {
|
||||
submitForm: `submitForm() {
|
||||
this.$refs['${confGlobal.formRef}'].validate(valid => {
|
||||
if(!valid) return
|
||||
// TODO 提交表单
|
||||
})
|
||||
},`,
|
||||
resetForm: `resetForm() {
|
||||
this.$refs['${confGlobal.formRef}'].resetFields()
|
||||
},`
|
||||
} : null,
|
||||
dialog: {
|
||||
onOpen: 'onOpen() {},',
|
||||
onClose: `onClose() {
|
||||
this.$refs['${confGlobal.formRef}'].resetFields()
|
||||
},`,
|
||||
close: `close() {
|
||||
this.$emit('update:visible', false)
|
||||
},`,
|
||||
handelConfirm: `handelConfirm() {
|
||||
this.$refs['${confGlobal.formRef}'].validate(valid => {
|
||||
if(!valid) return
|
||||
this.close()
|
||||
})
|
||||
},`
|
||||
}
|
||||
}
|
||||
|
||||
const methods = minxins[type]
|
||||
if (methods) {
|
||||
Object.keys(methods).forEach(key => {
|
||||
list.push(methods[key])
|
||||
})
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// 构建data
|
||||
function buildData(scheme, dataList) {
|
||||
const config = scheme.__config__
|
||||
if (scheme.__vModel__ === undefined) return
|
||||
const defaultValue = JSON.stringify(config.defaultValue)
|
||||
dataList.push(`${scheme.__vModel__}: ${defaultValue},`)
|
||||
}
|
||||
|
||||
// 构建校验规则
|
||||
function buildRules(scheme, ruleList) {
|
||||
const config = scheme.__config__
|
||||
if (scheme.__vModel__ === undefined) return
|
||||
const rules = []
|
||||
if (ruleTrigger[config.tag]) {
|
||||
if (config.required) {
|
||||
const type = isArray(config.defaultValue) ? 'type: \'array\',' : ''
|
||||
let message = isArray(config.defaultValue) ? `请至少选择一个${config.label}` : scheme.placeholder
|
||||
if (message === undefined) message = `${config.label}不能为空`
|
||||
rules.push(`{ required: true, ${type} message: '${message}', trigger: '${ruleTrigger[config.tag]}' }`)
|
||||
}
|
||||
if (config.regList && isArray(config.regList)) {
|
||||
config.regList.forEach(item => {
|
||||
if (item.pattern) {
|
||||
rules.push(
|
||||
`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${ruleTrigger[config.tag]}' }`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
ruleList.push(`${scheme.__vModel__}: [${rules.join(',')}],`)
|
||||
}
|
||||
}
|
||||
|
||||
// 构建options
|
||||
function buildOptions(scheme, optionsList) {
|
||||
if (scheme.__vModel__ === undefined) return
|
||||
// el-cascader直接有options属性,其他组件都是定义在slot中,所以有两处判断
|
||||
let { options } = scheme
|
||||
if (!options) options = scheme.__slot__.options
|
||||
if (scheme.__config__.dataType === 'dynamic') { options = [] }
|
||||
const str = `${scheme.__vModel__}Options: ${JSON.stringify(options)},`
|
||||
optionsList.push(str)
|
||||
}
|
||||
|
||||
function buildProps(scheme, propsList) {
|
||||
const str = `${scheme.__vModel__}Props: ${JSON.stringify(scheme.props.props)},`
|
||||
propsList.push(str)
|
||||
}
|
||||
|
||||
// el-upload的BeforeUpload
|
||||
function buildBeforeUpload(scheme) {
|
||||
const config = scheme.__config__
|
||||
const unitNum = units[config.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const
|
||||
returnList = []
|
||||
if (config.fileSize) {
|
||||
rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${config.fileSize}
|
||||
if(!isRightSize){
|
||||
this.$message.error('文件大小超过 ${config.fileSize}${config.sizeUnit}')
|
||||
}`
|
||||
returnList.push('isRightSize')
|
||||
}
|
||||
if (scheme.accept) {
|
||||
acceptCode = `let isAccept = new RegExp('${scheme.accept}').test(file.type)
|
||||
if(!isAccept){
|
||||
this.$message.error('应该选择${scheme.accept}类型的文件')
|
||||
}`
|
||||
returnList.push('isAccept')
|
||||
}
|
||||
const str = `${scheme.__vModel__}BeforeUpload(file) {
|
||||
${rightSizeCode}
|
||||
${acceptCode}
|
||||
return ${returnList.join('&&')}
|
||||
},`
|
||||
return returnList.length ? str : ''
|
||||
}
|
||||
|
||||
// el-upload的submit
|
||||
function buildSubmitUpload(scheme) {
|
||||
const str = `submitUpload() {
|
||||
this.$refs['${scheme.__vModel__}'].submit()
|
||||
},`
|
||||
return str
|
||||
}
|
||||
|
||||
function buildOptionMethod(methodName, model, methodList, scheme) {
|
||||
const config = scheme.__config__
|
||||
const str = `${methodName}() {
|
||||
// 注意:this.$axios是通过Vue.prototype.$axios = axios挂载产生的
|
||||
this.$axios({
|
||||
method: '${config.method}',
|
||||
url: '${config.url}'
|
||||
}).then(resp => {
|
||||
var { data } = resp
|
||||
this.${model} = data.${config.dataPath}
|
||||
})
|
||||
},`
|
||||
methodList.push(str)
|
||||
}
|
||||
|
||||
// js整体拼接
|
||||
function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods, created) {
|
||||
const str = `${exportDefault}{
|
||||
${inheritAttrs[type]}
|
||||
components: {},
|
||||
props: [],
|
||||
data () {
|
||||
return {
|
||||
${conf.formModel}: {
|
||||
${data}
|
||||
},
|
||||
${conf.formRules}: {
|
||||
${rules}
|
||||
},
|
||||
${uploadVar}
|
||||
${selectOptions}
|
||||
${props}
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created () {
|
||||
${created}
|
||||
},
|
||||
mounted () {},
|
||||
methods: {
|
||||
${methods}
|
||||
}
|
||||
}`
|
||||
return str
|
||||
}
|
16
src/components/generator/ruleTrigger.js
Normal file
16
src/components/generator/ruleTrigger.js
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* 用于生成表单校验,指定正则规则的触发方式。
|
||||
* 未在此处声明无触发方式的组件将不生成rule!!
|
||||
*/
|
||||
export default {
|
||||
'el-input': 'blur',
|
||||
'el-input-number': 'blur',
|
||||
'el-select': 'change',
|
||||
'el-radio-group': 'change',
|
||||
'el-checkbox-group': 'change',
|
||||
'el-cascader': 'change',
|
||||
'el-time-picker': 'change',
|
||||
'el-date-picker': 'change',
|
||||
'el-rate': 'change',
|
||||
tinymce: 'blur'
|
||||
}
|
3
src/components/tinymce/README.md
Normal file
3
src/components/tinymce/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
## 简介
|
||||
富文本编辑器tinymce的一个vue版本封装。使用cdn动态脚本引入的方式加载。
|
||||
|
8
src/components/tinymce/config.js
Normal file
8
src/components/tinymce/config.js
Normal file
@ -0,0 +1,8 @@
|
||||
/* eslint-disable max-len */
|
||||
|
||||
export const plugins = [
|
||||
'advlist anchor autolink autosave code codesample directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textpattern visualblocks visualchars wordcount'
|
||||
]
|
||||
export const toolbar = [
|
||||
'code searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote removeformat subscript superscript codesample hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen'
|
||||
]
|
38
src/components/tinymce/example/Index.vue
Normal file
38
src/components/tinymce/example/Index.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div>
|
||||
<Tinymce v-model="defaultValue" :height="300" placeholder="在这里输入文字" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Tinymce from '../index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Tinymce
|
||||
},
|
||||
props: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defaultValue: '<p>配置文档参阅:http://tinymce.ax-z.cn</p>'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
3
src/components/tinymce/index.js
Normal file
3
src/components/tinymce/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
import Index from './index.vue'
|
||||
|
||||
export default Index
|
88
src/components/tinymce/index.vue
Normal file
88
src/components/tinymce/index.vue
Normal file
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<textarea :id="tinymceId" style="visibility: hidden" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import loadTinymce from '@/utils/loadTinymce'
|
||||
import { plugins, toolbar } from './config'
|
||||
import { debounce } from 'throttle-debounce'
|
||||
|
||||
let num = 1
|
||||
|
||||
export default {
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: () => {
|
||||
num === 10000 && (num = 1)
|
||||
return `tinymce${+new Date()}${num++}`
|
||||
}
|
||||
},
|
||||
value: {
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tinymceId: this.id
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
loadTinymce(tinymce => {
|
||||
// eslint-disable-next-line global-require
|
||||
require('./zh_CN')
|
||||
let conf = {
|
||||
selector: `#${this.tinymceId}`,
|
||||
language: 'zh_CN',
|
||||
menubar: 'file edit insert view format table',
|
||||
plugins,
|
||||
toolbar,
|
||||
height: 300,
|
||||
branding: false,
|
||||
object_resizing: false,
|
||||
end_container_on_empty_block: true,
|
||||
powerpaste_word_import: 'clean',
|
||||
code_dialog_height: 450,
|
||||
code_dialog_width: 1000,
|
||||
advlist_bullet_styles: 'square',
|
||||
advlist_number_styles: 'default',
|
||||
default_link_target: '_blank',
|
||||
link_title: false,
|
||||
nonbreaking_force_tab: true
|
||||
}
|
||||
conf = Object.assign(conf, this.$attrs)
|
||||
conf.init_instance_callback = editor => {
|
||||
if (this.value) editor.setContent(this.value)
|
||||
this.vModel(editor)
|
||||
}
|
||||
tinymce.init(conf)
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
this.destroyTinymce()
|
||||
},
|
||||
methods: {
|
||||
vModel(editor) {
|
||||
// 控制连续写入时setContent的触发频率
|
||||
const debounceSetContent = debounce(250, editor.setContent)
|
||||
this.$watch('value', (val, prevVal) => {
|
||||
if (editor && val !== prevVal && val !== editor.getContent()) {
|
||||
if (typeof val !== 'string') val = val.toString()
|
||||
debounceSetContent.call(editor, val)
|
||||
}
|
||||
})
|
||||
|
||||
editor.on('change keyup undo redo', () => {
|
||||
this.$emit('input', editor.getContent())
|
||||
})
|
||||
},
|
||||
destroyTinymce() {
|
||||
if (!window.tinymce) return
|
||||
const tinymce = window.tinymce.get(this.tinymceId)
|
||||
if (tinymce) {
|
||||
tinymce.destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
28
src/components/tinymce/package.json
Normal file
28
src/components/tinymce/package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "form-gen-tinymce",
|
||||
"version": "1.0.0",
|
||||
"description": "富文本编辑器tinymce的一个vue版本封装。使用cdn动态脚本引入的方式加载。",
|
||||
"main": "lib/form-gen-tinymce.umd.js",
|
||||
"directories": {
|
||||
"example": "example"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/JakHuang/form-generator.git"
|
||||
},
|
||||
"keywords": [
|
||||
"tinymce-vue"
|
||||
],
|
||||
"dependencies": {
|
||||
"throttle-debounce": "^2.1.0"
|
||||
},
|
||||
"author": "jakHuang",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/JakHuang/form-generator/issues"
|
||||
},
|
||||
"homepage": "https://github.com/JakHuang/form-generator/blob/dev/src/components/tinymce"
|
||||
}
|
420
src/components/tinymce/zh_CN.js
Normal file
420
src/components/tinymce/zh_CN.js
Normal file
@ -0,0 +1,420 @@
|
||||
/* eslint-disable */
|
||||
tinymce.addI18n('zh_CN',{
|
||||
"Redo": "\u91cd\u505a",
|
||||
"Undo": "\u64a4\u9500",
|
||||
"Cut": "\u526a\u5207",
|
||||
"Copy": "\u590d\u5236",
|
||||
"Paste": "\u7c98\u8d34",
|
||||
"Select all": "\u5168\u9009",
|
||||
"New document": "\u65b0\u6587\u4ef6",
|
||||
"Ok": "\u786e\u5b9a",
|
||||
"Cancel": "\u53d6\u6d88",
|
||||
"Visual aids": "\u7f51\u683c\u7ebf",
|
||||
"Bold": "\u7c97\u4f53",
|
||||
"Italic": "\u659c\u4f53",
|
||||
"Underline": "\u4e0b\u5212\u7ebf",
|
||||
"Strikethrough": "\u5220\u9664\u7ebf",
|
||||
"Superscript": "\u4e0a\u6807",
|
||||
"Subscript": "\u4e0b\u6807",
|
||||
"Clear formatting": "\u6e05\u9664\u683c\u5f0f",
|
||||
"Align left": "\u5de6\u8fb9\u5bf9\u9f50",
|
||||
"Align center": "\u4e2d\u95f4\u5bf9\u9f50",
|
||||
"Align right": "\u53f3\u8fb9\u5bf9\u9f50",
|
||||
"Justify": "\u4e24\u7aef\u5bf9\u9f50",
|
||||
"Bullet list": "\u9879\u76ee\u7b26\u53f7",
|
||||
"Numbered list": "\u7f16\u53f7\u5217\u8868",
|
||||
"Decrease indent": "\u51cf\u5c11\u7f29\u8fdb",
|
||||
"Increase indent": "\u589e\u52a0\u7f29\u8fdb",
|
||||
"Close": "\u5173\u95ed",
|
||||
"Formats": "\u683c\u5f0f",
|
||||
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\u3002",
|
||||
"Headers": "\u6807\u9898",
|
||||
"Header 1": "\u6807\u98981",
|
||||
"Header 2": "\u6807\u98982",
|
||||
"Header 3": "\u6807\u98983",
|
||||
"Header 4": "\u6807\u98984",
|
||||
"Header 5": "\u6807\u98985",
|
||||
"Header 6": "\u6807\u98986",
|
||||
"Headings": "\u6807\u9898",
|
||||
"Heading 1": "\u6807\u98981",
|
||||
"Heading 2": "\u6807\u98982",
|
||||
"Heading 3": "\u6807\u98983",
|
||||
"Heading 4": "\u6807\u98984",
|
||||
"Heading 5": "\u6807\u98985",
|
||||
"Heading 6": "\u6807\u98986",
|
||||
"Preformatted": "\u9884\u5148\u683c\u5f0f\u5316\u7684",
|
||||
"Div": "Div",
|
||||
"Pre": "Pre",
|
||||
"Code": "\u4ee3\u7801",
|
||||
"Paragraph": "\u6bb5\u843d",
|
||||
"Blockquote": "\u5f15\u6587\u533a\u5757",
|
||||
"Inline": "\u6587\u672c",
|
||||
"Blocks": "\u57fa\u5757",
|
||||
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002",
|
||||
"Fonts": "\u5b57\u4f53",
|
||||
"Font Sizes": "\u5b57\u53f7",
|
||||
"Class": "\u7c7b\u578b",
|
||||
"Browse for an image": "\u6d4f\u89c8\u56fe\u50cf",
|
||||
"OR": "\u6216",
|
||||
"Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64",
|
||||
"Upload": "\u4e0a\u4f20",
|
||||
"Block": "\u5757",
|
||||
"Align": "\u5bf9\u9f50",
|
||||
"Default": "\u9ed8\u8ba4",
|
||||
"Circle": "\u7a7a\u5fc3\u5706",
|
||||
"Disc": "\u5b9e\u5fc3\u5706",
|
||||
"Square": "\u65b9\u5757",
|
||||
"Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd",
|
||||
"Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd",
|
||||
"Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd",
|
||||
"Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd",
|
||||
"Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd",
|
||||
"Anchor...": "\u951a\u70b9...",
|
||||
"Name": "\u540d\u79f0",
|
||||
"Id": "\u6807\u8bc6\u7b26",
|
||||
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002",
|
||||
"You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f",
|
||||
"Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f",
|
||||
"Special character...": "\u7279\u6b8a\u5b57\u7b26...",
|
||||
"Source code": "\u6e90\u4ee3\u7801",
|
||||
"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b",
|
||||
"Language": "\u8bed\u8a00",
|
||||
"Code sample...": "\u793a\u4f8b\u4ee3\u7801...",
|
||||
"Color Picker": "\u9009\u8272\u5668",
|
||||
"R": "R",
|
||||
"G": "G",
|
||||
"B": "B",
|
||||
"Left to right": "\u4ece\u5de6\u5230\u53f3",
|
||||
"Right to left": "\u4ece\u53f3\u5230\u5de6",
|
||||
"Emoticons...": "\u8868\u60c5\u7b26\u53f7...",
|
||||
"Metadata and Document Properties": "\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027",
|
||||
"Title": "\u6807\u9898",
|
||||
"Keywords": "\u5173\u952e\u8bcd",
|
||||
"Description": "\u63cf\u8ff0",
|
||||
"Robots": "\u673a\u5668\u4eba",
|
||||
"Author": "\u4f5c\u8005",
|
||||
"Encoding": "\u7f16\u7801",
|
||||
"Fullscreen": "\u5168\u5c4f",
|
||||
"Action": "\u64cd\u4f5c",
|
||||
"Shortcut": "\u5feb\u6377\u952e",
|
||||
"Help": "\u5e2e\u52a9",
|
||||
"Address": "\u5730\u5740",
|
||||
"Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f",
|
||||
"Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f",
|
||||
"Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84",
|
||||
"Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355",
|
||||
"Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
|
||||
"Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
|
||||
"Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
|
||||
"Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):",
|
||||
"Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a",
|
||||
"Learn more...": "\u4e86\u89e3\u66f4\u591a...",
|
||||
"You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}",
|
||||
"Plugins": "\u63d2\u4ef6",
|
||||
"Handy Shortcuts": "\u5feb\u6377\u952e",
|
||||
"Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf",
|
||||
"Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247",
|
||||
"Image description": "\u56fe\u7247\u63cf\u8ff0",
|
||||
"Source": "\u5730\u5740",
|
||||
"Dimensions": "\u5927\u5c0f",
|
||||
"Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4",
|
||||
"General": "\u666e\u901a",
|
||||
"Advanced": "\u9ad8\u7ea7",
|
||||
"Style": "\u6837\u5f0f",
|
||||
"Vertical space": "\u5782\u76f4\u8fb9\u8ddd",
|
||||
"Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd",
|
||||
"Border": "\u8fb9\u6846",
|
||||
"Insert image": "\u63d2\u5165\u56fe\u7247",
|
||||
"Image...": "\u56fe\u7247...",
|
||||
"Image list": "\u56fe\u7247\u5217\u8868",
|
||||
"Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c",
|
||||
"Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c",
|
||||
"Flip vertically": "\u5782\u76f4\u7ffb\u8f6c",
|
||||
"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c",
|
||||
"Edit image": "\u7f16\u8f91\u56fe\u7247",
|
||||
"Image options": "\u56fe\u7247\u9009\u9879",
|
||||
"Zoom in": "\u653e\u5927",
|
||||
"Zoom out": "\u7f29\u5c0f",
|
||||
"Crop": "\u88c1\u526a",
|
||||
"Resize": "\u8c03\u6574\u5927\u5c0f",
|
||||
"Orientation": "\u65b9\u5411",
|
||||
"Brightness": "\u4eae\u5ea6",
|
||||
"Sharpen": "\u9510\u5316",
|
||||
"Contrast": "\u5bf9\u6bd4\u5ea6",
|
||||
"Color levels": "\u989c\u8272\u5c42\u6b21",
|
||||
"Gamma": "\u4f3d\u9a6c\u503c",
|
||||
"Invert": "\u53cd\u8f6c",
|
||||
"Apply": "\u5e94\u7528",
|
||||
"Back": "\u540e\u9000",
|
||||
"Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4",
|
||||
"Date\/time": "\u65e5\u671f\/\u65f6\u95f4",
|
||||
"Insert\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
|
||||
"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
|
||||
"Text to display": "\u663e\u793a\u6587\u5b57",
|
||||
"Url": "\u5730\u5740",
|
||||
"Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...",
|
||||
"Current window": "\u5f53\u524d\u7a97\u53e3",
|
||||
"None": "\u65e0",
|
||||
"New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00",
|
||||
"Remove link": "\u5220\u9664\u94fe\u63a5",
|
||||
"Anchors": "\u951a\u70b9",
|
||||
"Link...": "\u94fe\u63a5...",
|
||||
"Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5",
|
||||
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f",
|
||||
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f",
|
||||
"Link list": "\u94fe\u63a5\u5217\u8868",
|
||||
"Insert video": "\u63d2\u5165\u89c6\u9891",
|
||||
"Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891",
|
||||
"Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53",
|
||||
"Alternative source": "\u955c\u50cf",
|
||||
"Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740",
|
||||
"Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)",
|
||||
"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:",
|
||||
"Embed": "\u5185\u5d4c",
|
||||
"Media...": "\u591a\u5a92\u4f53...",
|
||||
"Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c",
|
||||
"Page break": "\u5206\u9875\u7b26",
|
||||
"Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c",
|
||||
"Preview": "\u9884\u89c8",
|
||||
"Print...": "\u6253\u5370...",
|
||||
"Save": "\u4fdd\u5b58",
|
||||
"Find": "\u67e5\u627e",
|
||||
"Replace with": "\u66ff\u6362\u4e3a",
|
||||
"Replace": "\u66ff\u6362",
|
||||
"Replace all": "\u5168\u90e8\u66ff\u6362",
|
||||
"Previous": "\u4e0a\u4e00\u4e2a",
|
||||
"Next": "\u4e0b\u4e00\u4e2a",
|
||||
"Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...",
|
||||
"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.",
|
||||
"Match case": "\u533a\u5206\u5927\u5c0f\u5199",
|
||||
"Find whole words only": "\u5168\u5b57\u5339\u914d",
|
||||
"Spell check": "\u62fc\u5199\u68c0\u67e5",
|
||||
"Ignore": "\u5ffd\u7565",
|
||||
"Ignore all": "\u5168\u90e8\u5ffd\u7565",
|
||||
"Finish": "\u5b8c\u6210",
|
||||
"Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178",
|
||||
"Insert table": "\u63d2\u5165\u8868\u683c",
|
||||
"Table properties": "\u8868\u683c\u5c5e\u6027",
|
||||
"Delete table": "\u5220\u9664\u8868\u683c",
|
||||
"Cell": "\u5355\u5143\u683c",
|
||||
"Row": "\u884c",
|
||||
"Column": "\u5217",
|
||||
"Cell properties": "\u5355\u5143\u683c\u5c5e\u6027",
|
||||
"Merge cells": "\u5408\u5e76\u5355\u5143\u683c",
|
||||
"Split cell": "\u62c6\u5206\u5355\u5143\u683c",
|
||||
"Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165",
|
||||
"Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165",
|
||||
"Delete row": "\u5220\u9664\u884c",
|
||||
"Row properties": "\u884c\u5c5e\u6027",
|
||||
"Cut row": "\u526a\u5207\u884c",
|
||||
"Copy row": "\u590d\u5236\u884c",
|
||||
"Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9",
|
||||
"Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9",
|
||||
"Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165",
|
||||
"Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165",
|
||||
"Delete column": "\u5220\u9664\u5217",
|
||||
"Cols": "\u5217",
|
||||
"Rows": "\u884c",
|
||||
"Width": "\u5bbd",
|
||||
"Height": "\u9ad8",
|
||||
"Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd",
|
||||
"Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd",
|
||||
"Show caption": "\u663e\u793a\u6807\u9898",
|
||||
"Left": "\u5de6\u5bf9\u9f50",
|
||||
"Center": "\u5c45\u4e2d",
|
||||
"Right": "\u53f3\u5bf9\u9f50",
|
||||
"Cell type": "\u5355\u5143\u683c\u7c7b\u578b",
|
||||
"Scope": "\u8303\u56f4",
|
||||
"Alignment": "\u5bf9\u9f50\u65b9\u5f0f",
|
||||
"H Align": "\u6c34\u5e73\u5bf9\u9f50",
|
||||
"V Align": "\u5782\u76f4\u5bf9\u9f50",
|
||||
"Top": "\u9876\u90e8\u5bf9\u9f50",
|
||||
"Middle": "\u5782\u76f4\u5c45\u4e2d",
|
||||
"Bottom": "\u5e95\u90e8\u5bf9\u9f50",
|
||||
"Header cell": "\u8868\u5934\u5355\u5143\u683c",
|
||||
"Row group": "\u884c\u7ec4",
|
||||
"Column group": "\u5217\u7ec4",
|
||||
"Row type": "\u884c\u7c7b\u578b",
|
||||
"Header": "\u8868\u5934",
|
||||
"Body": "\u8868\u4f53",
|
||||
"Footer": "\u8868\u5c3e",
|
||||
"Border color": "\u8fb9\u6846\u989c\u8272",
|
||||
"Insert template...": "\u63d2\u5165\u6a21\u677f...",
|
||||
"Templates": "\u6a21\u677f",
|
||||
"Template": "\u6a21\u677f",
|
||||
"Text color": "\u6587\u5b57\u989c\u8272",
|
||||
"Background color": "\u80cc\u666f\u8272",
|
||||
"Custom...": "\u81ea\u5b9a\u4e49...",
|
||||
"Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272",
|
||||
"No color": "\u65e0",
|
||||
"Remove color": "\u79fb\u9664\u989c\u8272",
|
||||
"Table of Contents": "\u5185\u5bb9\u5217\u8868",
|
||||
"Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846",
|
||||
"Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26",
|
||||
"Word count": "\u5b57\u6570",
|
||||
"Count": "\u8ba1\u6570",
|
||||
"Document": "\u6587\u6863",
|
||||
"Selection": "\u9009\u62e9",
|
||||
"Words": "\u5355\u8bcd",
|
||||
"Words: {0}": "\u5b57\u6570\uff1a{0}",
|
||||
"{0} words": "{0} \u5b57",
|
||||
"File": "\u6587\u4ef6",
|
||||
"Edit": "\u7f16\u8f91",
|
||||
"Insert": "\u63d2\u5165",
|
||||
"View": "\u89c6\u56fe",
|
||||
"Format": "\u683c\u5f0f",
|
||||
"Table": "\u8868\u683c",
|
||||
"Tools": "\u5de5\u5177",
|
||||
"Powered by {0}": "\u7531{0}\u9a71\u52a8",
|
||||
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9",
|
||||
"Image title": "\u56fe\u7247\u6807\u9898",
|
||||
"Border width": "\u8fb9\u6846\u5bbd\u5ea6",
|
||||
"Border style": "\u8fb9\u6846\u6837\u5f0f",
|
||||
"Error": "\u9519\u8bef",
|
||||
"Warn": "\u8b66\u544a",
|
||||
"Valid": "\u6709\u6548",
|
||||
"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846",
|
||||
"Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002",
|
||||
"System Font": "\u7cfb\u7edf\u5b57\u4f53",
|
||||
"Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}",
|
||||
"Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}",
|
||||
"Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}",
|
||||
"Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}",
|
||||
"example": "\u793a\u4f8b",
|
||||
"Search": "\u641c\u7d22",
|
||||
"All": "\u5168\u90e8",
|
||||
"Currency": "\u8d27\u5e01",
|
||||
"Text": "\u6587\u5b57",
|
||||
"Quotations": "\u5f15\u7528",
|
||||
"Mathematical": "\u6570\u5b66",
|
||||
"Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145",
|
||||
"Symbols": "\u7b26\u53f7",
|
||||
"Arrows": "\u7bad\u5934",
|
||||
"User Defined": "\u81ea\u5b9a\u4e49",
|
||||
"dollar sign": "\u7f8e\u5143\u7b26\u53f7",
|
||||
"currency sign": "\u8d27\u5e01\u7b26\u53f7",
|
||||
"euro-currency sign": "\u6b27\u5143\u7b26\u53f7",
|
||||
"colon sign": "\u5192\u53f7",
|
||||
"cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7",
|
||||
"french franc sign": "\u6cd5\u90ce\u7b26\u53f7",
|
||||
"lira sign": "\u91cc\u62c9\u7b26\u53f7",
|
||||
"mill sign": "\u5bc6\u5c14\u7b26\u53f7",
|
||||
"naira sign": "\u5948\u62c9\u7b26\u53f7",
|
||||
"peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7",
|
||||
"rupee sign": "\u5362\u6bd4\u7b26\u53f7",
|
||||
"won sign": "\u97e9\u5143\u7b26\u53f7",
|
||||
"new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7",
|
||||
"dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7",
|
||||
"kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7",
|
||||
"tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7",
|
||||
"drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7",
|
||||
"german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7",
|
||||
"peso sign": "\u6bd4\u7d22\u7b26\u53f7",
|
||||
"guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7",
|
||||
"austral sign": "\u6fb3\u5143\u7b26\u53f7",
|
||||
"hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7",
|
||||
"cedi sign": "\u585e\u5730\u7b26\u53f7",
|
||||
"livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7",
|
||||
"spesmilo sign": "spesmilo\u7b26\u53f7",
|
||||
"tenge sign": "\u575a\u6208\u7b26\u53f7",
|
||||
"indian rupee sign": "\u5370\u5ea6\u5362\u6bd4",
|
||||
"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9",
|
||||
"nordic mark sign": "\u5317\u6b27\u9a6c\u514b",
|
||||
"manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7",
|
||||
"ruble sign": "\u5362\u5e03\u7b26\u53f7",
|
||||
"yen character": "\u65e5\u5143\u5b57\u6837",
|
||||
"yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837",
|
||||
"yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09",
|
||||
"yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09",
|
||||
"Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...",
|
||||
"Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7",
|
||||
"People": "\u4eba\u7c7b",
|
||||
"Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136",
|
||||
"Food and Drink": "\u98df\u7269\u548c\u996e\u54c1",
|
||||
"Activity": "\u6d3b\u52a8",
|
||||
"Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9",
|
||||
"Objects": "\u7269\u4ef6",
|
||||
"Flags": "\u65d7\u5e1c",
|
||||
"Characters": "\u5b57\u7b26",
|
||||
"Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)",
|
||||
"{0} characters": "{0} \u4e2a\u5b57\u7b26",
|
||||
"Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002",
|
||||
"Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002",
|
||||
"Update": "\u66f4\u65b0",
|
||||
"Color swatch": "\u989c\u8272\u6837\u672c",
|
||||
"Turquoise": "\u9752\u7eff\u8272",
|
||||
"Green": "\u7eff\u8272",
|
||||
"Blue": "\u84dd\u8272",
|
||||
"Purple": "\u7d2b\u8272",
|
||||
"Navy Blue": "\u6d77\u519b\u84dd",
|
||||
"Dark Turquoise": "\u6df1\u84dd\u7eff\u8272",
|
||||
"Dark Green": "\u6df1\u7eff\u8272",
|
||||
"Medium Blue": "\u4e2d\u84dd\u8272",
|
||||
"Medium Purple": "\u4e2d\u7d2b\u8272",
|
||||
"Midnight Blue": "\u6df1\u84dd\u8272",
|
||||
"Yellow": "\u9ec4\u8272",
|
||||
"Orange": "\u6a59\u8272",
|
||||
"Red": "\u7ea2\u8272",
|
||||
"Light Gray": "\u6d45\u7070\u8272",
|
||||
"Gray": "\u7070\u8272",
|
||||
"Dark Yellow": "\u6697\u9ec4\u8272",
|
||||
"Dark Orange": "\u6df1\u6a59\u8272",
|
||||
"Dark Red": "\u6df1\u7ea2\u8272",
|
||||
"Medium Gray": "\u4e2d\u7070\u8272",
|
||||
"Dark Gray": "\u6df1\u7070\u8272",
|
||||
"Light Green": "\u6d45\u7eff\u8272",
|
||||
"Light Yellow": "\u6d45\u9ec4\u8272",
|
||||
"Light Red": "\u6d45\u7ea2\u8272",
|
||||
"Light Purple": "\u6d45\u7d2b\u8272",
|
||||
"Light Blue": "\u6d45\u84dd\u8272",
|
||||
"Dark Purple": "\u6df1\u7d2b\u8272",
|
||||
"Dark Blue": "\u6df1\u84dd\u8272",
|
||||
"Black": "\u9ed1\u8272",
|
||||
"White": "\u767d\u8272",
|
||||
"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f",
|
||||
"Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846",
|
||||
"history": "\u5386\u53f2",
|
||||
"styles": "\u6837\u5f0f",
|
||||
"formatting": "\u683c\u5f0f\u5316",
|
||||
"alignment": "\u5bf9\u9f50",
|
||||
"indentation": "\u7f29\u8fdb",
|
||||
"permanent pen": "\u8bb0\u53f7\u7b14",
|
||||
"comments": "\u5907\u6ce8",
|
||||
"Format Painter": "\u683c\u5f0f\u5237",
|
||||
"Insert\/edit iframe": "\u63d2\u5165\/\u7f16\u8f91\u6846\u67b6",
|
||||
"Capitalization": "\u5927\u5199",
|
||||
"lowercase": "\u5c0f\u5199",
|
||||
"UPPERCASE": "\u5927\u5199",
|
||||
"Title Case": "\u9996\u5b57\u6bcd\u5927\u5199",
|
||||
"Permanent Pen Properties": "\u6c38\u4e45\u7b14\u5c5e\u6027",
|
||||
"Permanent pen properties...": "\u6c38\u4e45\u7b14\u5c5e\u6027...",
|
||||
"Font": "\u5b57\u4f53",
|
||||
"Size": "\u5b57\u53f7",
|
||||
"More...": "\u66f4\u591a...",
|
||||
"Spellcheck Language": "\u62fc\u5199\u68c0\u67e5\u8bed\u8a00",
|
||||
"Select...": "\u9009\u62e9...",
|
||||
"Preferences": "\u9996\u9009\u9879",
|
||||
"Yes": "\u662f",
|
||||
"No": "\u5426",
|
||||
"Keyboard Navigation": "\u952e\u76d8\u6307\u5f15",
|
||||
"Version": "\u7248\u672c",
|
||||
"Anchor": "\u951a\u70b9",
|
||||
"Special character": "\u7279\u6b8a\u7b26\u53f7",
|
||||
"Code sample": "\u4ee3\u7801\u793a\u4f8b",
|
||||
"Color": "\u989c\u8272",
|
||||
"Emoticons": "\u8868\u60c5",
|
||||
"Document properties": "\u6587\u6863\u5c5e\u6027",
|
||||
"Image": "\u56fe\u7247",
|
||||
"Insert link": "\u63d2\u5165\u94fe\u63a5",
|
||||
"Target": "\u6253\u5f00\u65b9\u5f0f",
|
||||
"Link": "\u94fe\u63a5",
|
||||
"Poster": "\u5c01\u9762",
|
||||
"Media": "\u5a92\u4f53",
|
||||
"Print": "\u6253\u5370",
|
||||
"Prev": "\u4e0a\u4e00\u4e2a",
|
||||
"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362",
|
||||
"Whole words": "\u5168\u5b57\u5339\u914d",
|
||||
"Spellcheck": "\u62fc\u5199\u68c0\u67e5",
|
||||
"Caption": "\u6807\u9898",
|
||||
"Insert template": "\u63d2\u5165\u6a21\u677f"
|
||||
});
|
28
src/utils/loadBeautifier.js
Normal file
28
src/utils/loadBeautifier.js
Normal file
@ -0,0 +1,28 @@
|
||||
import loadScript from './loadScript'
|
||||
import ELEMENT from 'element-ui'
|
||||
import pluginsConfig from './pluginsConfig'
|
||||
|
||||
let beautifierObj
|
||||
|
||||
export default function loadBeautifier(cb) {
|
||||
const { beautifierUrl } = pluginsConfig
|
||||
if (beautifierObj) {
|
||||
cb(beautifierObj)
|
||||
return
|
||||
}
|
||||
|
||||
const loading = ELEMENT.Loading.service({
|
||||
fullscreen: true,
|
||||
lock: true,
|
||||
text: '格式化资源加载中...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(255, 255, 255, 0.5)'
|
||||
})
|
||||
|
||||
loadScript(beautifierUrl, () => {
|
||||
loading.close()
|
||||
// eslint-disable-next-line no-undef
|
||||
beautifierObj = beautifier
|
||||
cb(beautifierObj)
|
||||
})
|
||||
}
|
40
src/utils/loadMonaco.js
Normal file
40
src/utils/loadMonaco.js
Normal file
@ -0,0 +1,40 @@
|
||||
import loadScript from './loadScript'
|
||||
import ELEMENT from 'element-ui'
|
||||
import pluginsConfig from './pluginsConfig'
|
||||
|
||||
// monaco-editor单例
|
||||
let monacoEidtor
|
||||
|
||||
/**
|
||||
* 动态加载monaco-editor cdn资源
|
||||
* @param {Function} cb 回调,必填
|
||||
*/
|
||||
export default function loadMonaco(cb) {
|
||||
if (monacoEidtor) {
|
||||
cb(monacoEidtor)
|
||||
return
|
||||
}
|
||||
|
||||
const { monacoEditorUrl: vs } = pluginsConfig
|
||||
|
||||
// 使用element ui实现加载提示
|
||||
const loading = ELEMENT.Loading.service({
|
||||
fullscreen: true,
|
||||
lock: true,
|
||||
text: '编辑器资源初始化中...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(255, 255, 255, 0.5)'
|
||||
})
|
||||
|
||||
!window.require && (window.require = {})
|
||||
!window.require.paths && (window.require.paths = {})
|
||||
window.require.paths.vs = vs
|
||||
|
||||
loadScript(`${vs}/loader.js`, () => {
|
||||
window.require(['vs/editor/editor.main'], () => {
|
||||
loading.close()
|
||||
monacoEidtor = window.monaco
|
||||
cb(monacoEidtor)
|
||||
})
|
||||
})
|
||||
}
|
60
src/utils/loadScript.js
Normal file
60
src/utils/loadScript.js
Normal file
@ -0,0 +1,60 @@
|
||||
const callbacks = {}
|
||||
|
||||
/**
|
||||
* 加载一个远程脚本
|
||||
* @param {String} src 一个远程脚本
|
||||
* @param {Function} callback 回调
|
||||
*/
|
||||
function loadScript(src, callback) {
|
||||
const existingScript = document.getElementById(src)
|
||||
const cb = callback || (() => {})
|
||||
if (!existingScript) {
|
||||
callbacks[src] = []
|
||||
const $script = document.createElement('script')
|
||||
$script.src = src
|
||||
$script.id = src
|
||||
$script.async = 1
|
||||
document.body.appendChild($script)
|
||||
const onEnd = 'onload' in $script ? stdOnEnd.bind($script) : ieOnEnd.bind($script)
|
||||
onEnd($script)
|
||||
}
|
||||
|
||||
callbacks[src].push(cb)
|
||||
|
||||
function stdOnEnd(script) {
|
||||
script.onload = () => {
|
||||
this.onerror = this.onload = null
|
||||
callbacks[src].forEach(item => {
|
||||
item(null, script)
|
||||
})
|
||||
delete callbacks[src]
|
||||
}
|
||||
script.onerror = () => {
|
||||
this.onerror = this.onload = null
|
||||
cb(new Error(`Failed to load ${src}`), script)
|
||||
}
|
||||
}
|
||||
|
||||
function ieOnEnd(script) {
|
||||
script.onreadystatechange = () => {
|
||||
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
|
||||
this.onreadystatechange = null
|
||||
callbacks[src].forEach(item => {
|
||||
item(null, script)
|
||||
})
|
||||
delete callbacks[src]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 顺序加载一组远程脚本
|
||||
* @param {Array} list 一组远程脚本
|
||||
* @param {Function} cb 回调
|
||||
*/
|
||||
export function loadScriptQueue(list, cb) {
|
||||
const first = list.shift()
|
||||
list.length ? loadScript(first, () => loadScriptQueue(list, cb)) : loadScript(first, cb)
|
||||
}
|
||||
|
||||
export default loadScript
|
29
src/utils/loadTinymce.js
Normal file
29
src/utils/loadTinymce.js
Normal file
@ -0,0 +1,29 @@
|
||||
import loadScript from './loadScript'
|
||||
import ELEMENT from 'element-ui'
|
||||
import pluginsConfig from './pluginsConfig'
|
||||
|
||||
let tinymceObj
|
||||
|
||||
export default function loadTinymce(cb) {
|
||||
const { tinymceUrl } = pluginsConfig
|
||||
|
||||
if (tinymceObj) {
|
||||
cb(tinymceObj)
|
||||
return
|
||||
}
|
||||
|
||||
const loading = ELEMENT.Loading.service({
|
||||
fullscreen: true,
|
||||
lock: true,
|
||||
text: '富文本资源加载中...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(255, 255, 255, 0.5)'
|
||||
})
|
||||
|
||||
loadScript(tinymceUrl, () => {
|
||||
loading.close()
|
||||
// eslint-disable-next-line no-undef
|
||||
tinymceObj = tinymce
|
||||
cb(tinymceObj)
|
||||
})
|
||||
}
|
13
src/utils/pluginsConfig.js
Normal file
13
src/utils/pluginsConfig.js
Normal file
@ -0,0 +1,13 @@
|
||||
const CDN = 'https://lib.baomitu.com/' // CDN Homepage: https://cdn.baomitu.com/
|
||||
const publicPath = process.env.BASE_URL
|
||||
|
||||
function splicingPluginUrl(PluginName, version, fileName) {
|
||||
return `${CDN}${PluginName}/${version}/${fileName}`
|
||||
}
|
||||
|
||||
export default {
|
||||
beautifierUrl: splicingPluginUrl('js-beautify', '1.13.5', 'beautifier.min.js'),
|
||||
// monacoEditorUrl: splicingPluginUrl('monaco-editor', '0.19.3', 'min/vs'), // 使用 monaco-editor CDN 链接
|
||||
monacoEditorUrl: `${publicPath}libs/monaco-editor/vs`, // 使用 monaco-editor 本地代码
|
||||
tinymceUrl: splicingPluginUrl('tinymce', '5.7.0', 'tinymce.min.js')
|
||||
}
|
Loading…
Reference in New Issue
Block a user