first commit

This commit is contained in:
2025-02-20 15:04:05 +08:00
commit 1793865396
2243 changed files with 357784 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
+125
View File
@@ -0,0 +1,125 @@
import request from '@/utils/request'
/**
* 绑定产品
* @param pram
*/
export function bindProduct(pram) {
const data = {
id: pram.id,
productId: pram.productId
}
return request({
url: '/admin/article/bind/product',
method: 'POST',
params: data
})
}
/**
* 删除文章
* @param id
* @constructor
*/
export function DelArticle(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/article/delete',
method: 'GET',
params: data
})
}
/**
* 文章详情
* @param id
* @constructor
*/
export function InfoArticle(id) {
const data = {
id: id
}
return request({
url: '/admin/article/info',
method: 'get',
params: data
})
}
/**
* 文章列表
* @param pram
* @constructor
*/
export function ListArticle(pram) {
const data = {
keywords: pram.keywords,
cid: pram.cid,
page: pram.page,
limit: pram.limit
}
return request({
url: '/admin/article/list',
method: 'GET',
params: data
})
}
/**
* 新增文章
* @param pram
* @constructor
*/
export function AddArticle(pram) {
const data = {
author: pram.author,
cid: pram.cid,
content: pram.content,
imageInput: pram.imageInput,
isBanner: pram.isBanner,
isHot: pram.isHot,
shareSynopsis: pram.shareSynopsis,
shareTitle: pram.shareTitle,
sort: pram.sort,
synopsis: pram.synopsis,
title: pram.title,
url: pram.url
}
return request({
url: '/admin/article/save',
method: 'post',
data: data
})
}
/**
* 更新文章
* @param pram
* @constructor
*/
export function UpdateArticle(pram) {
const data = {
author: pram.author,
cid: pram.cid,
content: pram.content,
imageInput: pram.imageInput,
isBanner: pram.isBanner,
isHot: pram.isHot,
shareSynopsis: pram.shareSynopsis,
shareTitle: pram.shareTitle,
sort: pram.sort,
synopsis: pram.synopsis,
title: pram.title,
url: pram.url
}
return request({
url: '/admin/article/update',
method: 'post',
params: { id: pram.id },
data: data
})
}
+32
View File
@@ -0,0 +1,32 @@
import req from './req'
/**
* 查询授权
* @param pram
*/
export function authCertQuery(prams) {
const data = {
domain_name:prams.host,
label:22,
version:'2.0'
}
return req({
url: document.location.protocol + '//authorize.crmeb.net/api/auth_cert_query',
// url: 'https://authorize.crmeb.net/api/auth_cert_query',
method: 'POST',
data
})
}
/**
* 授权表单提交
*/
export function authCertSubmit(data) {
return req({
url: document.location.protocol + '//authorize.crmeb.net/api/auth_apply',
// url: 'https://authorize.crmeb.net/api/auth_apply',
method: 'POST',
data
})
}
+152
View File
@@ -0,0 +1,152 @@
import request from '@/utils/request'
/**
* 新增分类
* @param pram
*/
export function addCategroy(pram) {
const data = {
extra: pram.extra,
name: pram.name,
pid: pram.pid,
sort: pram.sort,
status: pram.status,
type: pram.type,
url: pram.url
}
return request({
url: '/admin/category/save',
method: 'POST',
params: data
})
}
/**
* 分类详情
* @param pram
*/
export function infoCategroy(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/category/info',
method: 'GET',
params: data
})
}
/**
* 删除分类
* @param pram
*/
export function deleteCategroy(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/category/delete',
method: 'GET',
params: data
})
}
/**
* 分类列表
* @param pram
*/
export function listCategroy(pram) {
const data = {
limit: pram.limit,
name: pram.name,
page: pram.page,
pid: pram.pid,
status: pram.status,
type: pram.type
}
return request({
url: '/admin/category/list',
method: 'GET',
params: data
})
}
/**
* 分类数据tree数据
* @param pram
*/
export function treeCategroy(pram) {
const data = {
type: pram.type,
status: pram.status,
name: pram.name
}
return request({
url: '/admin/category/list/tree',
method: 'GET',
params: data
})
}
/**
* 更新分类
* @param pram
*/
export function updateCategroy(pram) {
const data = {
extra: pram.extra,
name: pram.name,
pid: pram.pid,
sort: pram.sort,
status: pram.status,
type: pram.type,
url: pram.url,
id: pram.id
}
return request({
url: '/admin/category/update',
method: 'POST',
params: data
})
}
/**
* 根据id集合查询对应分类列表
* @param pram
*/
export function categroyByIds(pram) {
const data = {
ids: pram.ids
}
return request({
url: '/admin/category/list/ids',
method: 'GET',
params: data
})
}
/**
* 修改 显示关闭状态
* @param pram
*/
export function categroyUpdateStatus(id) {
return request({
url: `/admin/category/updateStatus/${id}`,
method: 'GET'
})
}
/**
* 文章详情
* @param pram
*/
export function articleInfoApi(params) {
return request({
url: `/admin/article/info`,
method: 'GET',
params
})
}
+21
View File
@@ -0,0 +1,21 @@
import request from '@/utils/request'
/**
* 查询待生成代码列表
* @param pram
*/
export function getCodegenList(pram) {
const data = {
page: pram.page,
limit: pram.limit,
tableName: pram.tableName
}
return request({
url: '/codegen/list',
method: 'GET',
params: data
})
}
+102
View File
@@ -0,0 +1,102 @@
import request from '@/utils/request'
// 配置管理
export function configDelete(pram) {
const data = {
id: pram.id
}
return request({
url: 'admin/system/config/delete',
method: 'GET',
params: data
})
}
export function configInfo(pram) {
const data = {
id: pram.id
}
return request({
url: 'admin/system/config/info',
method: 'GET',
params: data
})
}
export function configList(pram) {
const data = {
id: pram.id,
configTabId: pram.configTabId,
desc: pram.desc,
high: pram.high,
info: pram.info,
inputType: pram.inputType,
menuName: pram.menuName,
parameter: pram.parameter,
required: pram.required,
sort: pram.sort,
status: pram.status,
type: pram.type,
updateType: pram.updateType,
value: pram.value,
width: pram.width,
page: pram.page,
limit: pram.limit
}
return request({
url: 'admin/system/config/list',
method: 'POST',
params: data
})
}
export function configSave(pram) {
const data = {
id: pram.id,
configTabId: pram.configTabId,
desc: pram.desc,
high: pram.high,
info: pram.info,
inputType: pram.inputType,
menuName: pram.menuName,
parameter: pram.parameter,
required: pram.required,
sort: pram.sort,
status: pram.status,
type: pram.type,
updateType: pram.updateType,
value: pram.value,
width: pram.width
}
return request({
url: 'admin/system/config/save',
method: 'POST',
params: data
})
}
export function configUpdate(pram) {
const data = {
id: pram.id,
configTabId: pram.configTabId,
desc: pram.desc,
high: pram.high,
info: pram.info,
inputType: pram.inputType,
menuName: pram.menuName,
parameter: pram.parameter,
required: pram.required,
sort: pram.sort,
status: pram.status,
type: pram.type,
updateType: pram.updateType,
value: pram.value,
width: pram.width
}
return request({
url: 'admin/system/config/update',
method: 'POST',
params: data
})
}
+97
View File
@@ -0,0 +1,97 @@
import request from '@/utils/request'
// 配置分类管理
// 注意暂时没用到,使用无限极分类实现
export function configTabDelete(pram) {
const data = {
id: pram.id
}
return request({
url: 'admin/system/config/tab/delete',
method: 'GET',
params: data
})
}
export function configTabInfo(pram) {
const data = {
id: pram.id
}
return request({
url: 'admin/system/config/tab/info',
method: 'GET',
params: data
})
}
export function configTabList(pram) {
const data = {
id: pram.id,
engTitle: pram.engTitle,
icon: pram.icon,
info: pram.info,
title: pram.title,
parameter: pram.parameter,
status: pram.status,
page: pram.page,
limit: pram.limit
}
return request({
url: 'admin/system/config/tab/list',
method: 'POST',
params: data
})
}
export function configSave(pram) {
const data = {
id: pram.id,
configTabId: pram.configTabId,
desc: pram.desc,
high: pram.high,
info: pram.info,
inputType: pram.inputType,
menuName: pram.menuName,
parameter: pram.parameter,
required: pram.required,
sort: pram.sort,
status: pram.status,
type: pram.type,
updateType: pram.updateType,
value: pram.value,
width: pram.width
}
return request({
url: 'admin/system/config/save',
method: 'POST',
params: data
})
}
export function configUpdate(pram) {
const data = {
id: pram.id,
configTabId: pram.configTabId,
desc: pram.desc,
high: pram.high,
info: pram.info,
inputType: pram.inputType,
menuName: pram.menuName,
parameter: pram.parameter,
required: pram.required,
sort: pram.sort,
status: pram.status,
type: pram.type,
updateType: pram.updateType,
value: pram.value,
width: pram.width
}
return request({
url: 'admin/system/config/update',
method: 'POST',
params: data
})
}
+67
View File
@@ -0,0 +1,67 @@
import request from '@/utils/request'
// 首页数据概览
export function viewModelApi() {
return request({
url: '/admin/statistics/home/index',
method: 'GET',
})
}
// 用户曲线图
export function chartUserApi() {
return request({
url: '/admin/statistics/home/chart/user',
method: 'get'
})
}
// 用户购买统计
export function chartBuyApi() {
return request({
url: '/admin/statistics/home/chart/user/buy',
method: 'get'
})
}
// 订单量趋势 30天
export function chartOrder30Api() {
return request({
url: '/admin/statistics/home/chart/order',
method: 'get'
})
}
// 订单量趋势 月
export function chartOrderMonthApi() {
return request({
url: '/admin/statistics/home/chart/order/month',
method: 'get'
})
}
// 订单量趋势 周
export function chartOrderWeekApi() {
return request({
url: '/admin/statistics/home/chart/order/week',
method: 'get'
})
}
// 订单量趋势 年
export function chartOrderYearApi() {
return request({
url: '/admin/statistics/home/chart/order/year',
method: 'get'
})
}
// 首页经营数据
export function businessData() {
return request({
url: '/admin/statistics/home/operating/data',
method: 'get',
})
}
+81
View File
@@ -0,0 +1,81 @@
import request from '@/utils/request'
/**
* @description 分销设置 -- 详情
*/
export function configApi() {
return request({
url: '/admin/store/retail/spread/manage/get',
method: 'get'
})
}
/**
* @description 分销设置 -- 表单提交
*/
export function configUpdateApi(data) {
return request({
url: '/admin/store/retail/spread/manage/set',
method: 'post',
data
})
}
/**
* @description 分销员 -- 列表
*/
export function promoterListApi(params) {
return request({
url: '/admin/store/retail/list',
method: 'get',
params
})
}
/**
* @description 推广人 -- 列表
*/
export function spreadListApi( params, data) {
return request({
url: '/admin/store/retail/spread/userlist',
method: 'post',
params,
data
})
}
/**
* @description 推广人订单 -- 列表
*/
export function spreadOrderListApi(params, data) {
return request({
url: '/admin/store/retail/spread/orderlist',
method: 'post',
params,
data
})
}
/**
* @description 推广人 -- 清除上级推广人
*/
export function spreadClearApi(id) {
return request({
url: `/admin/store/retail/spread/clean/${id}`,
method: 'get'
})
}
/**
* @description 分销统计
*/
export function spreadStatisticsApi(params) {
return request({
url: `/admin/store/retail/statistics`,
method: 'get',
params
})
}
+134
View File
@@ -0,0 +1,134 @@
import request from '@/utils/request'
/**
* 提现申请 列表
* @param pram
*/
export function applyListApi(params) {
return request({
url: '/admin/finance/apply/list',
method: 'get',
params
})
}
/**
* 提现申请 金额
* @param pram
*/
export function applyBalanceApi(params) {
return request({
url: '/admin/finance/apply/balance',
method: 'post',
params
})
}
/**
* 提现申请 修改
* @param pram
*/
export function applyUpdateApi(params) {
return request({
url: '/admin/finance/apply/update',
method: 'post',
params
})
}
/**
* 提现申请 审核
* @param pram
*/
export function applyStatusApi(params, data) {
return request({
url: '/admin/finance/apply/apply',
method: 'post',
params,
data
})
}
/**
* 充值 列表
* @param pram
*/
export function topUpLogListApi(params) {
return request({
url: '/admin/user/topUpLog/list',
method: 'get',
params
})
}
/**
* 充值 金额
* @param pram
*/
export function balanceApi() {
return request({
url: '/admin/user/topUpLog/balance',
method: 'post'
})
}
/**
* 充值 删除
* @param pram
*/
export function topUpLogDeleteApi(params) {
return request({
url: '/admin/user/topUpLog/delete',
method: 'get',
params
})
}
/**
* 充值 退款
* @param pram
*/
export function refundApi(data) {
return request({
url: '/admin/user/topUpLog/refund',
method: 'post',
data
})
}
/**
* 资金监控 列表
* @param pram
*/
export function monitorListApi(params) {
return request({
url: '/admin/finance/founds/monitor/list',
method: 'get',
params
})
}
/**
* 资金监控 明细类型
* @param pram
*/
export function monitorListOptionApi() {
return request({
url: `/admin/finance/founds/monitor/list/option`,
method: 'get'
})
}
/**
* 佣金记录 列表
* @param pram
*/
export function brokerageListApi(params) {
return request({
url: '/admin/finance/founds/monitor/brokerage/record',
method: 'get',
params
})
}
+172
View File
@@ -0,0 +1,172 @@
import request from '@/utils/request'
// 城市列表
export function cityList(data) {
return request({
url: '/admin/system/city/list',
method: 'get',
params: { ...data }
})
}
// 城市列表
export function cityListTree() {
return request({
url: '/admin/system/city/list/tree',
method: 'get'
})
}
// 城市修改状态
export function updateStatus(data) {
return request({
url: '/admin/system/city/update/status',
method: 'post',
params: { ...data }
})
}
// 城市修改
export function cityUpdate(data) {
return request({
url: '/admin/system/city/update',
method: 'post',
params: { ...data }
})
}
// 城市详情
export function cityInfo(data) {
return request({
url: '/admin/system/city/info',
method: 'get',
params: { ...data }
})
}
// 物流公司列表
export function expressList(data) {
return request({
url: '/admin/express/list',
method: 'get',
params: { ...data }
})
}
// 同步物流公司
export function expressSyncApi() {
return request({
url: '/admin/express/sync/express',
method: 'post'
})
}
// 物流公司修改状态
export function expressUpdateShow(data) {
return request({
url: '/admin/express/update/show',
method: 'post',
data
})
}
// 物流公司 编辑
export function expressUpdate(data) {
return request({
url: '/admin/express/update',
method: 'post',
data
})
}
// 新增物流公司
export function expressSave(data) {
return request({
url: '/admin/express/save',
method: 'post',
params: { ...data }
})
}
// 删除物流公司
export function expressDelete(data) {
return request({
url: '/admin/express/delete',
method: 'GET',
params: { ...data }
})
}
// 物流运费模板列表
export function shippingTemplatesList(data) {
return request({
url: '/admin/express/shipping/templates/list',
method: 'get',
params: { ...data }
})
}
// 物流运费模板详情
export function templateDetailApi(data) {
return request({
url: '/admin/express/shipping/templates/info',
method: 'get',
params: { ...data }
})
}
// 物流运费模板包邮
export function shippingFree(data) {
return request({
url: '/admin/express/shipping/free/list',
method: 'get',
params: { ...data }
})
}
// 物流运费模板不包邮
export function shippingRegion(data) {
return request({
url: 'admin/express/shipping/region/list',
method: 'get',
params: { ...data }
})
}
// 物流运费模板新增
export function shippingSave(data) {
return request({
url: 'admin/express/shipping/templates/save',
method: 'post',
data: data
})
}
// 物流运费模板更新
export function shippingUpdate(data, id) {
return request({
url: 'admin/express/shipping/templates/update',
method: 'post',
data: data,
params: { ...id }
})
}
// 物流运费模板删除
export function shippingDetete(data) {
return request({
url: 'admin/express/shipping/templates/delete',
method: 'get',
params: data
})
}
// 物流公司详情
export function expressInfo(data) {
return request({
url: 'admin/express/info',
method: 'get',
params: { ...data }
})
}
+572
View File
@@ -0,0 +1,572 @@
import request from '@/utils/request'
/**
* 优惠券 列表
* @param pram
*/
export function marketingListApi(params) {
return request({
url: '/admin/marketing/coupon/list',
method: 'get',
params
})
}
/**
* 用户管理 优惠券列表
* @param pram
*/
export function marketingSendApi(params) {
return request({
url: '/admin/marketing/coupon/send/list',
method: 'get',
params
})
}
/**
* 优惠券 详情
* @param pram
*/
export function couponInfoApi(params) {
return request({
url: '/admin/marketing/coupon/info',
method: 'post',
params
})
}
/**
* 优惠券 发送
* @param pram
*/
export function couponUserApi(params) {
return request({
url: '/admin/marketing/coupon/user/receive',
method: 'post',
params
})
}
/**
* 优惠券 发送
* @param pram
*/
export function couponSaveApi(data) {
return request({
url: '/admin/marketing/coupon/save',
method: 'post',
data
})
}
/**
* 优惠券 修改状态
* @param pram
*/
export function couponIssueStatusApi(params) {
return request({
url: '/admin/marketing/coupon/update/status',
method: 'post',
params
})
}
/**
* 优惠券 删除
* @param pram
*/
export function couponDeleteApi(params) {
return request({
url: '/admin/marketing/coupon/delete',
method: 'post',
params
})
}
/**
* 会员领取记录 列表
* @param pram
*/
export function couponUserListApi(params) {
return request({
url: '/admin/marketing/coupon/user/list',
method: 'get',
params
})
}
/**
* 积分日志 列表
* @param pram
*/
export function integralListApi(params, data) {
return request({
url: '/admin/user/integral/list',
method: 'post',
params,
data
})
}
/**
* 秒杀配置 列表
* @param pram
*/
export function seckillListApi(params) {
return request({
url: '/admin/store/seckill/manger/list',
method: 'get',
params
})
}
/**
* 秒杀配置 详情
* @param pram
*/
export function seckillInfoApi(params) {
return request({
url: '/admin/store/seckill/manger/info',
method: 'get',
params
})
}
/**
* 秒杀配置 新增
* @param pram
*/
export function seckillSaveApi(data) {
return request({
url: '/admin/store/seckill/manger/save',
method: 'post',
data
})
}
/**
* 秒杀配置 修改
* @param pram
*/
export function seckillUpdateApi(params, data) {
return request({
url: '/admin/store/seckill/manger/update',
method: 'post',
params,
data
})
}
/**
* 秒杀配置 删除
* @param pram
*/
export function seckillDeleteApi(params) {
return request({
url: '/admin/store/seckill/manger/delete',
method: 'get',
params
})
}
/**
* 秒杀商品 列表
* @param pram
*/
export function seckillStoreListApi(params) {
return request({
url: '/admin/store/seckill/list',
method: 'get',
params
})
}
/**
* 秒杀商品 详情
* @param pram
*/
export function seckillStoreInfoApi(params) {
return request({
url: '/admin/store/seckill/info',
method: 'get',
params
})
}
/**
* 秒杀商品 新增
* @param pram
*/
export function seckillStoreSaveApi(data) {
return request({
url: '/admin/store/seckill/save',
method: 'post',
data
})
}
/**
* 秒杀商品 修改
* @param pram
*/
export function seckillStoreUpdateApi(params, data) {
return request({
url: '/admin/store/seckill/update',
method: 'post',
params,
data
})
}
/**
* 秒杀商品 删除
* @param pram
*/
export function seckillStoreDeleteApi(params) {
return request({
url: '/admin/store/seckill/delete',
method: 'get',
params
})
}
/**
* 秒杀商品 修改状态
*/
export function seckillStoreStatusApi(params) {
return request({
url: '/admin/store/seckill/update/status',
method: 'post',
params
})
}
/**
* 秒杀配置 修改状态
*/
export function seckillConfigStatusApi(id,params) {
return request({
url: `/admin/store/seckill/manger/update/status/${id}`,
method: 'post',
params
})
}
/**
* 砍价商品 列表
*/
export function bargainListApi(params) {
return request({
url: `/admin/store/bargain/list`,
method: 'get',
params
})
}
/**
* 砍价商品 新增
*/
export function bargainSaveApi(data) {
return request({
url: `/admin/store/bargain/save`,
method: 'POST',
data
})
}
/**
* 砍价商品 详情
*/
export function bargainInfoApi(params) {
return request({
url: `/admin/store/bargain/info`,
method: 'get',
params
})
}
/**
* 砍价商品 编辑
*/
export function bargainUpdateApi(params, data) {
return request({
url: `/admin/store/bargain/update`,
method: 'post',
params,
data
})
}
/**
* 砍价商品 删除
*/
export function bargainDeleteApi(params) {
return request({
url: `/admin/store/bargain/delete`,
method: 'get',
params
})
}
/**
* 砍价列表 详情
*/
export function bargainOrderPinkApi(id) {
return request({
url: `/admin/store/bargain/bargain_list/${id}`,
method: 'get'
})
}
/**
* 砍价列表 列表
*/
export function bargainListListApi(params) {
return request({
url: `/admin/store/bargain/bargain_list`,
method: 'get',
params
})
}
/**
* 拼团商品 修改拼团状态
*/
export function bargainStatusApi(params) {
return request({
url: `/admin/store/bargain/update/status`,
method: 'post',
params
})
}
/**
* 拼团商品 列表
*/
export function combinationListApi(params) {
return request({
url: `/admin/store/combination/list`,
method: 'get',
params
})
}
/**
* 拼团商品 删除
*/
export function combinationDeleteApi(params) {
return request({
url: `/admin/store/combination/delete`,
method: 'get',
params
})
}
/**
* 拼团商品 新增
*/
export function combinationSaveApi(data) {
return request({
url: `/admin/store/combination/save`,
method: 'post',
data
})
}
/**
* 拼团商品 修改
*/
export function combinationUpdateApi(params,data) {
return request({
url: `/admin/store/combination/update`,
method: 'post',
params,
data
})
}
/**
* 拼团商品 详情
*/
export function combinationInfoApi(params) {
return request({
url: `/admin/store/combination/info`,
method: 'get',
params
})
}
/**
* 拼团商品 修改拼团状态
*/
export function combinationStatusApi(params) {
return request({
url: `/admin/store/combination/update/status`,
method: 'post',
params
})
}
/**
* 拼团列表 列表
*/
export function combineListApi(params) {
return request({
url: `/admin/store/combination/combine/list`,
method: 'get',
params
})
}
/**
* 拼团列表 统计
*/
export function combineStatisticsApi(params) {
return request({
url: `/admin/store/combination/statistics`,
method: 'get',
params
})
}
/**
* 拼团列表 详情
*/
export function combineOrderPinkApi(id) {
return request({
url: `/admin/store/combination/order_pink/${id}`,
method: 'get'
})
}
/**
* 砍价 导出
*/
export function exportBargainApi(params) {
return request({
url: `/admin/export/excel/bargain/product`,
method: 'get',
params
})
}
/**
* 拼团 导出
*/
export function exportcombiantionApi(params) {
return request({
url: `/admin/export/excel/combiantion/product`,
method: 'get',
params
})
}
/**
* 视频号 草稿列表
*/
export function draftListApi(params) {
return request({
url: `/admin/pay/component/product/draft/list`,
method: 'get',
params
})
}
/**
* 视频号 商品列表
*/
export function videoProductListApi(params) {
return request({
url: `/admin/pay/component/product/list`,
method: 'get',
params
})
}
/**
* 视频号 类目
*/
export function catListApi(params) {
return request({
url: `/admin/pay/component/cat/get/list`,
method: 'get'
})
}
/**
* 视频号 添加
*/
export function videoAddApi(data) {
return request({
url: `/admin/pay/component/product/add`,
method: 'post',
data
})
}
/**
* 视频号 编辑
*/
export function videoUpdateApi(data) {
return request({
url: `/admin/pay/component/product/update`,
method: 'post',
data
})
}
/**
* 视频号 上架
*/
export function videoUpApi(proId) {
return request({
url: `/admin/pay/component/product/listing/${proId}`,
method: 'post'
})
}
/**
* 视频号 下架
*/
export function videoDownApi(proId) {
return request({
url: `/admin/pay/component/product/delisting/${proId}`,
method: 'post'
})
}
/**
* 视频号 删除
*/
export function videoDelApi(proId) {
return request({
url: `/admin/pay/component/product/delete/${proId}`,
method: 'post'
})
}
/**
* 视频号 草稿商品详情
*/
export function draftInfoApi(id) {
return request({
url: `/admin/pay/component/product/draft/get/${id}`,
method: 'get'
})
}
/**
* 视频号 草稿商品编辑
*/
export function draftUpdateApi(data) {
return request({
url: `/admin/pay/component/product/update`,
method: 'post',
data
})
}
+252
View File
@@ -0,0 +1,252 @@
import request from '@/utils/request'
/**
* 订单 列表
* @param prams
*/
export function orderListApi(params) {
return request({
url: '/admin/store/order/list',
method: 'get',
params
})
}
/**
* 订单 列表 获取各状态数量
* @param params
*/
export function orderStatusNumApi(params) {
return request({
url: '/admin/store/order/status/num',
method: 'get',
params
})
}
/**
* 订单 列表 数据统计
* @param params
*/
export function orderListDataApi(params) {
return request({
url: '/admin/store/order/list/data',
method: 'get',
params
})
}
/**
* 订单 删除
* @param params
*/
export function orderDeleteApi(params) {
return request({
url: '/admin/store/order/delete',
method: 'get',
params
})
}
/**
* 订单 编辑
* @param prams
*/
export function orderUpdateApi(data, params) {
return request({
url: '/admin/store/order/update',
method: 'post',
data,
params
})
}
/**
* 订单 记录
* @param prams
*/
export function orderLogApi(params) {
return request({
url: '/admin/store/order/status/list',
method: 'get',
params
})
}
/**
* 订单 详情
* @param prams
*/
export function orderDetailApi(params) {
return request({
url: '/admin/store/order/info',
method: 'get',
params
})
}
/**
* 订单 备注
* @param prams
*/
export function orderMarkApi(params) {
return request({
url: '/admin/store/order/mark',
method: 'post',
params
})
}
/**
* 订单 发货
* @param prams
*/
export function orderSendApi(data) {
return request({
url: '/admin/store/order/send',
method: 'post',
data
})
}
/**
* 订单 拒绝退款
* @param prams
*/
export function orderRefuseApi(params) {
return request({
url: '/admin/store/order/refund/refuse',
method: 'get',
params
})
}
/**
* 订单 立即退款
* @param prams
*/
export function orderRefundApi(params) {
return request({
url: '/admin/store/order/refund',
method: 'get',
params
})
}
/**
* 订单 核销订单
* @param prams
*/
export function writeUpdateApi(vCode) {
return request({
url: `/admin/store/order/writeUpdate/${vCode}`,
method: 'get'
})
}
/**
* 订单 核销码查询待核销订单
* @param prams
*/
export function writeConfirmApi(vCode) {
return request({
url: `/admin/store/order/writeConfirm/${vCode}`,
method: 'get'
})
}
/**
* 订单 统计 头部数据
*/
export function orderStatisticsApi() {
return request({
url: `/admin/store/order/statistics`,
method: 'get'
})
}
/**
* 核销订单 月列表数据
*/
export function statisticsDataApi(params) {
return request({
url: `/admin/store/order/statisticsData`,
method: 'get',
params
})
}
/**
* 一键改价
*/
export function updatePriceApi(data) {
return request({
url: `admin/store/order/update/price`,
method: 'post',
data
})
}
/**
*订单统计详情
*/
export function orderTimeApi(params) {
return request({
url: `/admin/store/order/time`,
method: 'get',
params
})
}
/**
*面单默认配置信息
*/
export function sheetInfoApi() {
return request({
url: `/admin/store/order/sheet/info`,
method: 'get'
})
}
/**
*面单默认配置信息
*/
export function getLogisticsInfoApi(params) {
return request({
url: `/admin/store/order/getLogisticsInfo`,
method: 'get',
params
})
}
/**
*视频号物流公司
*/
export function companyGetListApi() {
return request({
url: `/admin/pay/component/delivery/company/get/list`,
method: 'get'
})
}
/**
*视频号物流公司
*/
export function videoSendApi(data) {
return request({
url: `/admin/store/order/video/send`,
method: 'post',
data
})
}
/**
*打印小票
*/
export function orderPrint(id) {
return request({
url: `/admin/yly/print/${id}`,
method: 'get',
})
}
+33
View File
@@ -0,0 +1,33 @@
import axios from 'axios'
const service = axios.create({
timeout: 40000,
})
service.interceptors.request.use(
config => {
return config
},
error => {
Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
response => {
const res = response
if (res.status !== 200 && res.status !== 401) {
Message({
message: res.data.msg || 'Error',
type: 'error',
duration: 5 * 1000
})
return Promise.reject()
}else {
return res.data
}
},
error => {
}
)
export default service
+112
View File
@@ -0,0 +1,112 @@
import request from '@/utils/request'
/**
* 新增
* @param
*/
export function addRole(pram) {
const data = {
level: pram.level,
roleName: pram.roleName,
status: pram.status,
rules: pram.rules
}
// data.rules = pram.rules.join(',')
return request({
url: '/admin/system/role/save',
method: 'POST',
data: data
})
}
/**
* 删除
* @param
*/
export function delRole(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/system/role/delete',
method: 'GET',
params: data
})
}
/**
* 详情
* @param
*/
export function getInfo(pram) {
return request({
url: `/admin/system/role/info/${pram}`,
method: 'GET',
})
}
/**
* 分页列表
* @param
*/
export function getRoleList(pram) {
const data = {
createTime: pram.createTime,
updateTime: pram.updateTime,
level: pram.level,
page: pram.page,
limit: pram.limit,
roleName: pram.roleName,
rules: pram.rules,
status: pram.status
}
return request({
url: '/admin/system/role/list',
method: 'get',
params: data
})
}
/**
* 修改
* @param
*/
export function updateRole(pram) {
const data = {
id: pram.id,
roleName: pram.roleName,
rules: pram.rules,
status: pram.status
}
return request({
url: '/admin/system/role/update',
method: 'post',
params: {id: pram.id},
data: data
})
}
/**
* 修改身份状态
* @param
*/
export function updateRoleStatus(pram) {
return request({
url: '/admin/system/role/updateStatus',
method: 'get',
params: {id: pram.id,status:pram.status},
})
}
/**
* 缓存菜单
* @param
*/
export function menuCacheList(pram) {
return request({
url: '/admin/system/menu/cache/tree',
method: 'get',
})
}
+24
View File
@@ -0,0 +1,24 @@
import request from '@/utils/request'
/**
* 角色详情
*/
export function getRoleById(pram) {
return request({
url: `/admin/system/role/info/${pram.roles}`,
method: 'GET',
})
}
/**
* 菜单
* @param pram
*/
export function menuListApi() {
return request({
url: '/admin/getMenus',
method: 'GET'
})
}
+207
View File
@@ -0,0 +1,207 @@
import request from '@/utils/request'
/**
* @description 短信发送记录 -- 列表
*/
export function smsLstApi(params) {
return request({
url: '/admin/pass/user/record',
method: 'get',
params
})
}
/**
* @description 短信账户 -- 登录
*/
export function configApi(data) {
return request({
url: '/admin/pass/login',
method: 'post',
data
})
}
/**
* @description 短信账户 -- 获取验证码
*/
export function captchaApi(params) {
return request({
url: `/admin/pass/sendUserCode`,
method: 'get',
params
})
}
/**
* @description 短信账户 -- 注册
*/
export function registerApi(data) {
return request({
url: '/admin/pass/register',
method: 'post',
data
})
}
/**
* @description 短信账户 -- 是否登录
*/
export function isLoginApi() {
return request({
url: '/admin/pass/isLogin',
method: 'get'
})
}
/**
* @description 短信账户 -- 退出登录
*/
export function logoutApi() {
return request({
url: '/admin/pass/logout',
method: 'get'
})
}
/**
* @description 短信账户 -- 剩余条数
*/
export function smsNumberApi() {
return request({
url: '/admin/sms/logout',
method: 'get'
})
}
/**
* @description 短信模板 -- 列表
*/
export function smsTempLstApi(params) {
return request({
url: '/admin/sms/temps',
method: 'get',
params
})
}
/**
* @description 短信购买 -- 支付套餐
*/
export function smsPriceApi(params) {
return request({
url: '/admin/pass/meal/list',
method: 'get',
params
})
}
/**
* @description 短信购买 -- 支付码
*/
export function payCodeApi(data) {
return request({
url: '/admin/pass/meal/code',
method: 'post',
data
})
}
/**
* @description 短信模板 -- 添加表单
*/
export function tempCreateApi(data) {
return request({
url: '/admin/sms/temp/apply',
method: 'post',
data
})
}
/**
* @description 短信 -- 用户信息
*/
export function smsInfoApi() {
return request({
url: '/admin/pass/info',
method: 'get'
})
}
/**
* @description 短信 -- 短信提醒开关保存
*/
export function smsSaveApi(params) {
return request({
url: '/admin/sms/config/save',
method: 'post',
params
})
}
/**
* @description 短信 -- 修改密码
*/
export function updatePasswordApi(data) {
return request({
url: '/admin/pass/update/password',
method: 'post',
data
})
}
/**
* @description 短信 -- 修改手机号
*/
export function updateHoneApi(data) {
return request({
url: '/admin/pass/update/phone',
method: 'post',
data
})
}
/**
* @description 一号通 -- 服务开通
*/
export function serviceOpenApi(data) {
return request({
url: '/admin/pass/service/open',
method: 'post',
data
})
}
/**
* @description 一号通 -- 电子面单模板
*/
export function exportTempApi(params) {
return request({
url: '/admin/express/template',
method: 'get',
params
})
}
/**
* @description 全部物流公司
*/
export function expressAllApi(params) {
return request({
url: 'admin/express/all',
method: 'get',
params
})
}
/**
* @description 修改签名
*/
export function smsSignApi(data) {
return request({
url: 'admin/sms/modify/sign',
method: 'post',
data
})
}
/**
* @description 修改手机号验证账号密码
*/
export function phoneValidatorApi(data) {
return request({
url: 'admin/pass/update/phone/validator',
method: 'post',
data
})
}
+142
View File
@@ -0,0 +1,142 @@
import request from '@/utils/request'
/**
* 商品统计数据
* @param pram
*/
export function productDataApi(params) {
return request({
url: `/admin/statistics/product/data`,
method: 'GET',
params
})
}
/**
* 商品排行数据
* @param pram
*/
export function productRankApi(params) {
return request({
url: `/admin/statistics/product/ranking`,
method: 'GET',
params
})
}
/**
* 商品趋势数据
* @param pram
*/
export function productTrendApi(params) {
return request({
url: `/admin/statistics/product/trend`,
method: 'GET',
params
})
}
/**
* 交易统计数据
* @param pram
*/
export function tradeDataApi() {
return request({
url: `/admin/statistics/trade/data`,
method: 'GET',
})
}
/**
* 交易概览
* @param pram
*/
export function tradeOverviewApi(params) {
return request({
url: `/admin/statistics/trade/overview`,
method: 'GET',
params
})
}
/**
* 交易趋势
* @param pram
*/
export function tradeTrendApi(params) {
return request({
url: `/admin/statistics/trade/trend`,
method: 'GET',
params
})
}
/**
* 用户总数据
* @param pram
*/
export function userTotalData() {
return request({
url: `/admin/statistics/user/total/data`,
method: 'GET'
})
}
/**
* 用户区域数据
* @param pram
*/
export function userAreaData() {
return request({
url: `/admin/statistics/user/area`,
method: 'GET'
})
}
/**
* 用户渠道数据
* @param pram
*/
export function userChannelData() {
return request({
url: `/admin/statistics/user/channel`,
method: 'GET'
})
}
/**
* 用户概览
* @param pram
*/
export function userOverviewData(params) {
return request({
url: `/admin/statistics/user/overview`,
method: 'GET',
params
})
}
/**
* 用户性别数据
* @param pram
*/
export function userSexData() {
return request({
url: `/admin/statistics/user/sex`,
method: 'GET',
})
}
/**
* 用户概览列表
* @param pram
*/
export function userOverviewListApi(params) {
return request({
url: `/admin/statistics/user/overview/list`,
method: 'GET',
params
})
}
+304
View File
@@ -0,0 +1,304 @@
import request from '@/utils/request'
/**
* 新增商品
* @param pram
*/
export function productCreateApi(data) {
return request({
url: '/admin/store/product/save',
method: 'POST',
data
})
}
/**
* 编辑商品
* @param pram
*/
export function productUpdateApi(data) {
return request({
url: '/admin/store/product/update',
method: 'POST',
data
})
}
/**
* 商品详情
* @param pram
*/
export function productDetailApi(id) {
return request({
url: `/admin/store/product/info/${id}`,
method: 'GET'
})
}
/**
* 删除商品
* @param pram
*/
export function productDeleteApi(id, type) {
return request({
url: `/admin/store/product/delete/${id}`,
method: 'get',
params:{type:type}
})
}
/**
* 商品列表 表头数量
*/
export function productHeadersApi() {
return request({
url: '/admin/store/product/tabs/headers',
method: 'GET'
})
}
/**
* 商品列表
* @param pram
*/
export function productLstApi(params) {
return request({
url: '/admin/store/product/list',
method: 'GET',
params
})
}
/**
* 商品分类
* @param pram
*/
export function categoryApi(params) {
return request({
url: '/admin/category/list/tree',
method: 'GET',
params
})
}
/**
* 商品上架
* @param pram
*/
export function putOnShellApi(id) {
return request({
url: `/admin/store/product/putOnShell/${id}`,
method: 'GET'
})
}
/**
* 商品下架
* @param pram
*/
export function offShellApi(id) {
return request({
url: `/admin/store/product/offShell/${id}`,
method: 'GET'
})
}
/**
* 商品规格 列表
* @param pram
*/
export function templateListApi(params) {
return request({
url: '/admin/store/product/rule/list',
method: 'GET',
params
})
}
/**
* 商品规格 删除
* @param pram
*/
export function attrDeleteApi(id) {
return request({
url: `/admin/store/product/rule/delete/${id}`,
method: 'get'
})
}
/**
* 商品规格 新增
* @param pram
*/
export function attrCreatApi(data) {
return request({
url: '/admin/store/product/rule/save',
method: 'POST',
data
})
}
/**
* 商品规格 编辑
* @param pram
*/
export function attrEditApi(data) {
return request({
url: '/admin/store/product/rule/update',
method: 'POST',
data
})
}
/**
* 商品规格 详情
* @param pram
*/
export function attrInfoApi(id) {
return request({
url: `admin/store/product/rule/info/${id}`,
method: 'GET'
})
}
/**
* 商品评论 列表
* @param pram
*/
export function replyListApi(params) {
return request({
url: '/admin/store/product/reply/list',
method: 'GET',
params
})
}
/**
* 商品评论 新增
* @param pram
*/
export function replyCreatApi(data) {
return request({
url: '/admin/store/product/reply/save',
method: 'POST',
data
})
}
/**
* 商品评论 编辑
* @param pram
*/
export function replyEditApi(data) {
return request({
url: '/admin/store/product/reply/update',
method: 'POST',
data
})
}
/**
* 商品评论 详情
* @param pram
*/
export function replyInfoApi(id) {
return request({
url: `/admin/store/product/reply/info/${id}`,
method: 'GET'
})
}
/**
* 商品评论 删除
* @param pram
*/
export function replyDeleteApi(id) {
return request({
url: `/admin/store/product/reply/delete/${id}`,
method: 'GET'
})
}
/**
* 商品评论 回复
* @param pram
*/
export function replyCommentApi(data) {
return request({
url: `/admin/store/product/reply/comment`,
method: 'post',
data
})
}
/**
* 商品评论 导出
* @param pram
*/
export function productExportApi(params) {
return request({
url: `/admin/export/excel/product`,
method: 'get',
params
})
}
/**
* 商品复制 99Api
* @param pram
*/
export function importProductApi(params) {
return request({
url: `/admin/store/product/importProduct`,
method: 'post',
params
})
}
/**
* 商品复制 一号通
* @param pram
*/
export function copyProductApi(data) {
return request({
url: `/admin/store/product/copy/product`,
method: 'post',
data
})
}
/**
* 恢复
* @param pram
*/
export function restoreApi(id) {
return request({
url: `/admin/store/product/restore/${id}`,
method: 'get'
})
}
/**
* 商品列表 导出
* @param pram
*/
export function productExcelApi(params) {
return request({
url: `/admin/export/excel/product`,
method: 'get',
params
})
}
/**
* 商品列表 获取复制商品配置
* @param pram
*/
export function copyConfigApi() {
return request({
url: `/admin/store/product/copy/config`,
method: 'post'
})
}
/**
* 订单数据 导出
* @param pram
*/
export function orderExcelApi(params) {
return request({
url: `/admin/export/excel/order`,
method: 'get',
params
})
}
+219
View File
@@ -0,0 +1,219 @@
import request from '@/utils/request'
/**
* 提货点分页列表
* @param pram
*/
export function storeListApi(data) {
return request({
url: '/admin/system/store/list',
method: 'get',
params: data
})
}
/**
* 提货点数量
* @param pram
*/
export function storeGetCountApi() {
return request({
url: '/admin/system/store/getCount',
method: 'get'
})
}
/**
* 提货点门店状态
* @param pram
*/
export function storeUpdateStatusApi(data) {
return request({
url: '/admin/system/store/update/status',
method: 'get',
params: data
})
}
/**
* 提货点门店刪除
* @param pram
*/
export function storeDeleteApi(data) {
return request({
url: '/admin/system/store/delete',
method: 'get',
params: data
})
}
/**
* 提货点门店回收站刪除
* @param pram
*/
export function allDeleteApi(params) {
return request({
url: '/admin/system/store/completely/delete',
method: 'get',
params
})
}
/**
* 提货点添加
* @param pram
*/
export function storeSaveApi(data) {
return request({
url: '/admin/system/store/save',
method: 'post',
data
})
}
/**
* 提货点详情
* @param pram
*/
export function storeInfoApi(data) {
return request({
url: '/admin/system/store/info',
method: 'get',
params: data
})
}
/**
* 提货点修改
* @param pram
*/
export function storeUpdateApi(data,id) {
// const param = ;
return request({
url: '/admin/system/store/update',
method: 'post',
params: {id: id},
data
})
}
/**
* 提货点恢复
* @param pram
*/
export function storeRecoveryApi(params) {
return request({
url: '/admin/system/store/recovery',
method: 'get',
params
})
}
/**
* 核销员分页列表
* @param pram
*/
export function storeStaffListApi(data) {
return request({
url: '/admin/system/store/staff/list',
method: 'get',
params: data
})
}
/**
* 核销员添加
* @param pram
*/
export function storeStaffSaveApi(data) {
return request({
url: '/admin/system/store/staff/save',
method: 'POST',
params: data
})
}
/**
* 核销员删除
* @param pram
*/
export function storeStaffDeleteApi(data) {
return request({
url: '/admin/system/store/staff/delete',
method: 'get',
params: data
})
}
/**
* 核销员编辑
* @param pram
*/
export function storeStaffUpdateApi(data) {
return request({
url: '/admin/system/store/staff/update',
method: 'POST',
params: data
})
}
/**
* 核销员编辑
* @param pram
*/
export function storeStaffInfoApi(id) {
return request({
url: '/admin/system/store/staff/info',
method: 'get',
params: id
})
}
/**
* 核销员编辑
* @param pram
*/
export function storeStaffUpdateStatusApi(data) {
return request({
url: '/admin/system/store/staff/update/status',
method: 'get',
params: data
})
}
/**
* 核销员编辑
* @param pram
*/
export function userListApi(data) {
return request({
url: '/admin/wechat/user/list',
method: 'get',
params: data
})
}
/**
* 核销订单
* @param pram
*/
export function orderListApi(params) {
return request({
url: '/admin/system/store/order/list',
method: 'post',
params
})
}
+49
View File
@@ -0,0 +1,49 @@
import request from '@/utils/request'
/**
* @description 附件分类 -- 所有分类
*/
export function formatLstApi(data) {
return request.get({
url: '/admin/product/save',
method: 'POST',
data
})
}
/**
* @description 附件分类 -- 添加分类
*/
export function attachmentCreateApi() {
return request.get(`system/attachment/category/create/form`)
}
/**
* @description 附件分类 -- 编辑分类
*/
export function attachmentUpdateApi(id) {
return request.get(`system/attachment/category/update/form/${id}`)
}
/**
* @description 附件分类 -- 删除分类
*/
export function attachmentDeleteApi(id) {
return request.delete(`system/attachment/category/delete/${id}`)
}
/**
* @description 图片列表
*/
export function attachmentListApi(data) {
return request.get(`system/attachment/lst`, data)
}
/**
* @description 图片列表 -- 删除
*/
export function picDeleteApi(id) {
return request.delete(`system/attachment/delete`, id)
}
/**
* @description 图片列表 -- 修改附件分类
*/
export function categoryApi(ids, attachment_category_id) {
return request.post(`system/attachment/category`, { ids, attachment_category_id })
}
+113
View File
@@ -0,0 +1,113 @@
import request from '@/utils/request'
export function configCheckUnique(pram) {
const data = {
name: pram.name
}
return request({
url: '/admin/system/config/check',
method: 'GET',
params: data
})
}
export function configDelete(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/system/config/delete',
method: 'GET',
params: data
})
}
export function configInfo(pram) {
const data = {
formId: pram.id
}
return request({
url: '/admin/system/config/info',
method: 'GET',
params: data
})
}
export function configList(pram) {
const data = {
page: pram.page,
limit: pram.limit
}
return request({
url: '/admin/system/config/list',
method: 'GET',
params: data
})
}
export function configSave(pram) {
const data = {
systemConfigRequest: {
desc: pram.desc,
groupId: pram.groupId,
info: pram.info,
name: pram.name,
pid: pram.pid,
status: pram.status,
type: pram.type,
value: pram.value // value 存储表单配置数据,其他的参数来自于父级数据 justForAPI
}
}
return request({
url: '/admin/system/config/save',
method: 'POST',
params: data
})
}
export function configSaveForm(pram) {
return request({
url: '/admin/system/config/save/form',
method: 'POST',
data: pram
})
}
export function configUpdate(pram) {
const data = {
id: pram.id,
systemConfigRequest: pram.systemConfigRequest
}
return request({
url: '/admin/system/config/update',
method: 'POST',
params: data
})
}
export function configSaveUniq(pram) {
const data = {
key: pram.key,
value: pram.value
}
return request({
url: '/admin/system/config/saveuniq',
method: 'POST',
params: data
})
}
export function configGetUniq(pram) {
const data = {
key: pram.key
}
return request({
url: '/admin/system/config/getuniq',
method: 'GET',
params: data
})
}
+138
View File
@@ -0,0 +1,138 @@
import request from '@/utils/request'
export function getFormConfigInfo(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/system/form/temp/info',
method: 'GET',
params: data
})
}
export function getFormConfigList(pram) {
const data = {
keywords: pram.keywords,
page: pram.page,
limit: pram.limit
}
return request({
url: '/admin/system/form/temp/list',
method: 'GET',
params: data
})
}
export function getFormConfigSave(pram) {
const data = {
content: pram.content,
info: pram.info,
name: pram.name
}
return request({
url: '/admin/system/form/temp/save',
method: 'POST',
data: data
})
}
export function getFormConfigEdit(pram) {
const params = { id: pram.id }
const data = {
content: pram.content,
info: pram.info,
name: pram.name
}
return request({
url: '/admin/system/form/temp/update',
method: 'POST',
params: params,
data: data
})
}
/**
* 系统通知列表
* @param pram
*/
export function notificationListApi(pram) {
const data = {
sendType: pram.sendType
//发送类型(1:通知会员,2:通知平台)
}
return request({
url: '/admin/system/notification/list',
method: 'GET',
params: data
})
}
/**
* 小程序订阅模板开关
* @param pram
*/
export function notificationRoutine(id) {
return request({
url: `/admin/system/notification/routine/switch/${id}`,
method: 'post',
})
}
/**
* 公众号模板开关
* @param pram
*/
export function notificationWechat(id) {
return request({
url: `/admin/system/notification/wechat/switch/${id}`,
method: 'post',
})
}
/**
* 发送短信开关
* @param pram
*/
export function notificationSms(id) {
return request({
url: `/admin/system/notification/sms/switch/${id}`,
method: 'post',
})
}
/**
* 通知详情
* @param pram
*/
export function notificationDetail(param) {
let data = {
detailType:param.type,
id:param.id
};
return request({
url: `/admin/system/notification/detail`,
method: 'get',
params:data
})
}
//admin/system/notification/detail
/**
* 修改通知
* @param pram
*/
export function notificationUpdate(param) {
let data = {
detailType:param.type,
id:param.id,
status:param.status,
tempId:param.tempId
};
return request({
url: `/admin/system/notification/update`,
method: 'post',
data
})
}
+144
View File
@@ -0,0 +1,144 @@
import request from '@/utils/request'
export function groupDelete(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/system/group/delete',
method: 'GET',
params: data
})
}
export function groupInfo(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/system/group/info',
method: 'GET',
params: data
})
}
export function groupList(pram) {
const data = {
keywords: pram.keywords,
page: pram.page,
limit: pram.limit
}
return request({
url: '/admin/system/group/list',
method: 'GET',
params: data
})
}
export function groupDataList(pram) {
const data = {
gid:pram.gid,
keywords: pram.keywords,
page: pram.page,
limit: pram.limit
}
return request({
url: '/admin/system/group/data/list',
method: 'GET',
params: data
})
}
export function groupSave(pram) {
const data = {
formId: pram.formId,
info: pram.info,
name: pram.name
}
return request({
url: '/admin/system/group/save',
method: 'POST',
params: data
})
}
export function groupEdit(pram) {
const data = {
formId: pram.formId,
info: pram.info,
name: pram.name,
id: pram.id
}
return request({
url: '/admin/system/group/update',
method: 'POST',
params: data
})
}
/**
* @description 页面设计 获取数据
*/
export function designListApi() {
return request.get(`/admin/page/layout/index`)
}
/**
* @description 页面设计商品Tab 获取数据
*/
export function goodDesignList(pram) {
const data = {
gid: pram.gid,
}
return request({
url: '/admin/system/group/data/list',
method: 'GET',
params: data
})
}
/**
* @description 页面设计 保存
*/
export function SaveDataApi(data, url) {
return request({
url: url,
method: 'POST',
data
})
}
/**
* @description 获取配置
*/
export function getDataApi(data) {
return request({
url: '/admin/page/layout/category/config',
method: 'GET',
data
})
}
/**
* @description 保存设置
*/
export function themeSave(params) {
return request({
url: `/admin/system/config/saveuniq`,
method: 'post',
params
})
}
/**
* @description 获取设置
*/
export function getTheme(params) {
return request({
url: `/admin/system/config/getuniq`,
method: 'get',
params
})
}
+57
View File
@@ -0,0 +1,57 @@
import request from '@/utils/request'
export function groupDataDelete(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/system/group/data/delete',
method: 'GET',
params: data
})
}
export function groupDataInfo(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/system/group/data/info',
method: 'GET',
params: data
})
}
export function groupDataList(pram) {
const data = {
gid: pram.gid,
keywords: pram.keywords,
status: pram.status, // 1=开启 2=关闭
page: pram.page,
limit: pram.limit
}
return request({
url: '/admin/system/group/data/list',
method: 'GET',
params: data
})
}
export function groupDataSave(pram) {
return request({
url: '/admin/system/group/data/save',
method: 'POST',
data: pram
})
}
export function groupDataEdit(pram, id) {
return request({
url: '/admin/system/group/data/update',
method: 'POST',
data: pram,
params: { id: id }
})
}
+110
View File
@@ -0,0 +1,110 @@
import request from '@/utils/request'
export function systemConfigCheck(pram) {
const data = {
name: pram.name
}
return request({
url: '/admin/system/config/check',
method: 'GET',
params: data
})
}
export function systemConfigInfo(pram) {
const data = {
formId: pram.id
}
return request({
url: '/admin/system/config/info',
method: 'GET',
params: data
})
}
export function systemConfigSave(pram) {
return request({
url: '/admin/system/config/save/form',
method: 'POST',
data: pram
})
}
/**
* 文件上传
* @param data
*/
export function fileFileApi(data, params) {
return request({
url: '/admin/upload/file',
method: 'POST',
params,
data
})
}
/**
* 图片上传
* @param data
*/
export function fileImageApi(data, params) {
return request({
url: '/admin/upload/image',
method: 'POST',
params,
data
})
}
/**
* 图片列表
* @param data
*/
export function fileListApi(params) {
return request({
url: '/admin/system/attachment/list',
method: 'get',
params
})
}
/**
* 图片列表 删除图片
* @param data
*/
export function fileDeleteApi(id) {
return request({
url: `/admin/system/attachment/delete/${id}`,
method: 'get'
})
}
/**
* 图片列表 移動分類
* @param data
*/
export function attachmentMoveApi(data) {
return request({
url: `/admin/system/attachment/move`,
method: 'post',
data
})
}
/**
* 微信上传图片
* @param data
*/
export function wechatUploadApi(data, params) {
return request({
url: `/admin/wechat/media/upload`,
method: 'post',
data,
params
})
}
+188
View File
@@ -0,0 +1,188 @@
import request from '@/utils/request'
export function getMenu() {
return request({
url: '/admin/system/role/testMenu',
method: 'GET'
})
}
export function adminDel(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/system/admin/delete',
method: 'GET',
params: data
})
}
export function adminInfo(pram) {
const data = {
id: pram.id
}
return request({
url: '/admin/system/admin/info',
method: 'GET',
params: data
})
}
export function adminList(params) {
return request({
url: '/admin/system/admin/list',
method: 'GET',
params
})
}
export function adminAdd(pram) {
const data = {
account: pram.account,
level: pram.level,
pwd: pram.pwd,
realName: pram.realName,
roles: pram.roles.join(','),
status: pram.status,
phone: pram.phone
}
return request({
url: '/admin/system/admin/save',
method: 'POST',
data: data
})
}
export function adminUpdate(pram) {
const data = {
account: pram.account,
level: pram.level,
pwd: pram.pwd,
roles:pram.roles,
realName: pram.realName,
status: pram.status,
id: pram.id,
isDel: pram.isDel
}
return request({
url: '/admin/system/admin/update',
method: 'POST',
data
})
}
/**
* 修改状态
* @param pram
*/
export function updateStatusApi(params) {
return request({
url: `/admin/system/admin/updateStatus`,
method: 'get',
params
})
}
/**
* 修改后台管理员是否接收状态
* @param pram
*/
export function updateIsSmsApi(params) {
return request({
url: `/admin/system/admin/update/isSms`,
method: 'get',
params
})
}
/**
* 权限规则菜单列表
* @param pram
*/
export function menuListApi(params) {
const data = {
menuType: params.menuType, //菜单类型:M-目录,C-菜单,A-按钮
name: params.name, //菜单名称
}
return request({
url: `/admin/system/menu/list`,
method: 'get',
params:data
})
}
/**
* 权限规则新增菜单
* @param data
*/
export function menuAdd(data) {
let systemMenuRequest = data;
return request({
url: `/admin/system/menu/add`,
method: 'post',
data:systemMenuRequest
})
}
/**
* 权限规则删除菜单
* @param data
*/
export function menuDelete(id) {
return request({
url: `/admin/system/menu/delete/${id}`,
method: 'post',
})
}
/**
* 权限规则菜单详情
* @param data
*/
export function menuInfo(id) {
return request({
url: `/admin/system/menu/info/${id}`,
method: 'get',
})
}
/**
* 权限规则菜单修改
* @param data
*/
export function menuUpdate(data) {
let systemMenuRequest = data;
return request({
url: `/admin/system/menu/update`,
method: 'post',
data:systemMenuRequest
})
}
/**
* 权限规则修改菜单显示状态
* @param data
*/
export function menuUpdateShowStatus(params) {
return request({
url: `/admin/system/menu/updateShowStatus`,
method: 'post',
params
})
}
//
/**
* 权限规则菜单详情
* @param data
*/
export function sensitiveListApi(params) {
return request({
url: `/admin/log/sensitive/list`,
method: 'get',
params
})
}
+382
View File
@@ -0,0 +1,382 @@
import request from '@/utils/request'
export function login(data) {
return request({
url: '/admin/login',
method: 'post',
data
})
}
export function getInfo(token) {
return request({
url: '/admin/getAdminInfoByToken',
method: 'get',
params: { token }
})
}
export function logout() {
return request({
url: '/admin/logout',
method: 'get'
})
}
/**
* 会员管理 列表
* @param pram
*/
export function userListApi(params) {
return request({
url: `/admin/user/list`,
method: 'get',
params
})
}
/**
* 会员管理 修改
* @param pram
*/
export function userUpdateApi(params, data) {
return request({
url: `/admin/user/update`,
method: 'post',
params,
data
})
}
/**
* 会员管理等级 修改
* @param pram
*/
export function userLevelUpdateApi( data) {
return request({
url: `/admin/user/update/level`,
method: 'post',
data
})
}
/**
* 会员管理 详情
* @param pram
*/
export function userInfoApi(params) {
return request({
url: `/admin/user/info`,
method: 'get',
params
})
}
/**
* 会员管理 账户详情
* @param pram
*/
export function infobyconditionApi(params) {
return request({
url: `/admin/user/infobycondition`,
method: 'get',
params
})
}
/**
* 会员管理 账户详情top数据
* @param pram
*/
export function topdetailApi(params) {
return request({
url: `/admin/user/topdetail`,
method: 'get',
params
})
}
/**
* 会员管理 批量设置分组
* @param pram
*/
export function groupPiApi(params) {
return request({
url: `/admin/user/group`,
method: 'post',
params
})
}
/**
* 会员管理 批量设置标签
* @param pram
*/
export function tagPiApi(params) {
return request({
url: `/admin/user/tag`,
method: 'post',
params
})
}
/**
* 会员管理 积分余额
* @param pram
*/
export function foundsApi(params) {
return request({
url: `/admin/user/operate/founds`,
method: 'get',
params
})
}
/**
* 会员管理 删除
* @param pram
*/
export function userDeleteApi(params) {
return request({
url: `/admin/user/delete`,
method: 'get',
params
})
}
/**
* 会员等级 列表
* @param pram
*/
export function levelListApi() {
return request({
url: `/admin/system/user/level/list`,
method: 'get'
})
}
/**
* 会员等级 新增
* @param pram
*/
export function levelSaveApi(data) {
return request({
url: `/admin/system/user/level/save`,
method: 'post',
data
})
}
/**
* 会员等级 编辑
* @param pram
*/
export function levelUpdateApi(params, data) {
return request({
url: `/admin/system/user/level/update/${params}`,
method: 'post',
// params,
data
})
}
/**
* 会员等级 详情
* @param pram
*/
export function levelInfoApi(params) {
return request({
url: `/admin/system/user/level/info`,
method: 'get',
params
})
}
/**
* 会员等级 删除
* @param pram
*/
export function levelDeleteApi(id) {
return request({
url: `/admin/system/user/level/delete/${id}`,
method: 'post'
})
}
/**
* 会员等级 是否显示
* @param pram
*/
export function levelUseApi(data) {
return request({
url: `/admin/system/user/level/use`,
method: 'post',
data
})
}
/**
* 会员标签 列表
* @param pram
*/
export function tagListApi(params) {
return request({
url: `/admin/user/tag/list`,
method: 'get',
params
})
}
/**
* 会员标签 新增
* @param pram
*/
export function tagSaveApi(data) {
return request({
url: `/admin/user/tag/save`,
method: 'post',
data
})
}
/**
* 会员标签 编辑
* @param pram
*/
export function tagUpdateApi(params, data) {
return request({
url: `/admin/user/tag/update`,
method: 'post',
params,
data
})
}
/**
* 会员标签 详情
* @param pram
*/
export function tagInfoApi(params) {
return request({
url: `/admin/user/tag/info`,
method: 'get',
params
})
}
/**
* 会员标签 删除
* @param pram
*/
export function tagDeleteApi(params) {
return request({
url: `/admin/user/tag/delete`,
method: 'get',
params
})
}
/**
* 会员分组 列表
* @param pram
*/
export function groupListApi(params) {
return request({
url: `/admin/user/group/list`,
method: 'get',
params
})
}
/**
* 会员分组 新增
* @param pram
*/
export function groupSaveApi(data) {
return request({
url: `/admin/user/group/save`,
method: 'post',
data
})
}
/**
* 会员分组 编辑
* @param pram
*/
export function groupUpdateApi(params, data) {
return request({
url: `/admin/user/group/update`,
method: 'post',
params,
data
})
}
/**
* 会员分组 详情
* @param pram
*/
export function groupInfoApi(params) {
return request({
url: `/admin/user/group/info`,
method: 'get',
params
})
}
/**
* 会员分组 删除
* @param pram
*/
export function groupDeleteApi(params) {
return request({
url: `/admin/user/group/delete`,
method: 'get',
params
})
}
/**
*获取登录页图片
*/
export function getLoginPicApi() {
return request({
url: `/admin/getLoginPic`,
method: 'get'
})
}
/**
* @description 验证码
*/
export function captchaApi() {
return request({
url: `/admin/validate/code/get`,
method: 'get'
})
}
/**
* @description 修改上级推广人
*/
export function updateSpreadApi(data) {
return request({
url: `/admin/user/update/spread`,
method: 'post',
data
})
}
/**
* @description 修改手机号
*/
export function updatePhoneApi(params) {
return request({
url: `/admin/user/update/phone`,
method: 'get',
params
})
}
+393
View File
@@ -0,0 +1,393 @@
import request from '@/utils/request'
export function menuCreate(data) {
return request({
url: '/admin/wechat/menu/public/create',
method: 'post',
params: data
})
}
export function menuDelete(data) {
return request({
url: '/admin/wechat/menu/public/delete',
method: 'post',
params: data
})
}
export function menuInfo(pram) {
const data = {
isAsync: pram.isAsync
}
return request({
url: '/admin/wechat/menu/public/get',
method: 'post',
params: data
})
}
/**
* 微信模板消息 列表
* @param pram
*/
export function wechatTemplateListApi(params) {
return request({
url: `/admin/wechat/template/list`,
method: 'get',
params
})
}
/**
* 微信模板消息 新增
* @param pram
*/
export function wechatTemplateSaveApi(data) {
return request({
url: `/admin/wechat/template/save`,
method: 'post',
data
})
}
/**
* 微信模板消息 编辑
* @param pram
*/
export function wechatTemplateUpdateApi(id, data) {
return request({
url: `/admin/wechat/template/update/${id}`,
method: 'post',
data
})
}
/**
* 微信模板消息 详情
* @param pram
*/
export function wechatTemplateInfoApi(id) {
return request({
url: `/admin/wechat/template/info/${id}`,
method: 'get'
})
}
/**
* 微信模板消息 修改状态
* @param pram
*/
export function wechatTemplateStatusApi(id, params) {
return request({
url: `/admin/wechat/template/update/status/${id}`,
method: 'post',
params
})
}
/**
* 微信模板消息 删除
* @param pram
*/
export function wechatTemplateDeleteApi(id) {
return request({
url: `/admin/wechat/template/delete/${id}`,
method: 'get'
})
}
/**
* 关键字回复 列表
* @param pram
*/
export function replyListApi(params) {
return request({
url: `/admin/wechat/keywords/reply/list`,
method: 'get',
params
})
}
/**
* 关键字回复 新增
* @param pram
*/
export function replySaveApi(data) {
return request({
url: `/admin/wechat/keywords/reply/save`,
method: 'post',
data
})
}
/**
* 关键字回复 修改状态
* @param pram
*/
export function replyStatusApi(params) {
return request({
url: `/admin/wechat/keywords/reply/status`,
method: 'post',
params
})
}
/**
* 关键字回复 编辑
* @param pram
*/
export function replyUpdateApi(params, data) {
return request({
url: `/admin/wechat/keywords/reply/update`,
method: 'post',
params,
data
})
}
/**
* 关键字回复 详情
* @param pram
*/
export function replyInfoApi(params) {
return request({
url: `/admin/wechat/keywords/reply/info`,
method: 'get',
params
})
}
/**
* 关键字回复 删除
* @param pram
*/
export function replyDeleteApi(params) {
return request({
url: `/admin/wechat/keywords/reply/delete`,
method: 'get',
params
})
}
/**
* 关键字查询数据
* @param pram
*/
export function keywordsInfoApi(params) {
return request({
url: `/admin/wechat/keywords/reply/info/keywords`,
method: 'get',
params
})
}
/**
* 微信菜单 获取数据
* @param pram
*/
export function wechatMenuApi(params) {
return request({
url: `/admin/wechat/menu/public/get`,
method: 'get',
params
})
}
/**
* 微信菜单 新增
* @param pram
*/
export function wechatMenuAddApi(data) {
return request({
url: `/admin/wechat/menu/public/create`,
method: 'post',
data
})
}
/**
* 小程序 公共模板列表
*/
export function publicTempListApi(params) {
return request({
url: `/admin/wechat/program/public/temp/list`,
method: 'get',
params
})
}
/**
* 小程序 模版所属类目
*/
export function categoryApi() {
return request({
url: `/admin/wechat/program/category`,
method: 'get'
})
}
/**
* 小程序 通过微信模板tid获取关键字列表
*/
export function getWeChatKeywordsByTidApi(params) {
return request({
url: `/admin/wechat/program/getWeChatKeywordsByTid`,
method: 'get',
params
})
}
/**
* 小程序 模板详情,主要是获取左侧标题
*/
export function publicTempInfoApi(params) {
return request({
url: `/admin/wechat/program/public/temp/info`,
method: 'get',
params
})
}
/**
* 小程序 我的模板列表
*/
export function myTempListApi(params) {
return request({
url: `/admin/wechat/program/my/temp/list`,
method: 'get',
params
})
}
/**
* 小程序 我的模板详情
*/
export function myTempInfoApi(params) {
return request({
url: `/admin/wechat/program/my/temp/info`,
method: 'get',
params
})
}
/**
* 小程序 模板新增
*/
export function myTempSaveApi(data) {
return request({
url: `/admin/wechat/program/my/temp/save`,
method: 'post',
data
})
}
/**
* 小程序 模板修改
*/
export function myTempUpdateApi(params, data) {
return request({
url: `/admin/wechat/program/my/temp/update`,
method: 'post',
params,
data
})
}
/**
* 小程序 我的模板修改状态
*/
export function myTempStatusApi(params) {
return request({
url: `/admin/wechat/program/my/temp/update/status`,
method: 'get',
params
})
}
/**
* 小程序 我的模板修改应用场景
*/
export function myTempTypeApi(params) {
return request({
url: `/admin/wechat/program/my/temp/update/type`,
method: 'get',
params
})
}
/**
* 获取微信sdk配置
* @returns {*}
*/
export function getWechatConfig() {
return request({
url: `/admin/wechat/config`,
method: 'get',
params:{ url: encodeURIComponent(location.href.split('#')[0]) } // for Test
})
}
/**
* 微信授权登录
* @returns {*}
*/
export function wechatAuth(code) {
return request({
url: `/admin/authorize/login`,
method: 'get',
params: { code }
})
}
/**
* 与微信解绑账号
*/
export function unbindApi() {
return request({
url: `/admin/unbind`,
method: 'get'
})
}
/**
* 一键同步我的模板到小程序
*/
export function tempAsyncApi() {
return request({
url: `/admin/wechat/program/my/temp/async`,
method: 'get'
})
}
/**
* 公众号模板消息同步
*/
export function wechatAsyncApi() {
return request({
url: `/admin/wechat/template/whcbqhn/sync`,
method: 'post'
})
}
/**
* 小程序模板消息同步
*/
export function routineAsyncApi() {
return request({
url: `/admin/wechat/template/routine/sync`,
method: 'post'
})
}
/**
* 小程序源码下载
*/
export function wechatCodeDownload() {
return request({
url: `/admin/wechat/code/download`,
method: 'get'
})
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+85
View File
@@ -0,0 +1,85 @@
// JavaScript Document
! function() {
function o(w, v, i) {
return w.getAttribute(v) || i
}
function j(i) {
return document.getElementsByTagName(i)
}
function l() {
var i = j("script"),
w = i.length,
v = i[w - 1];
return {
l: w,
z: o(v, "zIndex", -2),
o: o(v, "opacity", 0.8),
c: o(v, "color", "255,255,255"),
n: o(v, "count", 240)
}
}
function k() {
r = u.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, n = u.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}
function b() {
delay = delay + 1;
if( delay < 5 ) { m(b) } else { delay = 0;
e.clearRect(0, 0, r, n);
var w = [f].concat(t);
var x, v, A, B, z, y;
t.forEach(function(i) {
i.x += i.xa, i.y += i.ya, i.xa *= i.x > r || i.x < 0 ? -1 : 1, i.ya *= i.y > n || i.y < 0 ? -1 : 1, e.fillRect(i.x - 0.5, i.y - 0.5, 2, 2);e.fillStyle="#FFFFFF";
for (v = 0; v < w.length; v++) {
x = w[v];
if (i !== x && null !== x.x && null !== x.y) {
B = i.x - x.x, z = i.y - x.y, y = B * B + z * z;
y < x.max && (x === f && y >= x.max / 2 && (i.x -= 0.03 * B, i.y -= 0.03 * z), A = (x.max - y) / x.max, e.beginPath(), e.lineWidth = A / 2, e.strokeStyle = "rgba(" + s.c + "," + (A + 0.2) + ")", e.moveTo(i.x, i.y), e.lineTo(x.x, x.y), e.stroke())
}
}
w.splice(w.indexOf(i), 1)
}), m(b) }
}
var u = document.createElement("canvas"),
s = l(),
c = "c_n" + s.l,
e = u.getContext("2d"),
delay = 0,
r, n, m = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(i) {
window.setTimeout(i, 1000 / 45)
},
a = Math.random,
f = {
x: null,
y: null,
max: 20000
}
u.id = c;
u.style.cssText = "position:fixed;top:0;left:0;z-index:" + s.z + ";opacity:" + s.o;
j("body")[0].appendChild(u);
k(), window.onresize = k;
window.onmousemove = function(i) {
i = i || window.event, f.x = i.clientX, f.y = i.clientY
}, window.onmouseout = function() {
f.x = null, f.y = null
};
for (var t = [], p = 0; s.n > p; p++) {
var h = a() * r,
g = a() * n,
q = 2 * a() - 1,
d = 2 * a() - 1;
t.push({
x: h,
y: g,
xa: q,
ya: d,
max: 6000
})
}
setTimeout(function() {
b()
}, 100)
}();
+62
View File
@@ -0,0 +1,62 @@
(function flexible(window, document) {
var docEl = document.documentElement || document.body;
var dpr = window.devicePixelRatio || 1;
// adjust body font size
function setBodyFontSize() {
if (document.body) {
} else {
document.addEventListener("DOMContentLoaded", setBodyFontSize);
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit() {
var rem = docEl.clientWidth / 7.5;
docEl.style.fontSize = rem + "px";
}
setRemUnit();
// reset rem unit on page resize
window.addEventListener("resize", setRemUnit);
window.addEventListener("pageshow", function(e) {
if (e.persisted) {
setRemUnit();
}
});
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement("body");
var testElement = document.createElement("div");
testElement.style.border = ".5px solid transparent";
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add("hairlines");
}
docEl.removeChild(fakeBody);
}
if (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") {
handleFontSize();
} else {
if (document.addEventListener) {
document.addEventListener("WeixinJSBridgeReady", handleFontSize, false);
} else if (document.attachEvent) {
document.attachEvent("WeixinJSBridgeReady", handleFontSize);
document.attachEvent("onWeixinJSBridgeReady", handleFontSize);
}
}
function handleFontSize() {
// 设置网页字体为默认大小
WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });
// 重写设置网页字体大小的事件
WeixinJSBridge.on('menu:setfont', function() {
WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });
});
}
})(window, document);
+82
View File
@@ -0,0 +1,82 @@
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
import pathToRegexp from 'path-to-regexp'
export default {
data() {
return {
levelList: null
}
},
watch: {
$route(route) {
// if you go to the redirect page, do not update the breadcrumbs
if (route.path.startsWith('/redirect/')) {
return
}
this.getBreadcrumb()
}
},
created() {
this.getBreadcrumb()
},
methods: {
getBreadcrumb() {
// only show routes with meta.title
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
const first = matched[0]
if (!this.isDashboard(first)) {
matched = [{ path: '/dashboard', meta: { title: '主页' }}].concat(matched)
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
},
isDashboard(route) {
const name = route && route.name
if (!name) {
return false
}
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
},
pathCompile(path) {
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
const { params } = this.$route
var toPath = pathToRegexp.compile(path)
return toPath(params)
},
handleLink(item) {
const { redirect, path } = item
if (redirect) {
this.$router.push(redirect)
return
}
this.$router.push(this.pathCompile(path))
}
}
}
</script>
<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>
+193
View File
@@ -0,0 +1,193 @@
<template>
<div>
<el-form ref="editPram" :model="editPram" label-width="130px">
<el-form-item
label="分类名称"
prop="name"
:rules="[{ required:true,message:'请输入分类名称',trigger:['blur','change'] }]"
>
<el-input v-model="editPram.name"  :maxlength="biztype.value === 1 ? 8 : 20" placeholder="分类名称" />
</el-form-item>
<el-form-item label="URL" v-if="biztype.value!==1 && biztype.value!==3">
<el-input v-model="editPram.url" placeholder="URL" />
</el-form-item>
<el-form-item label="父级" v-if="biztype.value!==3">
<el-cascader v-model="editPram.pid" :disabled="isCreate ===1 && editPram.pid ===0" :options="biztype.value === 5 ? allTreeList : parentOptions" :props="categoryProps" style="width:100%" />
</el-form-item>
<el-form-item label="菜单图标" v-if="biztype.value===5">
<el-input placeholder="请选择菜单图标" v-model="editPram.extra">
<el-button slot="append" icon="el-icon-circle-plus-outline" @click="addIcon"></el-button>
</el-input>
</el-form-item>
<el-form-item label="分类图标(180*180)" v-if="biztype.value === 1 || biztype.value === 3">
<div class="upLoadPicBox" @click="modalPicTap('1')">
<div v-if="editPram.extra" class="pictrue">
<img :src="editPram.extra">
</div>
<div v-else class="upLoad">
<i class="el-icon-camera cameraIconfont" />
</div>
</div>
</el-form-item>
<el-form-item label="排序">
<el-input-number v-model="editPram.sort" :min="0"/>
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="editPram.status" active-text="显示"
inactive-text="隐藏" :active-value="true" :inactive-value="false" />
</el-form-item>
<el-form-item label="扩展字段" v-if="biztype.value !== 1 && biztype.value !== 3 && biztype.value !== 5">
<el-input v-model="editPram.extra" type="textarea" placeholder="扩展字段" />
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loadingBtn" @click="handlerSubmit('editPram')" v-hasPermi="['admin:category:update']">确定</el-button>
<el-button @click="close">取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<!--创建和编辑公用一个组件-->
<script>
import * as categoryApi from '@/api/categoryApi.js'
import * as selfUtil from '@/utils/ZBKJIutil.js'
export default {
// name: "edit"
props: {
prent: {
type: Object,
required: true
},
isCreate: {
type: Number,
default: 0
},
editData: {
type: Object
},
biztype: {
type: Object,
required: true
},
allTreeList: {
type: Array
}
},
data() {
return {
loadingBtn: false,
constants: this.$constants,
editPram: {
extra: null,
name: null,
pid: null,
sort: 0,
status: true,
type: this.biztype.value,
url: null,
id: 0
},
categoryProps: {
value: 'id',
label: 'name',
children: 'child',
expandTrigger: 'hover',
checkStrictly: true,
emitPath: false
},
parentOptions: []
}
},
mounted() {
this.initEditData()
},
methods: {
// 点击图标
addIcon() {
const _this = this
_this.$modalIcon(function(icon) {
_this.editPram.extra = icon
})
},
// 点击商品图
modalPicTap (tit, num, i) {
const _this = this
const attr = []
this.$modalUpload(function(img) {
if(tit==='1'&& !num){
_this.editPram.extra = img[0].sattDir
}
if(tit==='2'&& !num){
img.map((item) => {
attr.push(item.attachment_src)
_this.formValidate.slider_image.push(item)
});
}
},tit, 'store')
},
close() {
this.$emit('hideEditDialog')
},
initEditData() {
this.parentOptions = [...this.allTreeList]
this.addTreeListLabelForCasCard(this.parentOptions, 'child')
const { extra, name, pid, sort, status, type, id, url } = this.editData
if(this.isCreate === 1){
this.editPram.extra = extra
this.editPram.name = name
this.editPram.pid = pid
this.editPram.sort = sort
this.editPram.status = status
this.editPram.type = type
this.editPram.url = url
this.editPram.id = id
}else{
this.editPram.pid = this.prent.id
this.editPram.type = this.biztype.value
}
},
addTreeListLabelForCasCard(arr, child) {
arr.forEach((o,i) => {
if (o.child && o.child.length) {
// o.disabled = true
o.child.forEach((j) => {
j.disabled = true
})
}
})
},
handlerSubmit(formName) {
this.$refs[formName].validate((valid) => {
if (!valid) return
this.handlerSaveOrUpdate(this.isCreate === 0)
})
},
handlerSaveOrUpdate(isSave) {
if (isSave) {
// this.editPram.pid = this.prent.id
this.loadingBtn = true
categoryApi.addCategroy(this.editPram).then(data => {
this.$emit('hideEditDialog')
this.$message.success('创建目录成功')
this.loadingBtn = false
}).catch(() => {
this.loadingBtn = false
})
} else {
this.editPram.pid = Array.isArray(this.editPram.pid) ? this.editPram.pid[0] : this.editPram.pid
this.loadingBtn = true
categoryApi.updateCategroy(this.editPram).then(data => {
this.$emit('hideEditDialog')
this.$message.success('更新目录成功')
this.loadingBtn = false
}).catch(() => {
this.loadingBtn = false
})
}
}
}
}
</script>
<style scoped>
</style>
+89
View File
@@ -0,0 +1,89 @@
<template>
<div>
<el-tree :data="ddd" :props="defaultProps" @node-click="handleNodeClick" />
</div>
</template>
<script>
import * as categoryApi from '@/api/categoryApi.js'
export default {
// name: "info"
props: {
id: {
type: Number,
required: true
}
},
data() {
return {
defaultProps: {
children: 'children',
label: 'label'
},
ddd: [{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
}]
}, {
label: '一级 2',
children: [{
label: '二级 2-1',
children: [{
label: '三级 2-1-1'
}]
}, {
label: '二级 2-2',
children: [{
label: '三级 2-2-1'
}]
}]
}, {
label: '一级 3',
children: [{
label: '二级 3-1',
children: [{
label: '三级 3-1-1'
}]
}, {
label: '二级 3-2',
children: [{
label: '三级 3-2-1'
}]
}]
}],
dataList: {// 数据结果
page: 0,
limit: 0,
totalPage: 0,
total: 0,
list: []
}
}
},
mounted() {
this.handlerGetTreeList(this.id)
},
methods: {
handlerGetTreeList(id) {
if (!id) {
this.$message.error('当前数据id不正确')
return
}
categoryApi.treeCategroy({ pid: id }).then(data => {
this.dataList = data
})
},
handleNodeClick(data) {
console.log('data:', data)
}
}
}
</script>
<style scoped>
</style>
+329
View File
@@ -0,0 +1,329 @@
<template>
<div>
<template v-if="selectModel">
<el-tree
ref="tree"
:data="treeList"
show-checkbox
node-key="id"
@check="getCurrentNode"
:default-checked-keys="selectModelKeysNew"
:props="treeProps">
</el-tree>
</template>
<template v-else>
<div class="divBox">
<el-card class="box-card">
<div slot="header" class="clearfix">
<div class="container">
<el-form inline size="small">
<el-form-item label="状态:">
<el-select v-model="listPram.status" placeholder="状态" class="selWidth" @change="handlerGetList">
<el-option label="全部" :value="-1"></el-option>
<el-option label="显示" :value="1"></el-option>
<el-option label="不显示" :value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="名称:">
<el-input v-model="listPram.name" placeholder="请输入名称" class="selWidth" size="small" clearable>
<el-button slot="append" icon="el-icon-search" @click="handlerGetList" size="small"/>
</el-input>
</el-form-item>
</el-form>
</div>
<el-button size="mini" type="primary" @click="handleAddMenu({id:0,name:'顶层目录'})" v-hasPermi="['admin:category:save']" >新增{{ biztype.name }}</el-button>
</div>
<el-table
ref="treeList"
:data="treeList"
size="mini"
class="table"
highlight-current-row
row-key="id"
:tree-props="{children: 'child', hasChildren: 'hasChildren'}"
>
<el-table-column prop="name" label="名称" min-width="240">
<template slot-scope="scope">
{{ scope.row.name }} | {{ scope.row.id }}
</template>
</el-table-column>
<template v-if="!selectModel">
<el-table-column label="类型" min-width="150">
<template slot-scope="scope">
<span>{{ scope.row.type | filterCategroyType | filterEmpty }}</span>
</template>
</el-table-column>
<el-table-column label="分类图标" min-width="80">
<template slot-scope="scope">
<div class="listPic" v-if=" biztype.value === 5 ">
<i :class="'el-icon-' + scope.row.extra" style="font-size: 20px;" />
</div>
<div class="demo-image__preview" v-else>
<el-image
style="width: 36px; height: 36px"
:src="scope.row.extra"
:preview-src-list="[scope.row.extra]"
v-if="scope.row.extra"
/>
<img style="width: 36px; height: 36px" v-else :src="defaultImg" alt="">
</div>
</template>
</el-table-column>
<el-table-column label="Url" min-width="250" v-if="biztype.value === 5" key="2">
<template slot-scope="scope">
<span>{{ scope.row.url }}</span>
</template>
</el-table-column>
<el-table-column label="排序" prop="sort" min-width="150" />
<el-table-column
label="状态"
min-width="150"
>
<!-- -->
<template slot-scope="scope" v-if="checkPermi(['admin:category:update:status'])">
<el-switch
v-model="scope.row.status"
:active-value="true"
:inactive-value="false"
active-text="显示"
inactive-text="隐藏"
@change="onchangeIsShow(scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="操作" min-width="200" fixed="right">
<template slot-scope="scope">
<el-button
v-if="(biztype.value === 1 && scope.row.pid === 0) || biztype.value === 5"
type="text"
size="small"
@click="handleAddMenu(scope.row)"
>添加子目录</el-button>
<el-button type="text" size="small" @click="handleEditMenu(scope.row)" v-hasPermi="['admin:category:info']">编辑</el-button>
<el-button type="text" size="small" @click="handleDelMenu(scope.row)" v-hasPermi="['admin:category:delete']">删除</el-button>
</template>
</el-table-column>
</template>
</el-table>
</el-card>
</div>
</template>
<el-dialog
:title="(editDialogConfig.isCreate===0?`创建${biztype.name}`:`编辑${biztype.name}`)"
:visible.sync="editDialogConfig.visible"
destroy-on-close
:close-on-click-modal="false"
>
<edit
v-if="editDialogConfig.visible"
:prent="editDialogConfig.prent"
:is-create="editDialogConfig.isCreate"
:edit-data="editDialogConfig.data"
:biztype="editDialogConfig.biztype"
:all-tree-list="treeList"
@hideEditDialog="hideEditDialog"
/>
</el-dialog>
</div>
</template>
<script>
import * as categoryApi from '@/api/categoryApi.js'
import info from './info'
import edit from './edit'
import * as selfUtil from '@/utils/ZBKJIutil.js'
import { checkPermi, checkRole } from "@/utils/permission";
export default {
// name: "list"
components: { info, edit },
props: {
biztype: { // 类型,1 产品分类,2 附件分类,3 文章分类, 4 设置分类, 5 菜单分类
type: Object,
default: { value: -1 },
validator: (obj) => {
return obj.value > 0
}
},
pid: {
type: Number,
default: 0,
validator: (value) => {
return value >= 0
}
},
selectModel: { // 是否选择模式
type: Boolean,
default: false
},
selectModelKeys: {
type: Array
},
rowSelect: {}
},
data() {
return {
selectModelKeysNew: this.selectModelKeys,
loading: false,
constants: this.$constants,
treeProps: {
label: 'name',
children: 'child',
// expandTrigger: 'hover',
// checkStrictly: false,
// emitPath: false
},
// treeCheckedKeys:[],// 选择模式下的属性结构默认选中
multipleSelection: [],
editDialogConfig: {
visible: false,
isCreate: 0, // 0=创建,1=编辑
prent: {}, // 父级对象
data: {},
biztype: this.biztype // 统一主业务中的目录类型
},
dataList: [],
treeList: [],
listPram: {
pid: this.pid,
type: this.biztype.value,
status: -1,
name: '',
page: this.$constants.page.page,
limit: this.$constants.page.limit[0]
},
viewInfoConfig: {
data: null,
visible: false
},
defaultImg:require('@/assets/imgs/moren.jpg')
}
},
mounted() {
/* if(this.biztype.value === 3){
this.listPram.pageSize = constants.page.pageSize[4]
this.handlerGetList()
}else{*/
this.handlerGetTreeList()
// }
},
methods: {
checkPermi, //权限控制
onchangeIsShow(row){
categoryApi.categroyUpdateStatus( row.id ).then(() => {
this.$message.success('修改成功')
this.handlerGetTreeList()
}).catch(()=>{
row.status = !row.status
})
},
handleEditMenu(rowData) {
this.editDialogConfig.isCreate = 1
this.editDialogConfig.data = rowData
this.editDialogConfig.prent = rowData
this.editDialogConfig.visible = true
},
handleAddMenu(rowData) {
this.editDialogConfig.isCreate = 0
this.editDialogConfig.prent = rowData
this.editDialogConfig.data = {}
this.editDialogConfig.biztype = this.biztype
this.editDialogConfig.visible = true
},
getCurrentNode(data) {
let node = this.$refs.tree.getNode(data);
this.childNodes(node);
// this.parentNodes(node);
//是否编辑的表示
// this.ruleForm.isEditorFlag = true;
//编辑时候使用
this.$emit('rulesSelect', this.$refs.tree.getCheckedKeys());
// this.selectModelKeys = this.$refs.tree.getCheckedKeys();
//无论编辑和新增点击了就传到后台这个值
// this.$emit('rulesSelect', this.$refs.tree.getCheckedKeys().concat(this.$refs.tree.getHalfCheckedKeys()));
// this.ruleForm.menuIdsisEditor = this.$refs.tree.getCheckedKeys().concat(this.$refs.tree.getHalfCheckedKeys());
},
//具体方法可以看element官网api
childNodes(node){
let len = node.childNodes.length;
for(let i = 0; i < len; i++){
node.childNodes[i].checked = node.checked;
this.childNodes(node.childNodes[i]);
}
},
parentNodes(node){
if(node.parent){
for(let key in node){
if(key == "parent"){
node[key].checked = true;
this.parentNodes(node[key]);
}
}
}
},
handleDelMenu(rowData) {
this.$confirm('确定删除当前数据?').then(() => {
categoryApi.deleteCategroy(rowData).then(data => {
this.handlerGetTreeList()
this.$message.success('删除成功')
})
})
},
handlerGetList() {
this.handlerGetTreeList();
// categoryApi.listCategroy({status:this.listPram.status, type: 1 }).then(data => {
// this.treeList = data.list
// })
},
handlerGetTreeList() {
// this.biztype.value === 5 && !this.selectModel) ? -1 : 1
// const _pram = { type: this.biztype.value, status: !this.selectModel ? -1 : (this.biztype.value === 5 ? -1 : 1) }
const _pram = { type: this.biztype.value, status: this.listPram.status, name: this.listPram.name }
this.loading = true
this.biztype.value!==3 ? categoryApi.treeCategroy(_pram).then(data => {
this.treeList = this.handleAddArrt(data)
this.loading = false
}).catch(()=>{
this.loading = false
}) : categoryApi.listCategroy({ type: 3, status: this.listPram.status, pid: this.listPram.pid, name: this.listPram.name}).then(data => {
this.treeList = data.list
})
},
handlerGetInfo(id) {
this.viewInfoConfig.data = id
this.viewInfoConfig.visible = true
},
handleNodeClick(data) {
console.log('data:', data)
},
handleAddArrt(treeData) {
const _result = selfUtil.addTreeListLabel(treeData)
return _result
},
hideEditDialog() {
setTimeout(() => {
this.editDialogConfig.prent = {}
this.editDialogConfig.type = 0
this.editDialogConfig.visible = false
this.handlerGetTreeList()
}, 200)
},
handleSelectionChange(d1, { checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys }) {
// this.multipleSelection = checkedKeys.concat(halfCheckedKeys)
this.multipleSelection = checkedKeys
this.$emit('rulesSelect', this.multipleSelection)
},
}
}
</script>
<style scoped>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>
+78
View File
@@ -0,0 +1,78 @@
<template>
<div v-if="errorLogs.length>0">
<el-badge :is-dot="true" style="line-height: 25px;margin-top: -5px;" @click.native="dialogTableVisible=true">
<el-button style="padding: 8px 10px;" size="small" type="danger">
<svg-icon icon-class="bug" />
</el-button>
</el-badge>
<el-dialog :visible.sync="dialogTableVisible" width="80%" append-to-body>
<div slot="title">
<span style="padding-right: 10px;">Error Log</span>
<el-button size="mini" type="primary" icon="el-icon-delete" @click="clearAll">Clear All</el-button>
</div>
<el-table :data="errorLogs" border>
<el-table-column label="Message">
<template slot-scope="{row}">
<div>
<span class="message-title">Msg:</span>
<el-tag type="danger">
{{ row.err.message }}
</el-tag>
</div>
<br>
<div>
<span class="message-title" style="padding-right: 10px;">Info: </span>
<el-tag type="warning">
{{ row.vm.$vnode.tag }} error in {{ row.info }}
</el-tag>
</div>
<br>
<div>
<span class="message-title" style="padding-right: 16px;">Url: </span>
<el-tag type="success">
{{ row.url }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column label="Stack">
<template slot-scope="scope">
{{ scope.row.err.stack }}
</template>
</el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'ErrorLog',
data() {
return {
dialogTableVisible: false
}
},
computed: {
errorLogs() {
return this.$store.getters.errorLogs
}
},
methods: {
clearAll() {
this.dialogTableVisible = false
this.$store.dispatch('errorLog/clearErrorLog')
}
}
}
</script>
<style scoped>
.message-title {
font-size: 16px;
color: #333;
font-weight: bold;
padding-right: 8px;
}
</style>
@@ -0,0 +1,73 @@
<template>
<div
v-if="isExternal"
:style="styleExternalIcon"
class="svg-external-icon svg-icon"
v-on="$listeners"
/>
<svg
v-else
:class="svgClass"
aria-hidden="true"
v-on="$listeners"
>
<use :xlink:href="iconName" />
</svg>
</template>
<script>
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return `svg-icon ${this.className}`
}
return 'svg-icon'
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
display: inline-block;
}
</style>
@@ -0,0 +1,708 @@
import { getToken } from '@/utils/auth'
import SettingMer from '@/utils/settingMer'
// 表单属性【右面板】
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,
tips:false, //tooltip描述是否开启
tipsDesc:'', //tooltip描述内容
tipsIsLink:false,//是否开启描述链接
tipsLink:'', //描述链接
layout: 'colFormItem',
span: 24,
document: 'https://element.eleme.cn/#/zh-CN/component/input',
// 正则校验规则
regList: []
},
// 组件的插槽属性
__slot__: {
prepend: '',
append: ''
},
// 其余的为可直接写在组件标签上的属性
placeholder: '请输入',
style: { width: '95%' },
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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: '95%' },
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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'
// },
// height: 300, // 编辑器高度
// branding: false // 隐藏右下角品牌烙印
// }
]
// 选择型组件 【左面板】
export const selectComponents = [
{
__config__: {
label: '下拉选择',
showLabel: true,
labelWidth: null,
tag: 'el-select',
tagIcon: 'select',
defaultValue: undefined,
layout: 'colFormItem',
span: 24,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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: '级联选择',
showLabel: true,
labelWidth: null,
tag: 'el-cascader',
tagIcon: 'cascader',
layout: 'colFormItem',
defaultValue: [],
dataType: 'dynamic',
span: 24,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
border: false,
// bindInput:false, //是否开启绑定输入
// bindValve:'', //绑定输入内容
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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: 'time-select',
tagIcon: 'time-select',
span: 24,
showLabel: true,
labelWidth: null,
layout: 'colFormItem',
defaultValue: null,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
},
style: { width: '100%' },
disabled: false,
clearable: true,
placeholder: '请选择',
format: 'HH:mm',
'value-format': 'HH:mm'
},
{
__config__: {
label: '日期选择',
tag: 'el-date-picker',
tagIcon: 'date',
defaultValue: null,
showLabel: true,
labelWidth: null,
span: 24,
layout: 'colFormItem',
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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: 'upload-file',
tagIcon: 'uploadPicture',
layout: 'colFormItem',
defaultValue: null,
showLabel: true,
labelWidth: null,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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
},
accept: '',
// headers: { 'Authori-zation': getToken() },
// data: { model: 'product', pid: 0 },
// action: SettingMer.apiBaseURL + 'admin/upload/image?model=product&pid=0',
// disabled: false,
// accept: '',
name: 'upfile',
// 'auto-upload': false,
// 'list-type': 'text',
// multiple: false
},
{
__config__: {
label: '自定义上传',
tag: 'self-upload',
tagIcon: 'selfUpload',
layout: 'colFormItem',
defaultValue: null,
showLabel: true,
labelWidth: null,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
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: 'https://jsonplaceholder.typicode.com/posts/',
disabled: true,
accept: 'image',
name: 'file',
// 'auto-upload': true,
// 'list-type': 'text',
multiple: false
},
// {
// __config__: {
// label: '富文本编辑器',
// tag: 'tinymce',
// tagIcon: 'rich-text',
// layout: 'colFormItem',
// defaultValue: null,
// showLabel: true,
// labelWidth: null,
// required: false,
// tips:false,
// tipsDesc:'',
// tipsIsLink:false,
// tipsLink:'',
// span: 24,
// showTip: false,
// regList: [],
// document: "http://tinymce.ax-z.cn",
// renderKey: 1636077154813,
// changeTag: true,
// },
// height: 300, // 编辑器高度
// name: 'tinymce',
// disabled: false
// }
]
// 布局型组件 【左面板】
export const layoutComponents = [
{
__config__: {
layout: 'rowFormItem',
tagIcon: 'row',
label: '行容器',
layoutTree: true,
children: [],
document: 'https://element.eleme.cn/#/zh-CN/component/layout'
},
type: 'default',
justify: 'start',
align: 'top'
},
{
__config__: {
label: '按钮',
showLabel: true,
changeTag: true,
labelWidth: null,
tag: 'el-button',
tagIcon: 'button',
defaultValue: undefined,
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
}
]
@@ -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')
}
@@ -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
}
]
@@ -0,0 +1,432 @@
/* eslint-disable max-len */
import ruleTrigger from './ruleTrigger'
import { getToken } from '@/utils/auth'
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__}"`
const headers = { 'Authori-zation': getToken() }
const data = el.data ? 'data' : ''
let child = buildElUploadChild(el)
if (child) child = `\n${child}\n` // 换行
return `<${tag} ${headers} ${data} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${tag}>`
},
'self-upload': el => {
const { tag, vModel } = attrBuilder(el)
const height = el.height ? `:height="${el.height}"` : ''
const multiple = el.multiple ? 'multiple' : ''
const branding = el.branding ? `:branding="${el.branding}"` : ''
return `<${tag} ${vModel} ${height} ${branding} ${multiple}></${tag}>`
},
'ueditor-from': el => {
const { tag, vModel } = attrBuilder(el)
const height = el.height ? `:height="${el.height}"` : ''
return `<${tag} ${vModel}${height} >`
},
'upload-file': el => {
const { tag, vModel } = attrBuilder(el)
const height = el.height ? `:height="${el.height}"` : ''
return `<${tag} ${vModel}${height} >`
},
'time-select': el => {
const { tag, vModel } = attrBuilder(el)
const height = el.height ? `:height="${el.height}"` : ''
return `<${tag} ${vModel}${height} >`
},
tinymce: el => {
const { tag, vModel } = attrBuilder(el)
const branding = el.branding ? `:branding="${el.branding}"` : ''
return `<${tag} ${vModel} ${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')
}
// el-upload 子级
// function buildSelfUploadChild(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
}
@@ -0,0 +1,253 @@
import { isArray } from 'util'
import { exportDefault, titleCase } from '@/utils/index'
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 = JSON.parse(JSON.stringify(formConfig))
const dataList = []
const ruleList = []
const optionsList = []
const propsList = []
const methodList = mixinMethod(type)
const uploadVarList = []
formConfig.fields.forEach(el => {
buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList)
})
const script = buildexport(
formConfig,
type,
dataList.join('\n'),
ruleList.join('\n'),
optionsList.join('\n'),
uploadVarList.join('\n'),
propsList.join('\n'),
methodList.join('\n')
)
confGlobal = null
return script
}
// 构建组件属性
function buildAttributes(scheme, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) {
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)
buildOptionMethod(`get${options}`, model, methodList)
}
}
// 处理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)
})
}
}
// 混入处理函数
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) {
const str = `${methodName}() {
// TODO 发起请求获取数据
this.${model}
},`
methodList.push(str)
}
// js整体拼接
function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) {
const str = `${exportDefault}{
${inheritAttrs[type]}
components: {},
props: [],
data () {
return {
${conf.formModel}: {
${data}
},
${conf.formRules}: {
${rules}
},
${uploadVar}
${selectOptions}
${props}
}
},
computed: {},
watch: {},
created () {},
mounted () {},
methods: {
${methods}
}
}`
return str
}
@@ -0,0 +1,19 @@
/**
* 用于生成表单校验,指定正则规则的触发方式。
* 未在此处声明无触发方式的组件将不生成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',
'time-select': 'change'
}
@@ -0,0 +1,235 @@
<script>
import render from '@/components/FormGenerator/components/render/render.js'
const ruleTrigger = {
'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'
}
function renderFrom(h) {
const { formConfCopy } = this
return (
<el-row gutter={formConfCopy.gutter}>
<el-form
size={formConfCopy.size}
label-position={formConfCopy.labelPosition}
disabled={formConfCopy.disabled}
label-width={`${formConfCopy.labelWidth}px`}
ref={formConfCopy.formRef}
// model不能直接赋值 https://github.com/vuejs/jsx/issues/49#issuecomment-472013664
props={{ model: this[formConfCopy.formModel] }}
rules={this[formConfCopy.formRules]}
>
{renderFormItem.call(this, h, formConfCopy.fields)}
{formConfCopy.formBtns && formBtns.call(this, h)}
</el-form>
</el-row>
)
}
function formBtns(h) {
return <el-col>
<el-form-item size='mini'>
<el-button type='primary' onClick={this.submitForm}>提交</el-button>
</el-form-item>
</el-col>
}
function renderFormItem(h, elementList) {
return elementList.map(scheme => {
const config = scheme.__config__
const layout = layouts[config.layout]
if (layout) {
return layout.call(this, h, scheme)
}
throw new Error(`没有与${config.layout}匹配的layout`)
})
}
function renderChildren(h, scheme) {
const config = scheme.__config__
if (!Array.isArray(config.children)) return null
return renderFormItem.call(this, h, config.children)
}
function setValue(event, config, scheme) {
this.$set(config, 'defaultValue', event)
this.$set(this[this.formConf.formModel], scheme.__vModel__, event)
}
function buildListeners(scheme) {
const config = scheme.__config__
const methods = this.formConf.__methods__ || {}
const listeners = {}
// 给__methods__中的方法绑定this和event
Object.keys(methods).forEach(key => {
listeners[key] = event => methods[key].call(this, event)
})
// 响应 render.js 中的 vModel $emit('input', val)
listeners.input = event => setValue.call(this, event, config, scheme)
return listeners
}
const layouts = {
colFormItem(h, scheme) {
const config = scheme.__config__
const listeners = buildListeners.call(this, scheme)
let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null
if (config.showLabel === false) labelWidth = '0'
if(config.tips && !config.tipsIsLink){
return (
<el-col span={config.span}>
<el-form-item label-width={labelWidth} prop={scheme.__vModel__}
label={config.showLabel ? config.label : ''}>
<el-tooltip effect="dark" placement="top-start" style="padding:10px 5px 0 0;">
            <i class="el-icon-warning-outline" />
            <div slot="content" style="max-width:400px;">{config.tipsDesc}</div>
         </el-tooltip>
<render conf={scheme} {...{ on: listeners }} />
</el-form-item>
</el-col>
)
}else if(config.tips && config.tipsIsLink){
return (
<el-col span={config.span}>
<el-form-item label-width={labelWidth} prop={scheme.__vModel__}
label={config.showLabel ? config.label : ''}>
<el-tooltip effect="dark" placement="top-start" style="padding:10px 5px 0 0;">
            <i class="el-icon-warning-outline" />
            <div slot="content" style="max-width:400px;">
<a href={config.tipsLink} target="_blank">{config.tipsDesc}</a>
</div>
         </el-tooltip>
<render conf={scheme} {...{ on: listeners }} />
</el-form-item>
</el-col>
)
}else{
return (
<el-col span={config.span}>
<el-form-item label-width={labelWidth} prop={scheme.__vModel__}
label={config.showLabel ? config.label : ''}>
<render conf={scheme} {...{ on: listeners }} />
</el-form-item>
</el-col>
)
}
},
rowFormItem(h, scheme) {
let child = renderChildren.apply(this, arguments)
if (scheme.type === 'flex') {
child = <el-row type={scheme.type} justify={scheme.justify} align={scheme.align}>
{child}
</el-row>
}
return (
<el-col span={scheme.span}>
<el-row gutter={scheme.gutter}>
{child}
</el-row>
</el-col>
)
}
}
export default {
components: {
render
},
props: {
formConf: {
type: Object,
required: true
},
formEditData: {
type: Object
},
isEdit: {
type: Boolean,
default: false
}
},
data() {
if (this.isEdit) { // 初始化待编辑数据
this.formConf.fields.forEach(conf => {
// 设置现有的数据
const hasValueForEdit = this.formEditData[conf.__vModel__]
if(hasValueForEdit){
conf.__config__.defaultValue = hasValueForEdit
}
// 如果是el-select标签 判断数据后改变实现默认选中效果
if(conf.__config__.tag === 'el-select' || conf.__config__.tag === 'el-radio-group'){
const perValue = conf.__slot__.options.filter(option => option.value == this.formEditData[conf.__vModel__])
if(perValue.length > 0){ // 有表单数据
conf.__config__.defaultValue = perValue[0].value
}
}
})
}
const data = {
formConfCopy: JSON.parse(JSON.stringify(this.formConf)),
[this.formConf.formModel]: {},
[this.formConf.formRules]: {}
}
this.initFormData(data.formConfCopy.fields, data[this.formConf.formModel])
this.buildRules(data.formConfCopy.fields, data[this.formConf.formRules])
return data
},
methods: {
initFormData(componentList, formData) {
componentList.forEach(cur => {
const config = cur.__config__
if (cur.__vModel__) formData[cur.__vModel__] = config.defaultValue
if (config.children) this.initFormData(config.children, formData)
})
},
buildRules(componentList, rules) {
componentList.forEach(cur => {
const config = cur.__config__
if (Array.isArray(config.regList)) {
if (config.required) {
const required = { required: config.required, message: cur.placeholder }
if (Array.isArray(config.defaultValue)) {
required.type = 'array'
required.message = `请至少选择一个${config.label}`
}
required.message === undefined && (required.message = `${config.label}不能为空`)
config.regList.push(required)
}
rules[cur.__vModel__] = config.regList.map(item => {
item.pattern && (item.pattern = eval(item.pattern))
item.trigger = ruleTrigger && ruleTrigger[config.tag]
return item
})
}
if (config.children) this.buildRules(config.children, rules)
})
},
resetForm() {
this.$emit('resetForm', this.formConf)
this.formConfCopy = JSON.parse(JSON.stringify(this.formConf))
this.$refs[this.formConf.formRef].resetFields()
},
submitForm() {
this.$refs[this.formConf.formRef].validate(valid => {
if (!valid) return false
// 触发sumit事件
this.$emit('submit', this[this.formConf.formModel])
return true
})
}
},
render(h) {
return renderFrom.call(this, h)
}
}
</script>
@@ -0,0 +1,17 @@
## form-generator JSON 解析器
>用于将form-generator导出的JSON解析成一个表单。
### 安装组件
```
npm i form-gen-parser
```
或者
```
yarn add form-gen-parser
```
### 使用示例
> [查看在线示例](https://mrhj.gitee.io/form-generator/#/parser)
示例代码:
> [src\components\parser\example\Index.vue](https://github.com/JakHuang/form-generator/blob/dev/src/components/parser/example/Index.vue)
@@ -0,0 +1,74 @@
<template>
<div>
<parser
v-if="formConf.fields.length > 0"
v-loading="loading"
:is-edit="isCreate === 1"
:form-conf="formConf"
:form-edit-data="editData"
@submit="handlerSubmit"
@resetForm="resetForm"
/>
<!-- editData:{{ editData }}-->
<!-- formConf:{{ formConf }}-->
<!-- isCreate:{{ isCreate }}-->
</div>
</template>
<script>
/**
* 注意:和Parser唯一的区别就是这里仅仅传入表单配置id即可自动加载已配置的表单
* 数据后渲染表单,
* 其他业务和Parser保持一致
*/
import * as systemFormConfigApi from '@/api/systemFormConfig.js'
import parser from '@/components/FormGenerator/components/parser/Parser'
export default {
// name: "ZBParser"
components: { parser },
props: {
formId: {
type: Number,
required: true
},
isCreate: {
type: Number,
default: 0 // 0=create 1=edit
},
editData: {
type: Object
},
},
data() {
return {
loading: false,
formConf: { fields: [] }
}
},
mounted() {
this.handlerGetFormConfig(this.formId)
},
methods: {
handlerGetFormConfig(formId) { // 获取表单配置后生成table列
this.loading = true
const _pram = { id: formId }
systemFormConfigApi.getFormConfigInfo(_pram).then(data => {
this.formConf = JSON.parse(data.content)
this.loading = false
}).catch(()=>{
this.loading = false
})
},
handlerSubmit(formValue) {
this.$emit('submit', formValue)
},
resetForm(formValue){
this.$emit('resetForm', formValue)
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,264 @@
<template>
<div class="test-form">
<parser :form-conf="formConf" @submit="sumbitForm1" />
<parser :key="key2" :form-conf="formConf" @submit="sumbitForm2" />
<el-button @click="change">
change
</el-button>
</div>
</template>
<script>
import Parser from '../Parser'
// 若parser是通过安装npm方式集成到项目中的,使用此行引入
// import Parser from 'form-gen-parser'
export default {
components: {
Parser
},
props: {},
data() {
return {
key2: +new Date(),
formConf: {
fields: [
{
__config__: {
label: '单行文本',
labelWidth: null,
showLabel: true,
changeTag: true,
tag: 'el-input',
tagIcon: 'input',
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
},
{
__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',
formId: 101,
renderKey: 1585980082729
},
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,
__vModel__: 'field101'
},
{
__config__: {
layout: 'rowFormItem',
tagIcon: 'row',
label: '行容器',
layoutTree: true,
children: [
{
__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',
formId: 102,
renderKey: 1586839671259
},
style: {},
max: 5,
'allow-half': false,
'show-text': false,
'show-score': false,
disabled: false,
__vModel__: 'field102'
}
],
document: 'https://element.eleme.cn/#/zh-CN/component/layout',
formId: 101,
span: 24,
renderKey: 1586839668999,
componentName: 'row101',
gutter: 15
},
type: 'default',
justify: 'start',
align: 'top'
}
],
formRef: 'elForm',
formModel: 'formData',
size: 'small',
labelPosition: 'right',
labelWidth: 100,
formRules: 'rules',
gutter: 15,
disabled: false,
span: 24,
formBtns: true,
unFocusedComponentBorder: false
},
formConf2: {
fields: [
{
__config__: {
label: '单行文本',
labelWidth: null,
showLabel: true,
changeTag: true,
tag: 'el-input',
tagIcon: 'input',
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
},
{
__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',
formId: 101,
renderKey: 1585980082729
},
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,
__vModel__: 'field101'
}
],
formRef: 'elForm',
formModel: 'formData',
size: 'small',
labelPosition: 'right',
labelWidth: 100,
formRules: 'rules',
gutter: 15,
disabled: false,
span: 24,
formBtns: true,
unFocusedComponentBorder: false
}
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
change() {
this.key2 = +new Date()
const t = this.formConf
this.formConf = this.formConf2
this.formConf2 = t
},
sumbitForm1(data) {
console.log('sumbitForm1提交数据:', data)
},
sumbitForm2(data) {
console.log('sumbitForm2提交数据:', data)
}
}
}
</script>
<style lang="scss" scoped>
.test-form {
margin: 15px auto;
width: 800px;
padding: 15px;
}
</style>
@@ -0,0 +1,3 @@
import Parser from './Parser'
export default Parser
@@ -0,0 +1,25 @@
{
"name": "form-gen-parser",
"version": "1.0.3",
"description": "表单json解析器",
"main": "lib/form-gen-parser.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"
},
"dependencies": {
"form-gen-render": "^1.0.0"
},
"author": "jakHuang",
"license": "MIT",
"bugs": {
"url": "https://github.com/JakHuang/form-generator/issues"
},
"homepage": "https://github.com/JakHuang/form-generator#readme"
}
@@ -0,0 +1,19 @@
{
"name": "form-gen-render",
"version": "1.0.4",
"description": "表单核心render",
"main": "lib/form-gen-render.umd.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/JakHuang/form-generator.git"
},
"author": "jakhuang",
"license": "MIT",
"bugs": {
"url": "https://github.com/JakHuang/form-generator/issues"
},
"homepage": "https://github.com/JakHuang/form-generator#readme"
}
@@ -0,0 +1,59 @@
function vModel(self, dataObject, defaultValue) {
dataObject.props.value = defaultValue
dataObject.on.input = val => {
self.$emit('input', val)
}
}
const componentChild = {}
/**
* 将./slots中的文件挂载到对象componentChild上
* 文件名为key,对应JSON配置中的__config__.tag
* 文件内容为value,解析JSON配置中的__slot__
*/
const slotsFiles = require.context('./slots', true, /\.js$/)
const keys = slotsFiles.keys() || []
keys.forEach(key => {
const tag = key.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = slotsFiles(key).default
componentChild[tag] = value
})
export default {
render(h) {
const dataObject = {
attrs: {},
props: {},
on: {},
style: {}
}
const confClone = JSON.parse(JSON.stringify(this.conf))
const children = []
const childObjs = componentChild[confClone.__config__.tag]
if (childObjs) {
Object.keys(childObjs).forEach(key => {
const childFunc = childObjs[key]
if (confClone.__slot__ && confClone.__slot__[key]) {
children.push(childFunc(h, confClone, key))
}
})
}
Object.keys(confClone).forEach(key => {
const val = confClone[key]
if (key === '__vModel__') {
vModel(this, dataObject, confClone.__config__.defaultValue)
} else if (dataObject[key]) {
dataObject[key] = { ...dataObject[key], ...val }
} else {
dataObject.attrs[key] = val
}
})
delete dataObject.attrs.__config__
delete dataObject.attrs.__slot__
return h(this.conf.__config__.tag, dataObject, children)
},
props: ['conf']
}
@@ -0,0 +1,5 @@
export default {
default(h, conf, key) {
return conf.__slot__[key]
}
}
@@ -0,0 +1,13 @@
export default {
options(h, conf, key) {
const list = []
conf.__slot__.options.forEach(item => {
if (conf.__config__.optionType === 'button') {
list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>)
} else {
list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>)
}
})
return list
}
}
@@ -0,0 +1,8 @@
export default {
prepend(h, conf, key) {
return <template slot='prepend'>{conf.__slot__[key]}</template>
},
append(h, conf, key) {
return <template slot='append'>{conf.__slot__[key]}</template>
}
}
@@ -0,0 +1,13 @@
export default {
options(h, conf, key) {
const list = []
conf.__slot__.options.forEach(item => {
if (conf.__config__.optionType === 'button') {
list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>)
} else {
list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>)
}
})
return list
}
}
@@ -0,0 +1,9 @@
export default {
options(h, conf, key) {
const list = []
conf.__slot__.options.forEach(item => {
list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>)
})
return list
}
}
@@ -0,0 +1,17 @@
export default {
'list-type': (h, conf, key) => {
const list = []
const config = conf.__config__
if (conf['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} {conf.accept}文件</div>
)
}
return list
}
}
@@ -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'
]
@@ -0,0 +1,3 @@
import Index from './index.vue'
export default Index
@@ -0,0 +1,93 @@
<template>
<textarea :id="tinymceId" class="textarea" />
</template>
<script>
import loadTinymce from '@/components/FormGenerator/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: {
type: [String, Number, Boolean],
default: ''
}
},
data() {
return {
tinymceId: this.id
}
},
mounted() {
loadTinymce(tinymce => {
import('./zh_CN').then(() => {
tinymce.init({
selector: `#${this.tinymceId}`,
language: 'zh_CN',
menubar: 'file edit insert view format table',
plugins,
toolbar,
height: this.$attrs.height || 300,
branding: this.$attrs.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,
init_instance_callback: editor => {
if (this.value) editor.setContent(this.value)
this.vModel(editor)
}
})
})
})
},
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>
<style lang="scss" scoped>
.textarea{
visibility: hidden;
}
</style>
@@ -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"
});
@@ -0,0 +1,110 @@
<template>
<div>
<el-dialog
v-bind="$attrs"
width="500px"
:close-on-click-modal="false"
:modal-append-to-body="false"
v-on="$listeners"
@open="onOpen"
@close="onClose"
>
<el-row :gutter="15">
<el-form
ref="elForm"
:model="formData"
:rules="rules"
size="medium"
label-width="100px"
>
<el-col :span="24">
<el-form-item label="生成类型" prop="type">
<el-radio-group v-model="formData.type">
<el-radio-button
v-for="(item, index) in typeOptions"
:key="index"
:label="item.value"
:disabled="item.disabled"
>
{{ item.label }}
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item v-if="showFileName" label="文件名" prop="fileName">
<el-input v-model="formData.fileName" placeholder="请输入文件名" clearable />
</el-form-item>
</el-col>
</el-form>
</el-row>
<div slot="footer">
<el-button @click="close">
取消
</el-button>
<el-button type="primary" @click="handelConfirm">
确定
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
inheritAttrs: false,
props: ['showFileName'],
data() {
return {
formData: {
fileName: undefined,
type: 'file'
},
rules: {
fileName: [{
required: true,
message: '请输入文件名',
trigger: 'blur'
}],
type: [{
required: true,
message: '生成类型不能为空',
trigger: 'change'
}]
},
typeOptions: [{
label: '页面',
value: 'file'
}, {
label: '弹窗',
value: 'dialog'
}]
}
},
computed: {
},
watch: {},
mounted() {},
methods: {
onOpen() {
if (this.showFileName) {
this.formData.fileName = `${+new Date()}.vue`
}
},
onClose() {
},
close(e) {
this.$emit('update:visible', false)
},
handelConfirm() {
this.$refs.elForm.validate(valid => {
if (!valid) return
this.$emit('confirm', { ...this.formData })
this.close()
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
@@ -0,0 +1,128 @@
<script>
import draggable from 'vuedraggable'
import render from '@/components/FormGenerator/components/render/render'
const components = {
itemBtns(h, element, index, parent) {
const { copyItem, deleteItem } = this.$listeners
return [
<span class='drawing-item-copy' title='复制' onClick={event => {
copyItem(element, parent); event.stopPropagation()
}}>
<i class='el-icon-copy-document' />
</span>,
<span class='drawing-item-delete' title='删除' onClick={event => {
deleteItem(index, parent); event.stopPropagation()
}}>
<i class='el-icon-delete' />
</span>
]
}
}
const layouts = {
colFormItem(h, element, index, parent) {
const { activeItem } = this.$listeners
const config = element.__config__
let className = this.activeId === config.formId ? 'drawing-item active-from-item' : 'drawing-item'
if (this.formConf.unFocusedComponentBorder) className += ' unfocus-bordered'
let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null
if (config.showLabel === false) labelWidth = '0'
if(config.tips == undefined){
this.$set(config,'tips',false);//如果以前的表单没有tooltip配置,就赋值一个默认值用来读取
}
if(config.tips){
return (
<el-col span={config.span} class={className}
nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
<el-form-item label-width={labelWidth}
label={config.showLabel ? config.label : ''} required={config.required}>
<el-tooltip effect="dark" placement="top-start" style="padding:10px 5px 0 0;">
            <i class="el-icon-warning-outline" />
            <div slot="content" style="max-width:400px;">{config.tipsDesc}</div>
         </el-tooltip>
<render key={config.renderKey} conf={element} onInput={ event => {
this.$set(config, 'defaultValue', event)
}} />
</el-form-item>
{components.itemBtns.apply(this, arguments)}
</el-col>
)
}else{
return (
<el-col span={config.span} class={className}
nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
<el-form-item label-width={labelWidth}
label={config.showLabel ? config.label : ''} required={config.required}>
<render key={config.renderKey} conf={element} onInput={ event => {
this.$set(config, 'defaultValue', event)
}} />
</el-form-item>
{components.itemBtns.apply(this, arguments)}
</el-col>
)
}
},
rowFormItem(h, element, index, parent) {
const { activeItem } = this.$listeners
const className = this.activeId === element.__config__.formId
? 'drawing-row-item active-from-item'
: 'drawing-row-item'
let child = renderChildren.apply(this, arguments)
if (element.type === 'flex') {
child = <el-row type={element.type} justify={element.justify} align={element.align}>
{child}
</el-row>
}
return (
<el-col span={element.__config__.span}>
<el-row gutter={element.__config__.gutter} class={className}
nativeOnClick={event => { activeItem(element); event.stopPropagation() }}>
<span class='component-name'>{element.__config__.componentName}</span>
<draggable list={element.__config__.children} animation={340} group='componentsGroup' class='drag-wrapper'>
{child}
</draggable>
{components.itemBtns.apply(this, arguments)}
</el-row>
</el-col>
)
}
}
function renderChildren(h, element, index, parent) {
const config = element.__config__
if (!Array.isArray(config.children)) return null
return config.children.map((el, i) => {
const layout = layouts[el.__config__.layout]
if (layout) {
return layout.call(this, h, el, i, config.children)
}
return layoutIsNotFound.call(this)
})
}
function layoutIsNotFound() {
throw new Error(`没有与${this.element.__config__.layout}匹配的layout`)
}
export default {
components: {
render,
draggable
},
props: [
'element',
'index',
'drawingList',
'activeId',
'formConf'
],
render(h) {
const layout = layouts[this.element.__config__.layout]
if (layout) {
return layout.call(this, h, this.element, this.index, this.drawingList)
}
return layoutIsNotFound.call(this)
}
}
</script>
@@ -0,0 +1,332 @@
<template>
<div>
<el-drawer v-bind="$attrs" v-on="$listeners" @opened="onOpen" @close="onClose">
<div style="height:100%">
<el-row style="height:100%;overflow:auto">
<el-col :md="24" :lg="12" class="left-editor">
<div class="setting" title="资源引用" @click="showResource">
<el-badge :is-dot="!!resources.length" class="item">
<i class="el-icon-setting" />
</el-badge>
</div>
<el-tabs v-model="activeTab" type="card" class="editor-tabs">
<el-tab-pane name="html">
<span slot="label">
<i v-if="activeTab==='html'" class="el-icon-edit" />
<i v-else class="el-icon-document" />
template
</span>
</el-tab-pane>
<el-tab-pane name="js">
<span slot="label">
<i v-if="activeTab==='js'" class="el-icon-edit" />
<i v-else class="el-icon-document" />
script
</span>
</el-tab-pane>
<el-tab-pane name="css">
<span slot="label">
<i v-if="activeTab==='css'" class="el-icon-edit" />
<i v-else class="el-icon-document" />
css
</span>
</el-tab-pane>
</el-tabs>
<div v-show="activeTab==='html'" id="editorHtml" class="tab-editor" />
<div v-show="activeTab==='js'" id="editorJs" class="tab-editor" />
<div v-show="activeTab==='css'" id="editorCss" class="tab-editor" />
</el-col>
<el-col :md="24" :lg="12" class="right-preview">
<div class="action-bar" :style="{'text-align': 'left'}">
<span class="bar-btn" @click="runCode">
<i class="el-icon-refresh" />
刷新
</span>
<span class="bar-btn" @click="exportFile">
<i class="el-icon-download" />
导出vue文件
</span>
<span ref="copyBtn" class="bar-btn copy-btn">
<i class="el-icon-document-copy" />
复制代码
</span>
<span class="bar-btn delete-btn" @click="$emit('update:visible', false)">
<i class="el-icon-circle-close" />
关闭
</span>
</div>
<iframe
v-show="isIframeLoaded"
ref="previewPage"
class="result-wrapper"
frameborder="0"
src="preview.html"
@load="iframeLoad"
/>
<div v-show="!isIframeLoaded" v-loading="true" class="result-wrapper" />
</el-col>
</el-row>
</div>
</el-drawer>
<resource-dialog
:visible.sync="resourceVisible"
:origin-resource="resources"
@save="setResource"
/>
</div>
</template>
<script>
import { parse } from '@babel/parser'
import ClipboardJS from 'clipboard'
import { saveAs } from 'file-saver'
import {
makeUpHtml, vueTemplate, vueScript, cssStyle
} from '@/components/FormGenerator/components/generator/html'
import { makeUpJs } from '@/components/FormGenerator/components/generator/js'
import { makeUpCss } from '@/components/FormGenerator/components/generator/css'
import { exportDefault, beautifierConf, titleCase } from '../utils/index'
import ResourceDialog from './ResourceDialog'
import loadMonaco from '../utils/loadMonaco'
import loadBeautifier from '../utils/loadBeautifier'
const editorObj = {
html: null,
js: null,
css: null
}
const mode = {
html: 'html',
js: 'javascript',
css: 'css'
}
let beautifier
let monaco
export default {
components: { ResourceDialog },
props: ['formData', 'generateConf'],
data() {
return {
activeTab: 'html',
htmlCode: '',
jsCode: '',
cssCode: '',
codeFrame: '',
isIframeLoaded: false,
isInitcode: false, // 保证open后两个异步只执行一次runcode
isRefreshCode: false, // 每次打开都需要重新刷新代码
resourceVisible: false,
scripts: [],
links: [],
monaco: null
}
},
computed: {
resources() {
return this.scripts.concat(this.links)
}
},
watch: {},
created() {
},
mounted() {
window.addEventListener('keydown', this.preventDefaultSave)
const clipboard = new ClipboardJS('.copy-btn', {
text: trigger => {
const codeStr = this.generateCode()
this.$notify({
title: '成功',
message: '代码已复制到剪切板,可粘贴。',
type: 'success'
})
return codeStr
}
})
clipboard.on('error', e => {
this.$message.error('代码复制失败')
})
},
beforeDestroy() {
window.removeEventListener('keydown', this.preventDefaultSave)
},
methods: {
preventDefaultSave(e) {
if (e.key === 's' && (e.metaKey || e.ctrlKey)) {
e.preventDefault()
}
},
onOpen() {
const { type } = this.generateConf
this.htmlCode = makeUpHtml(this.formData, type)
this.jsCode = makeUpJs(this.formData, type)
this.cssCode = makeUpCss(this.formData)
loadBeautifier(btf => {
beautifier = btf
this.htmlCode = beautifier.html(this.htmlCode, beautifierConf.html)
this.jsCode = beautifier.js(this.jsCode, beautifierConf.js)
this.cssCode = beautifier.css(this.cssCode, beautifierConf.html)
loadMonaco(val => {
monaco = val
this.setEditorValue('editorHtml', 'html', this.htmlCode)
this.setEditorValue('editorJs', 'js', this.jsCode)
this.setEditorValue('editorCss', 'css', this.cssCode)
if (!this.isInitcode) {
this.isRefreshCode = true
this.isIframeLoaded && (this.isInitcode = true) && this.runCode()
}
})
})
},
onClose() {
this.isInitcode = false
this.isRefreshCode = false
this.isIframeLoaded = false
},
iframeLoad() {
if (!this.isInitcode) {
this.isIframeLoaded = true
this.isRefreshCode && (this.isInitcode = true) && this.runCode()
}
},
setEditorValue(id, type, codeStr) {
if (editorObj[type]) {
editorObj[type].setValue(codeStr)
} else {
editorObj[type] = monaco.editor.create(document.getElementById(id), {
value: codeStr,
theme: 'vs-dark',
language: mode[type],
automaticLayout: true
})
}
// ctrl + s 刷新
editorObj[type].onKeyDown(e => {
if (e.keyCode === 49 && (e.metaKey || e.ctrlKey)) {
this.runCode()
}
})
},
runCode() {
const jsCodeStr = editorObj.js.getValue()
try {
const ast = parse(jsCodeStr, { sourceType: 'module' })
const astBody = ast.program.body
if (astBody.length > 1) {
this.$confirm(
'js格式不能识别,仅支持修改export default的对象内容',
'提示',
{
type: 'warning'
}
)
return
}
if (astBody[0].type === 'ExportDefaultDeclaration') {
const postData = {
type: 'refreshFrame',
data: {
generateConf: this.generateConf,
html: editorObj.html.getValue(),
js: jsCodeStr.replace(exportDefault, ''),
css: editorObj.css.getValue(),
scripts: this.scripts,
links: this.links
}
}
this.$refs.previewPage.contentWindow.postMessage(
postData,
location.origin
)
} else {
this.$message.error('请使用export default')
}
} catch (err) {
this.$message.error(`js错误:${err}`)
}
},
generateCode() {
const html = vueTemplate(editorObj.html.getValue())
const script = vueScript(editorObj.js.getValue())
const css = cssStyle(editorObj.css.getValue())
return beautifier.html(html + script + css, beautifierConf.html)
},
exportFile() {
this.$prompt('文件名:', '导出文件', {
inputValue: `${+new Date()}.vue`,
closeOnClickModal: false,
inputPlaceholder: '请输入文件名'
}).then(({ value }) => {
if (!value) value = `${+new Date()}.vue`
const codeStr = this.generateCode()
const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
saveAs(blob, value)
})
},
showResource() {
this.resourceVisible = true
},
setResource(arr) {
const scripts = []; const
links = []
if (Array.isArray(arr)) {
arr.forEach(item => {
if (item.endsWith('.css')) {
links.push(item)
} else {
scripts.push(item)
}
})
this.scripts = scripts
this.links = links
} else {
this.scripts = []
this.links = []
}
}
}
}
</script>
<style lang="scss" scoped>
@import '../styles/mixin';
.tab-editor {
position: absolute;
top: 33px;
bottom: 0;
left: 0;
right: 0;
font-size: 14px;
}
.left-editor {
position: relative;
height: 100%;
background: #1e1e1e;
overflow: hidden;
}
.setting{
position: absolute;
right: 15px;
top: 3px;
color: #a9f122;
font-size: 18px;
cursor: pointer;
z-index: 1;
}
.right-preview {
height: 100%;
.result-wrapper {
height: calc(100vh - 33px);
width: 100%;
overflow: auto;
padding: 12px;
box-sizing: border-box;
}
}
@include action-bar;
::v-deep .el-drawer__header {
display: none;
}
</style>

Some files were not shown because too many files have changed in this diff Show More