12.31开源admin代码更新

This commit is contained in:
hejinfu1026
2021-12-31 15:58:40 +08:00
parent ad99c24532
commit f5a9772176
545 changed files with 9743 additions and 139371 deletions

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**

View File

@@ -0,0 +1,41 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
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
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
// 配置管理

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
// 配置分类管理

View File

@@ -1,34 +1,20 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
// 订单量
export function statisticsOrderApi() {
// 首页数据概览
export function viewModelApi() {
return request({
url: '/admin/statistics/home/order',
method: 'get'
})
}
// 销售额
export function statisticsSalesApi() {
return request({
url: '/admin/statistics/home/sales',
method: 'get'
})
}
// 新增用户
export function statisticsUserApi() {
return request({
url: '/admin/statistics/home/user',
method: 'get'
})
}
// 用户访问量
export function statisticsViewsApi() {
return request({
url: '/admin/statistics/home/views',
method: 'get'
url: '/admin/statistics/home/index',
method: 'GET',
})
}
@@ -79,3 +65,11 @@ export function chartOrderYearApi() {
method: 'get'
})
}
// 首页经营数据
export function businessData() {
return request({
url: '/admin/statistics/home/operating/data',
method: 'get',
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**
@@ -108,19 +118,6 @@ export function monitorListApi(params) {
})
}
/**
* 资金监控 佣金详细记录
* @param pram
*/
export function monitorListDetailApi(userId, params) {
return request({
url: `/admin/finance/founds/monitor/list/user/detail/${userId}`,
method: 'get',
params
})
}
/**
* 资金监控 明细类型
* @param pram
@@ -138,8 +135,9 @@ export function monitorListOptionApi() {
*/
export function brokerageListApi(params) {
return request({
url: '/admin/finance/founds/monitor/list/user',
url: '/admin/finance/founds/monitor/brokerage/record',
method: 'get',
params
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
// 城市列表
@@ -168,4 +178,4 @@ export function expressInfo(data) {
method: 'get',
params: { ...data }
})
}
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**
@@ -178,11 +188,11 @@ export function statisticsDataApi(params) {
/**
* 一键改价
*/
export function editPriceApi(params) {
export function updatePriceApi(data) {
return request({
url: `/admin/store/order/editPrice`,
method: 'get',
params
url: `admin/store/order/update/price`,
method: 'post',
data
})
}
@@ -238,3 +248,13 @@ export function videoSendApi(data) {
data
})
}
/**
*打印小票
*/
export function orderPrint(id) {
return request({
url: `/admin/yly/print/${id}`,
method: 'get',
})
}

33
admin/src/api/req.js Normal file
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

View File

@@ -1,11 +1,25 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**
* 新增
* @param
*/
export function addRole(pram) {
const data = {
level: pram.level,
roleName: pram.roleName,
status: pram.status,
rules: pram.rules.join(',')
rules: pram.rules
}
// data.rules = pram.rules.join(',')
return request({
@@ -15,6 +29,10 @@ export function addRole(pram) {
})
}
/**
* 删除
* @param
*/
export function delRole(pram) {
const data = {
id: pram.id
@@ -26,17 +44,21 @@ export function delRole(pram) {
})
}
/**
* 详情
* @param
*/
export function getInfo(pram) {
const data = {
ids: pram.id
}
return request({
url: '/admin/system/role/info',
method: 'get',
params: data
url: `/admin/system/role/info/${pram}`,
method: 'GET',
})
}
/**
* 分页列表
* @param
*/
export function getRoleList(pram) {
const data = {
createTime: pram.createTime,
@@ -55,13 +77,15 @@ export function getRoleList(pram) {
})
}
/**
* 修改
* @param
*/
export function updateRole(pram) {
const data = {
id: pram.id,
level: pram.level,
roleName: pram.roleName,
rules: pram.rules.join(','),
rules: pram.rules,
status: pram.status
}
return request({
@@ -71,3 +95,26 @@ export function updateRole(pram) {
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',
})
}

View File

@@ -1,11 +1,22 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**
* 角色详情
*/
export function getRoleById(pram) {
const data = { ids: pram.roles }
return request({
url: '/admin/system/role/info',
url: `/admin/system/role/info/${pram.roles}`,
method: 'GET',
params: data
})
}
@@ -15,7 +26,7 @@ export function getRoleById(pram) {
*/
export function menuListApi() {
return request({
url: '/admin/system/role/menu',
url: '/admin/getMenus',
method: 'GET'
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**
* @description 短信发送记录 -- 列表

150
admin/src/api/statistic.js Normal file
View File

@@ -0,0 +1,150 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
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
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**
@@ -288,3 +298,15 @@ export function copyConfigApi() {
method: 'post'
})
}
/**
* 订单数据 导出
* @param pram
*/
export function orderExcelApi(params) {
return request({
url: `/admin/export/excel/order`,
method: 'get',
params
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
/**
* @description 附件分类 -- 所有分类

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
export function configCheckUnique(pram) {

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
export function getFormConfigInfo(pram) {
@@ -51,3 +61,87 @@ export function getFormConfigEdit(pram) {
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
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
export function groupDelete(pram) {
@@ -35,6 +45,20 @@ export function groupList(pram) {
})
}
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,
@@ -61,3 +85,68 @@ export function groupEdit(pram) {
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
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
export function groupDataDelete(pram) {

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
export function systemConfigCheck(pram) {
@@ -105,3 +115,4 @@ export function wechatUploadApi(data, params) {
params
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
export function getMenu() {
@@ -50,25 +60,25 @@ export function adminAdd(pram) {
return request({
url: '/admin/system/admin/save',
method: 'POST',
params: data
data: data
})
}
export function adminUpdate(pram) {
// const data = {
// account: pram.account,
// level: pram.level,
// pwd: pram.pwd,
// realName: pram.realName,
// roles: pram.roles.join(','),
// status: pram.status,
// id: pram.id,
// isDel: pram.isDel
// }
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',
params: pram
data
})
}
@@ -95,3 +105,92 @@ export function updateIsSmsApi(params) {
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
})
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
export function login(data) {
@@ -48,6 +58,18 @@ export function userUpdateApi(params, data) {
})
}
/**
* 会员管理等级 修改
* @param pram
*/
export function userLevelUpdateApi( data) {
return request({
url: `/admin/user/update/level`,
method: 'post',
data
})
}
/**
* 会员管理 详情
* @param pram
@@ -136,11 +158,10 @@ export function userDeleteApi(params) {
* 会员等级 列表
* @param pram
*/
export function levelListApi(params) {
export function levelListApi() {
return request({
url: `/admin/system/user/level/list`,
method: 'get',
params
method: 'get'
})
}
@@ -158,13 +179,13 @@ export function levelSaveApi(data) {
/**
* 会员等级 编辑
* @param pram
* @param pram
*/
export function levelUpdateApi(params, data) {
export function levelUpdateApi(params, data) {
return request({
url: `/admin/system/user/level/update`,
url: `/admin/system/user/level/update/${params}`,
method: 'post',
params,
// params,
data
})
}
@@ -185,11 +206,10 @@ export function levelInfoApi(params) {
* 会员等级 删除
* @param pram
*/
export function levelDeleteApi(params) {
export function levelDeleteApi(id) {
return request({
url: `/admin/system/user/level/delete`,
method: 'get',
params
url: `/admin/system/user/level/delete/${id}`,
method: 'post'
})
}
@@ -197,11 +217,11 @@ export function levelDeleteApi(params) {
* 会员等级 是否显示
* @param pram
*/
export function levelUseApi(params) {
export function levelUseApi(data) {
return request({
url: `/admin/system/user/level/use`,
method: 'get',
params
method: 'post',
data
})
}

View File

@@ -1,8 +1,16 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import request from '@/utils/request'
// TODO 微信沟通难度大暂放 呵呵
export function menuCreate(data) {
export function menuCreate(data) {
return request({
url: '/admin/wechat/menu/public/create',
method: 'post',
@@ -361,3 +369,33 @@ export function tempAsyncApi() {
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'
})
}

View File

File diff suppressed because one or more lines are too long

View File

File diff suppressed because one or more lines are too long

View File

@@ -5,6 +5,13 @@
"css_prefix_text": "icon",
"description": "",
"glyphs": [
{
"icon_id": "22329862",
"name": "drag2",
"font_class": "drag2",
"unicode": "e6ac",
"unicode_decimal": 59052
},
{
"icon_id": "15811115",
"name": "line-add commodity",

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -21,14 +21,16 @@
</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-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"/>
<el-input-number v-model="editPram.sort" :min="0"/>
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="editPram.status" active-text="显示"
@@ -38,7 +40,7 @@
<el-input v-model="editPram.extra" type="textarea" placeholder="扩展字段" />
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loadingBtn" @click="handlerSubmit('editPram')">确定</el-button>
<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>

View File

@@ -5,7 +5,6 @@
ref="tree"
:data="treeList"
show-checkbox
check-strictly
node-key="id"
@check="getCurrentNode"
:default-checked-keys="selectModelKeysNew"
@@ -23,12 +22,6 @@
<el-option label="全部" :value="-1"></el-option>
<el-option label="显示" :value="1"></el-option>
<el-option label="不显示" :value="0"></el-option>
<!--<el-option-->
<!--v-for="item in constants.roleListStatus"-->
<!--:key="item.value"-->
<!--:label="item.label"-->
<!--:value="item.value"-->
<!--/>-->
</el-select>
</el-form-item>
<el-form-item label="名称:">
@@ -38,7 +31,7 @@
</el-form-item>
</el-form>
</div>
<el-button size="mini" type="primary" @click="handleAddMenu({id:0,name:'顶层目录'})">新增{{ biztype.name }}</el-button>
<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"
@@ -49,7 +42,7 @@
row-key="id"
:tree-props="{children: 'child', hasChildren: 'hasChildren'}"
>
<el-table-column prop="name" label="名称" min-width="200">
<el-table-column prop="name" label="名称" min-width="240">
<template slot-scope="scope">
{{ scope.row.name }} | {{ scope.row.id }}
</template>
@@ -70,7 +63,9 @@
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>
@@ -84,7 +79,8 @@
label="状态"
min-width="150"
>
<template slot-scope="scope">
<!-- -->
<template slot-scope="scope" v-if="checkPermi(['admin:category:update:status'])">
<el-switch
v-model="scope.row.status"
:active-value="true"
@@ -95,11 +91,7 @@
/>
</template>
</el-table-column>
<!--<el-table-column label="启用状态" width="150">-->
<!--<template slot-scope="scope">-->
<!--<span>{{ scope.row.status | filterYesOrNo }}</span>-->
<!--</template>-->
<!--</el-table-column>-->
<el-table-column label="操作" min-width="200" fixed="right">
<template slot-scope="scope">
<el-button
@@ -108,8 +100,8 @@
size="small"
@click="handleAddMenu(scope.row)"
>添加子目录</el-button>
<el-button type="text" size="small" @click="handleEditMenu(scope.row)">编辑</el-button>
<el-button type="text" size="small" @click="handleDelMenu(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>
@@ -141,6 +133,7 @@ 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 },
@@ -163,9 +156,6 @@ export default {
type: Boolean,
default: false
},
// selectModelKeys: {
// type: String
// },
selectModelKeys: {
type: Array
},
@@ -179,9 +169,9 @@ export default {
treeProps: {
label: 'name',
children: 'child',
expandTrigger: 'hover',
checkStrictly: true,
emitPath: false
// expandTrigger: 'hover',
// checkStrictly: false,
// emitPath: false
},
// treeCheckedKeys:[],// 选择模式下的属性结构默认选中
multipleSelection: [],
@@ -205,7 +195,8 @@ export default {
viewInfoConfig: {
data: null,
visible: false
}
},
defaultImg:require('@/assets/imgs/moren.jpg')
}
},
mounted() {
@@ -217,6 +208,7 @@ export default {
// }
},
methods: {
checkPermi, //权限控制
onchangeIsShow(row){
categoryApi.categroyUpdateStatus( row.id ).then(() => {
this.$message.success('修改成功')
@@ -241,7 +233,7 @@ export default {
getCurrentNode(data) {
let node = this.$refs.tree.getNode(data);
this.childNodes(node);
this.parentNodes(node);
// this.parentNodes(node);
//是否编辑的表示
// this.ruleForm.isEditorFlag = true;
//编辑时候使用
@@ -320,7 +312,7 @@ export default {
// this.multipleSelection = checkedKeys.concat(halfCheckedKeys)
this.multipleSelection = checkedKeys
this.$emit('rulesSelect', this.multipleSelection)
}
},
}
}
</script>

View File

@@ -28,6 +28,10 @@ export const inputComponents = [
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',
@@ -41,7 +45,7 @@ export const inputComponents = [
},
// 其余的为可直接写在组件标签上的属性
placeholder: '请输入',
style: { width: '100%' },
style: { width: '95%' },
clearable: true,
'prefix-icon': '',
'suffix-icon': '',
@@ -59,6 +63,10 @@ export const inputComponents = [
tagIcon: 'textarea',
defaultValue: undefined,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
layout: 'colFormItem',
span: 24,
regList: [],
@@ -71,7 +79,7 @@ export const inputComponents = [
minRows: 4,
maxRows: 4
},
style: { width: '100%' },
style: { width: '95%' },
maxlength: null,
'show-word-limit': false,
readonly: false,
@@ -89,6 +97,10 @@ export const inputComponents = [
layout: 'colFormItem',
span: 24,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
regList: [],
document: 'https://element.eleme.cn/#/zh-CN/component/input'
},
@@ -119,6 +131,10 @@ export const inputComponents = [
span: 24,
layout: 'colFormItem',
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
regList: [],
document: 'https://element.eleme.cn/#/zh-CN/component/input-number'
},
@@ -164,6 +180,10 @@ export const selectComponents = [
layout: 'colFormItem',
span: 24,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/select'
@@ -191,11 +211,15 @@ export const selectComponents = [
labelWidth: null,
tag: 'el-cascader',
tagIcon: 'cascader',
layout: 'colFormItem',
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'
@@ -240,7 +264,13 @@ export const selectComponents = [
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__: {
@@ -268,6 +298,10 @@ export const selectComponents = [
layout: 'colFormItem',
optionType: 'default',
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
regList: [],
changeTag: true,
border: false,
@@ -299,6 +333,10 @@ export const selectComponents = [
labelWidth: null,
layout: 'colFormItem',
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/switch'
@@ -323,6 +361,10 @@ export const selectComponents = [
layout: 'colFormItem',
labelWidth: null,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/slider'
@@ -345,6 +387,10 @@ export const selectComponents = [
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'
@@ -370,6 +416,10 @@ export const selectComponents = [
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'
@@ -395,6 +445,10 @@ export const selectComponents = [
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'
@@ -417,6 +471,10 @@ export const selectComponents = [
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'
@@ -440,6 +498,10 @@ export const selectComponents = [
showLabel: true,
labelWidth: null,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
layout: 'colFormItem',
regList: [],
changeTag: true,
@@ -467,6 +529,10 @@ export const selectComponents = [
labelWidth: null,
layout: 'colFormItem',
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
regList: [],
changeTag: true,
document: 'https://element.eleme.cn/#/zh-CN/component/rate'
@@ -489,6 +555,10 @@ export const selectComponents = [
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'
@@ -502,12 +572,16 @@ export const selectComponents = [
__config__: {
label: '上传文件',
tag: 'upload-file',
tagIcon: 'uploadPicture',
tagIcon: 'uploadPicture',
layout: 'colFormItem',
defaultValue: null,
showLabel: true,
labelWidth: null,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
span: 24,
showTip: false,
buttonText: '点击上传',
@@ -515,7 +589,7 @@ export const selectComponents = [
changeTag: true,
// fileSize: 2,
// sizeUnit: 'MB',
document: 'https://element.eleme.cn/#/zh-CN/component/upload'
document: 'https://element.eleme.cn/#/zh-CN/component/upload'
},
__slot__: {
'list-type': true
@@ -541,6 +615,10 @@ export const selectComponents = [
showLabel: true,
labelWidth: null,
required: true,
tips:false,
tipsDesc:'',
tipsIsLink:false,
tipsLink:'',
span: 24,
showTip: false,
buttonText: '',
@@ -561,25 +639,31 @@ export const selectComponents = [
// 'list-type': 'text',
multiple: false
},
{
__config__: {
label: '富文本编辑器',
tag: 'ueditor-from',
tagIcon: 'ueditorFrom',
layout: 'colFormItem',
defaultValue: null,
showLabel: true,
labelWidth: null,
required: false,
span: 24,
showTip: false,
regList: [],
changeTag: true,
},
height: 300, // 编辑器高度
name: 'ueditor',
disabled: 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
// }
]
// 布局型组件 【左面板】

View File

@@ -15,7 +15,6 @@ const ruleTrigger = {
function renderFrom(h) {
const { formConfCopy } = this
return (
<el-row gutter={formConfCopy.gutter}>
<el-form
@@ -47,7 +46,6 @@ 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)
}
@@ -80,21 +78,51 @@ function buildListeners(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'
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>
)
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)

View File

@@ -11,7 +11,7 @@ yarn add form-gen-parser
```
### 使用示例
> [查看在线示例](https://mrhj.gitee.io/form-generator/#/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)

View File

@@ -37,7 +37,7 @@ export default {
},
editData: {
type: Object
}
},
},
data() {
return {

View File

@@ -1,7 +1,7 @@
/* 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 wxTemplate textpattern visualblocks visualchars wordcount'
'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'

View File

@@ -0,0 +1,3 @@
import Index from './index.vue'
export default Index

View File

@@ -27,18 +27,40 @@ const layouts = {
if (this.formConf.unFocusedComponentBorder) className += ' unfocus-bordered'
let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null
if (config.showLabel === false) labelWidth = '0'
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>
)
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
@@ -103,4 +125,4 @@ export default {
return layoutIsNotFound.call(this)
}
}
</script>
</script>

View File

@@ -52,9 +52,9 @@
<!-- <el-button icon="el-icon-view" type="text" @click="showJson">-->
<!-- 查看json-->
<!-- </el-button>-->
<!-- <el-button icon="el-icon-download" type="text" @click="download">-->
<!-- 导出vue文件-->
<!-- </el-button>-->
<!-- <el-button icon="el-icon-download" type="text" @click="download"> -->
<!-- 导出vue文件 -->
<!-- </el-button> -->
<!-- <el-button class="copy-btn-main" icon="el-icon-document-copy" type="text" @click="copy">-->
<!-- 复制代码-->
<!-- </el-button>-->
@@ -77,7 +77,7 @@
<el-input v-model="selfForm.info" placeholder="描述" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handlerSaveJSON('selfForm')">保存</el-button>
<el-button type="primary" @click="handlerSaveJSON('selfForm')" v-hasPermi="['admin:system:form:update']">保存</el-button>
</el-form-item>
</el-form>
</div>
@@ -168,7 +168,7 @@ import {
getDrawingList, saveDrawingList, getIdGlobal, saveIdGlobal, getFormConf, getFormConfSelf
} from '../utils/db'
import loadBeautifier from '../utils/loadBeautifier'
import {Debounce} from '@/utils/validate'
let beautifier
const emptyActiveData = { style: {}, autosize: {}}
let oldActiveId
@@ -416,7 +416,7 @@ export default {
this.AssembleFormData()
this.jsonDrawerVisible = true
},
handlerSaveJSON(form) {
handlerSaveJSON:Debounce(function(form) {
// this.AssembleFormData()
// loadBeautifier(btf => {
// beautifier = btf
@@ -434,7 +434,7 @@ export default {
this.selfForm.content = JSON.stringify(formConfig)
this.$emit('getFormConfigDataResult', this.selfForm)
})
},
}),
download() {
this.dialogVisible = true
this.showFileName = true

View File

@@ -508,8 +508,25 @@
<el-form-item v-if="activeData.__config__.required !== undefined" label="是否必填">
<el-switch v-model="activeData.__config__.required" />
</el-form-item>
<template v-if="activeData.__config__.layoutTree">
<el-form-item v-if="activeData.__config__.tips !== undefined" label="开启描述">
<el-switch v-model="activeData.__config__.tips" />
</el-form-item>
<el-form-item v-if="activeData.__config__.tips" label="描述内容">
<el-input v-model="activeData.__config__.tipsDesc" placeholder="请输入描述" />
</el-form-item>
<el-form-item v-if="activeData.__config__.tips" label="描述链接">
<el-switch v-model="activeData.__config__.tipsIsLink" />
</el-form-item>
<el-form-item v-if="activeData.__config__.tipsIsLink" label="链接地址">
<el-input v-model="activeData.__config__.tipsLink" placeholder="请输入链接地址" />
</el-form-item>
<!-- <el-form-item v-if="activeData.__config__.bindInput !== undefined" label="绑定输入">
<el-switch v-model="activeData.__config__.bindInput" />
</el-form-item>
<el-form-item v-if="activeData.__config__.bindInput" label="绑定内容">
<el-input v-model="activeData.__config__.bindValve" placeholder="请输入内容" />
</el-form-item> -->
<template v-if="activeData.__config__.layoutTree">
<el-divider>布局结构树</el-divider>
<el-tree
:data="[activeData.__config__]"

View File

@@ -1,101 +0,0 @@
<template>
<div :class="{'hidden':hidden}" class="pagination-container">
<el-pagination
:background="background"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:total="total"
v-bind="$attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script>
import { scrollTo } from '@/utils/scroll-to'
export default {
name: 'Pagination',
props: {
total: {
required: true,
type: Number
},
page: {
type: Number,
default: 1
},
limit: {
type: Number,
default: 20
},
pageSizes: {
type: Array,
default() {
return [10, 20, 30, 50]
}
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
background: {
type: Boolean,
default: true
},
autoScroll: {
type: Boolean,
default: true
},
hidden: {
type: Boolean,
default: false
}
},
computed: {
currentPage: {
get() {
return this.page
},
set(val) {
this.$emit('update:page', val)
}
},
pageSize: {
get() {
return this.limit
},
set(val) {
this.$emit('update:limit', val)
}
}
},
methods: {
handleSizeChange(val) {
this.$emit('pagination', { page: this.currentPage, limit: val })
if (this.autoScroll) {
scrollTo(0, 800)
}
},
handleCurrentChange(val) {
this.$emit('pagination', { page: val, limit: this.pageSize })
if (this.autoScroll) {
scrollTo(0, 800)
}
}
}
}
</script>
<style scoped>
.pagination-container {
background: #fff;
padding: 32px 16px;
}
.pagination-container.hidden {
display: none;
}
</style>

View File

@@ -0,0 +1,3 @@
<template >
<router-view />
</template>

View File

@@ -2,9 +2,6 @@
<div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
<div class="rightPanel-background" />
<div class="rightPanel">
<div class="handle-button" :style="{'top':buttonTop+'px','background-color':theme}" @click="show=!show" v-if="!isPhone">
<i :class="show?'el-icon-close':'el-icon-setting'" />
</div>
<div class="rightPanel-items">
<slot />
</div>
@@ -27,16 +24,21 @@ export default {
type: Number
}
},
data() {
return {
isPhone: this.$wechat.isPhone(),
show: false
}
},
computed: {
show: {
get() {
return this.$store.state.settings.showSettings
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'showSettings',
value: val
})
}
},
theme() {
return this.$store.state.settings.theme
}
},
},
watch: {
show(value) {
@@ -52,6 +54,7 @@ export default {
},
mounted() {
this.insertToBody()
this.addEventClick()
},
beforeDestroy() {
const elx = this.$refs.rightPanel
@@ -91,7 +94,7 @@ export default {
top: 0;
left: 0;
opacity: 0;
transition: opacity .3s cubic-bezier(.7, .3, .1, 1);
transition: opacity .3s cubic-bezier(0, 0, .25, 1);
background: rgba(0, 0, 0, .2);
z-index: -1;
}
@@ -104,14 +107,14 @@ export default {
top: 0;
right: 0;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
transition: all .25s cubic-bezier(.7, .3, .1, 1);
transition: all .25s cubic-bezier(0, 0, .25, 1);
transform: translate(100%);
background: #fff;
z-index: 40000;
}
.show {
transition: all .3s cubic-bezier(.7, .3, .1, 1);
transition: all .3s cubic-bezier(0, 0, .25, 1);
.rightPanel-background {
z-index: 20000;

View File

@@ -1,37 +1,10 @@
<template>
<div class="upload-container">
<el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true">
upload
</el-button>
<el-dialog :visible.sync="dialogVisible">
<el-upload
:multiple="true"
:file-list="fileList"
:show-file-list="true"
:on-remove="handleRemove"
:on-success="handleSuccess"
:before-upload="beforeUpload"
class="editor-slide-upload"
action="https://httpbin.org/post"
list-type="picture-card"
>
<el-button size="small" type="primary">
Click upload
</el-button>
</el-upload>
<el-button @click="dialogVisible = false">
Cancel
</el-button>
<el-button type="primary" @click="handleSubmit">
Confirm
</el-button>
</el-dialog>
<el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click="modalPicTap('2')"> upload</el-button>
</div>
</template>
<script>
// import { getToken } from 'api/qiniu'
export default {
name: 'EditorSlideUpload',
props: {
@@ -48,55 +21,18 @@ export default {
}
},
methods: {
checkAllSuccess() {
return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess)
modalPicTap(tit) {
const _this = this
this.$modalUpload(function(img) {
let arr = [];
if(img.length>10) return this.$message.warning("最多选择10张图片");
img.map((item) => {
arr.push(item.sattDir)
});
// console.log(arr);
_this.$emit('successCBK', arr)
}, tit, 'content')
},
handleSubmit() {
const arr = Object.keys(this.listObj).map(v => this.listObj[v])
if (!this.checkAllSuccess()) {
this.$message('Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!')
return
}
this.$emit('successCBK', arr)
this.listObj = {}
this.fileList = []
this.dialogVisible = false
},
handleSuccess(response, file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
this.listObj[objKeyArr[i]].url = response.files.file
this.listObj[objKeyArr[i]].hasSuccess = true
return
}
}
},
handleRemove(file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
delete this.listObj[objKeyArr[i]]
return
}
}
},
beforeUpload(file) {
const _self = this
const _URL = window.URL || window.webkitURL
const fileName = file.uid
this.listObj[fileName] = {}
return new Promise((resolve, reject) => {
const img = new Image()
img.src = _URL.createObjectURL(file)
img.onload = function() {
_self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height }
}
resolve(true)
})
}
}
}
</script>

View File

@@ -1,8 +1,16 @@
<template>
<div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}">
<div
:class="{ fullscreen: fullscreen }"
class="tinymce-container"
:style="{ width: containerWidth }"
>
<textarea :id="tinymceId" class="tinymce-textarea" />
<div class="editor-custom-btn-container">
<editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" />
<editorImage
color="#1890ff"
class="editor-upload-btn"
@successCBK="imageSuccessCBK"
/>
</div>
</div>
</template>
@@ -12,49 +20,53 @@
* docs:
* https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce
*/
import editorImage from './components/EditorImage'
import plugins from './plugins'
import toolbar from './toolbar'
import load from './dynamicLoadScript'
import editorImage from "./components/EditorImage";
import plugins from "./plugins";
import toolbar from "./toolbar";
import load from "./dynamicLoadScript";
// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
// const tinymceCDN = "https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js";
const tinymceCDN = "https://cdn.bootcdn.net/ajax/libs/tinymce/4.9.3/tinymce.min.js";
export default {
name: 'Tinymce',
name: "Tinymce",
components: { editorImage },
props: {
id: {
type: String,
default: function() {
return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
}
default: function () {
return (
"vue-tinymce-" +
+new Date() +
((Math.random() * 1000).toFixed(0) + "")
);
},
},
value: {
type: String,
default: ''
default: "",
},
toolbar: {
type: Array,
required: false,
default() {
return []
}
return [];
},
},
menubar: {
type: String,
default: 'file edit insert view format table'
default: "file edit insert view format table",
},
height: {
type: [Number, String],
required: false,
default: 360
default: 400,
},
width: {
type: [Number, String],
required: false,
default: 'auto'
}
default: "auto",
},
},
data() {
return {
@@ -63,150 +75,159 @@ export default {
tinymceId: this.id,
fullscreen: false,
languageTypeList: {
'en': 'en',
'zh': 'zh_CN',
'es': 'es_MX',
'ja': 'ja'
}
}
en: "en",
zh: "zh_CN",
es: "es_MX",
ja: "ja",
},
};
},
computed: {
containerWidth() {
const width = this.width
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
return `${width}px`
const width = this.width;
if (/^[\d]+(\.[\d]+)?$/.test(width)) {
// matches `100`, `'100'`
return `${width}px`;
}
return width
}
return width;
},
},
watch: {
value(val) {
if (!this.hasChange && this.hasInit) {
// if (!this.hasChange && this.hasInit) {
this.$nextTick(() =>
window.tinymce.get(this.tinymceId).setContent(val || ''))
}
}
window.tinymce.get(this.tinymceId).setContent(val || "")
);
// }
},
},
mounted() {
this.init()
this.init();
},
activated() {
if (window.tinymce) {
this.initTinymce()
this.initTinymce();
}
},
deactivated() {
this.destroyTinymce()
this.destroyTinymce();
},
destroyed() {
this.destroyTinymce()
this.destroyTinymce();
},
methods: {
init() {
// dynamic load tinymce from cdn
load(tinymceCDN, (err) => {
if (err) {
this.$message.error(err.message)
return
this.$message.error(err.message);
return;
}
this.initTinymce()
})
this.initTinymce();
});
},
initTinymce() {
const _this = this
const _this = this;
window.tinymce.init({
selector: `#${this.tinymceId}`,
language: this.languageTypeList['en'],
language: this.languageTypeList["en"],
height: this.height,
body_class: 'panel-body ',
body_class: "panel-body ",
object_resizing: false,
toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
menubar: this.menubar,
plugins: plugins,
fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 30pt 36pt", // 第二步
font_formats:
"微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings",
end_container_on_empty_block: true,
powerpaste_word_import: 'clean',
powerpaste_word_import: "clean",
code_dialog_height: 450,
code_dialog_width: 1000,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
default_link_target: '_blank',
advlist_bullet_styles: "square",
advlist_number_styles: "default",
imagetools_cors_hosts: ["www.tinymce.com", "codepen.io"],
default_link_target: "_blank",
link_title: false,
nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
init_instance_callback: editor => {
init_instance_callback: (editor) => {
if (_this.value) {
editor.setContent(_this.value)
editor.setContent(_this.value);
}
_this.hasInit = true
editor.on('NodeChange Change KeyUp SetContent', () => {
this.hasChange = true
this.$emit('input', editor.getContent())
})
_this.hasInit = true;
editor.on("NodeChange Change KeyUp SetContent", () => {
this.hasChange = true;
this.$emit("input", editor.getContent());
});
},
setup(editor) {
editor.on('FullscreenStateChanged', (e) => {
_this.fullscreen = e.state
})
}
// 整合七牛上传
// images_dataimg_filter(img) {
// setTimeout(() => {
// const $image = $(img);
// $image.removeAttr('width');
// $image.removeAttr('height');
// if ($image[0].height && $image[0].width) {
// $image.attr('data-wscntype', 'image');
// $image.attr('data-wscnh', $image[0].height);
// $image.attr('data-wscnw', $image[0].width);
// $image.addClass('wscnph');
// }
// }, 0);
// return img
// },
// images_upload_handler(blobInfo, success, failure, progress) {
// progress(0);
// const token = _this.$store.getters.token;
// getToken(token).then(response => {
// const url = response.data.qiniu_url;
// const formData = new FormData();
// formData.append('token', response.data.qiniu_token);
// formData.append('key', response.data.qiniu_key);
// formData.append('file', blobInfo.blob(), url);
// upload(formData).then(() => {
// success(url);
// progress(100);
// })
// }).catch(err => {
// failure('出现未知问题,刷新页面,或者联系程序员')
// console.integralLog(err);
// });
// },
})
editor.on("FullscreenStateChanged", (e) => {
_this.fullscreen = e.state;
});
},
});
},
destroyTinymce() {
const tinymce = window.tinymce.get(this.tinymceId)
const tinymce = window.tinymce.get(this.tinymceId);
if (this.fullscreen) {
tinymce.execCommand('mceFullScreen')
tinymce.execCommand("mceFullScreen");
}
if (tinymce) {
tinymce.destroy()
tinymce.destroy();
}
},
setContent(value) {
window.tinymce.get(this.tinymceId).setContent(value)
window.tinymce.get(this.tinymceId).setContent(value);
},
getContent() {
window.tinymce.get(this.tinymceId).getContent()
window.tinymce.get(this.tinymceId).getContent();
},
imageSuccessCBK(arr) {
const _this = this
arr.forEach(v => {
window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`)
})
}
}
}
const _this = this;
arr.forEach((v) => {
if (this.getFileType(v) == "video") {
window.tinymce.get(_this.tinymceId).insertContent( `<video class="wscnph" src="${v}" controls muted></video>`);
} else {
window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v}" />`);
}
});
},
getFileType(fileName) {
// 后缀获取
let suffix = "";
// 获取类型结果
let result = "";
try {
const flieArr = fileName.split(".");
suffix = flieArr[flieArr.length - 1];
} catch (err) {
suffix = "";
}
// fileName无后缀返回 false
if (!suffix) {
return false;
}
suffix = suffix.toLocaleLowerCase();
// 图片格式
const imglist = ["png", "jpg", "jpeg", "bmp", "gif"];
// 进行图片匹配
result = imglist.find((item) => item === suffix);
if (result) {
return "image";
}
// 匹配 视频
const videolist = ["mp4","m2v","mkv", "rmvb", "wmv","avi","flv","mov","m4v",];
result = videolist.find((item) => item === suffix);
if (result) {
return "video";
}
// 其他 文件类型
return "other";
},
},
};
</script>
<style scoped>
@@ -214,7 +235,7 @@ export default {
position: relative;
line-height: normal;
}
.tinymce-container>>>.mce-fullscreen {
.tinymce-container >>> .mce-fullscreen {
z-index: 10000;
}
.tinymce-textarea {

View File

@@ -2,6 +2,6 @@
// Detail plugins list see https://www.tinymce.com/docs/plugins/
// Custom builds see https://www.tinymce.com/download/custom-builds/
const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table wxTemplate textcolor textpattern visualblocks visualchars wordcount']
const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
export default plugins

View File

@@ -1,6 +1,6 @@
// Here is a list of the toolbar
// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']
const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample fontsizeselect fontselect', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor ']
export default toolbar

View File

@@ -0,0 +1,5 @@
<template>
<div>
</div>
</template>

View File

@@ -13,7 +13,7 @@
<i class="el-icon-document-checked cameraIconfont" />
</div>
</div>
<el-button v-else size="mini" type="primary">点击上传</el-button>
<el-button v-else size="mini" type="primary" v-hasPermi="['admin:upload:file']">点击上传</el-button>
</el-upload>
</div>
</template>

View File

@@ -31,10 +31,8 @@
<template slot-scope="scope">
<div class="demo-image__preview">
<el-image
v-for="(item, index) in scope.row.imageInput"
:key="index"
style="width: 36px; height: 36px"
:src="item"
:src="scope.row.imageInput"
:preview-src-list="imgList"
/>
</div>
@@ -121,11 +119,11 @@
handlerGetListData(pram) {
articleApi.ListArticle(pram).then(data => {
this.listData = data
this.listData.list.map((item) => {
item.imageInput.map(i => {
this.imgList.push(i)
})
})
// this.listData.list.map((item) => {
// item.imageInput.map(i => {
// this.imgList.push(i)
// })
// })
})
},
handlerGetCategoryTreeData() {

View File

@@ -1,16 +1,15 @@
<template>
<el-row align="middle" :gutter="10" class="ivu-mt">
<el-col :xl="6" :lg="6" :md="12" :sm="24" :xs="24" class="ivu-mb mb10" v-for="(item, index) in cardLists"
<el-row align="middle" :gutter="20" class="ivu-mt">
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="ivu-mb mb20" v-for="(item, index) in cardLists"
:key="index">
<div class="card_box">
<div class="card_box_cir" :class="{'one':index%5==0,'two':index%5==1,'three':index%5==2,'four':index%5==3,'five':index%5==4}">
<div class="card_box_cir1" :class="{'one1':index%5==0,'two1':index%5==1,'three1':index%5==2,'four1':index%5==3,'five1':index%5==4}">
<i class="el-icon-edit" style="color: #fff;"></i>
</div>
<div class="card_box_cir" :class="item.class">
<span class="iconfont" :class="item.icon" :style="{color:item.color}" v-if="item.icon"></span>
<i class="el-icon-edit" style="color: #fff;" v-else></i>
</div>
<div class="card_box_txt">
<span class="sp1" v-text="item.count || 0"></span>
<span class="sp2" v-text="item.name"></span>
<span class="sp1" v-text="item.count || 0"></span>
</div>
</div>
</el-col>
@@ -27,76 +26,81 @@
</script>
<style scoped lang="scss">
.one{
background: #E4ECFF;
}
.two{
background: #FFF3E0;
}
.three{
background: #EAF9E1;
}
.four{
background: #FFEAF4;
}
.five{
background: #F1E4FF;
}
.one {
background: rgba(24, 144, 255, .1);
}
.two {
background: rgba(162, 119, 255, .1);
}
.three {
background: rgba(232, 182, 0, .1);
}
.four {
background: rgba(27, 190, 107, .1);
}
.five {
background: rgba(75, 202, 213, .1);
}
.six {
background: rgba(239, 156, 32, .1);
}
.one1{
background: #4D7CFE;
background: #1890FF;
}
.two1{
background: #FFAB2B;
background: #A277FF;
}
.three1{
background: #6DD230;
background: #EF9C20;
}
.four1{
background: #FF85C0;
background: #1BBE6B;
}
.five1{
background: #B37FEB;
background: #4BCAD5;
}
.six1{
background: #EF9C20;
}
.card_box {
width: 100%;
height: 100%;
height: 110px;
display: flex;
align-items: center;
/*justify-content: center*/
padding: 25px;
box-sizing: border-box;
border-radius: 4px;
background: #f5f7f9;
background: #fff;
box-sizing: border-box;
.card_box_cir {
width: 60px;
height: 60px;
border-radius: 50%;
width: 50px;
height: 50px;
border-radius: 4px;
overflow: hidden;
margin-right: 20px;
display: flex;
justify-content: center;
align-items: center;
.card_box_cir1 {
width: 48px;
height: 48px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
}
.card_box_txt {
.sp1 {
display: block;
color: #252631;
font-size: 24px;
line-height: 37px;
color: #333333;
font-size: 28px;
padding-top: 3px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
}
.sp2 {
display: block;
color: #98A9BC;
font-size: 12px;
color: #606266;
font-size: 14px;
font-weight: 400;
}
}
}
.iconfont{
font-size: 23px;
}
</style>

View File

@@ -69,7 +69,7 @@
</el-table-column>
<el-table-column v-if="handle==='send'" label="操作" min-width="120" fixed="right" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" class="mr10" @click="sendGrant(scope.row.id)">发送</el-button>
<el-button type="text" size="small" class="mr10" @click="sendGrant(scope.row.id)" v-hasPermi="['admin:coupon:user:receive']">发送</el-button>
</template>
</el-table-column>
</el-table>

View File

@@ -60,7 +60,7 @@
min-Width="120"/>
<el-table-column label="身份" prop="realName" min-width="230">
<template slot-scope="scope">
<el-tag size="small" type="info" v-for="(item, index) in scope.row.roleNames.split(',')" class="mr5">{{ item }}</el-tag>
<el-tag size="small" type="info" v-for="(item, index) in scope.row.roleNames.split(',')" :key="index" class="mr5">{{ item }}</el-tag>
</template>
</el-table-column>
<el-table-column label="最后登录时间" prop="lastTime" min-width="180">

View File

@@ -0,0 +1,71 @@
<template>
<div>
<div :id="echarts" :style="styles" />
</div>
</template>
<script>
import echarts from 'echarts'
export default {
name: 'Index',
props: {
styles: {
type: Object,
default: null
},
optionData: {
type: Object,
default: null
}
},
data() {
return {
myChart: null
}
},
computed: {
echarts() {
return 'echarts' + Math.ceil(Math.random() * 100)
}
},
watch: {
optionData: {
handler(newVal, oldVal) {
this.handleSetVisitChart()
},
deep: true // 对象内部属性的监听,关键。
}
},
mounted: function() {
const vm = this
vm.$nextTick(() => {
vm.handleSetVisitChart()
window.addEventListener('resize', this.wsFunc)
})
},
beforeDestroy() {
window.removeEventListener('resize', this.wsFunc)
if (!this.myChart) {
return
}
this.myChart.dispose()
this.myChart = null
},
methods: {
wsFunc() {
this.myChart.resize()
},
handleSetVisitChart() {
this.myChart = echarts.init(document.getElementById(this.echarts))
let option = null
option = this.optionData
// 基于准备好的dom初始化echarts实例
this.myChart.setOption(option, true)
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,85 +0,0 @@
<template>
<div>
<vue-ueditor-wrap v-model="contents" :config="myConfig" style="width: 90%;" @beforeInit="addCustomDialog" />
</div>
</template>
<script>
export default {
name: 'Index',
// components: { VueUeditorWrap },
scrollerHeight: {
content: String,
default: ''
},
props: {
content: {
type: String,
default: ''
},
value: {}
},
beforeMount(){
// 接收 v-model 数据
if(this.value){
this.contents = this.value
}
},
data() {
return {
contents: this.content,
myConfig: {
autoHeightEnabled: false, // 编辑器不自动被内容撑高
initialFrameHeight: 500, // 初始容器高度
initialFrameWidth: '100%', // 初始容器宽度
UEDITOR_HOME_URL: '/UEditor/',
serverUrl: ''
}
}
},
watch: {
content: function(val) {
this.contents = this.content
},
contents: function(val) {
this.$emit('input', val)
}
},
methods: {
// 添加自定义弹窗
addCustomDialog(editorId) {
window.UE.registerUI('test-dialog', function(editor, uiName) {
// 创建 dialog
const dialog = new window.UE.ui.Dialog({
// 指定弹出层中页面的路径,这里只能支持页面,路径参考常见问题 2
iframeUrl: '/setting/uploadPicture?field=dialog&type=2',
// 需要指定当前的编辑器实例
editor: editor,
// 指定 dialog 的名字
name: uiName,
// dialog 的标题
title: '上传图片',
// 指定 dialog 的外围样式
cssRules: 'width:1000px;height:620px;padding:20px;'
})
this.dialog = dialog
var btn = new window.UE.ui.Button({
name: 'dialog-button',
title: '上传图片',
cssRules: `background-image: url(@/assets/images/icons.png);background-position: -726px -77px;`,
onclick: function() {
// 渲染dialog
dialog.render()
dialog.open()
}
})
return btn
}, 37)
}
}
}
</script>
<style scoped>
</style>

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
(function () {
/* eslint-disable */
if (window.frameElement.id) {
let parent = window.parent,
dialog = parent.$EDITORUI[window.frameElement.id.replace(/_iframe$/, '')],
editor = dialog.editor,
UE = parent.UE,
domUtils = UE.dom.domUtils,
utils = UE.utils,
browser = UE.browser,
/* eslint-disable */
ajax = UE.ajax,
$G = function (id) {
return document.getElementById(id)
},
$focus = function (node) {
setTimeout(function () {
if (browser.ie) {
var r = node.createTextRange();
r.collapse(false);
r.select();
} else {
node.focus()
}
}, 0)
};
window.nowEditor = {editor: editor, dialog: dialog};
utils.loadFile(document, {
href: editor.options.themePath + editor.options.theme + '/dialogbase.css?cache=' + Math.random(),
tag: 'link',
type: 'text/css',
rel: 'stylesheet'
});
var lang = editor.getLang(dialog.className.split('-')[2]);
if (lang) {
domUtils.on(window, 'load', function () {
var langImgPath = editor.options.langPath + editor.options.lang + '/images/';
// 针对静态资源
for (var i in lang['static']) {
var dom = $G(i);
if (!dom) continue;
let tagName = dom.tagName,
content = lang['static'][i];
if (content.src) {
// clone
content = utils.extend({}, content, false);
content.src = langImgPath + content.src;
}
if (content.style) {
content = utils.extend({}, content, false);
content.style = content.style.replace(/url\s*\(/g, 'url(' + langImgPath)
}
switch (tagName.toLowerCase()) {
case 'var':
dom.parentNode.replaceChild(document.createTextNode(content), dom);
break;
case 'select':
var ops = dom.options;
for (var j = 0, oj; oj = ops[j];) {
oj.innerHTML = content.options[j++];
}
for (var p in content) {
p != 'options' && dom.setAttribute(p, content[p]);
}
break;
default :
domUtils.setAttributes(dom, content);
}
}
});
}
}
})();

View File

@@ -13,11 +13,12 @@ uploadFrom.install = function(Vue, options) {
const instance = new ToastConstructor()
instance.$mount(document.createElement('div'))
document.body.appendChild(instance.$el)
Vue.prototype.$modalUpload = function(callback, isMore, modelName) {
Vue.prototype.$modalUpload = function(callback, isMore, modelName, boolean) {
instance.visible = true
instance.callback = callback
instance.isMore = isMore
instance.modelName = modelName
instance.booleanVal = boolean
}
}
export default uploadFrom

View File

@@ -4,7 +4,7 @@
title="上传图片"
:visible.sync="visible"
width="950px"
:modal="false"
:modal="booleanVal"
append-to-body
:before-close="handleClose"
>
@@ -24,7 +24,8 @@ export default {
callback: function() {},
isMore: '',
modelName: '',
ISmodal: false
ISmodal: false,
booleanVal: false
}
},
watch: {

View File

@@ -5,7 +5,7 @@
<el-form inline>
<el-form-item>
<el-input v-model="tableFrom.keywords" placeholder="请输入用户名称" class="selWidth">
<el-button slot="append" icon="el-icon-search" @click="getList" />
<el-button slot="append" icon="el-icon-search" @click="search" />
</el-input>
</el-form-item>
</el-form>
@@ -17,7 +17,7 @@
size="small"
>
<el-table-column label="" width="40">
<template scope="scope">
<template slot-scope="scope">
<el-radio v-model="templateRadio" :label="scope.row.uid" @change.native="getTemplateRow(scope.$index,scope.row)">&nbsp</el-radio>
</template>
</el-table-column>
@@ -31,7 +31,7 @@
label="微信用户名称"
min-width="130"
/>
<el-table-column label="客服头像" min-width="80">
<el-table-column label="用户头像" min-width="80">
<template slot-scope="scope">
<div class="demo-image__preview">
<el-image
@@ -129,6 +129,17 @@ export default {
this.loading = false
})
},
search(){
this.loading = true
userListApi({keywords:this.tableFrom.keywords}).then(res => {
this.tableData.data = res.list
this.tableData.total = res.total
this.loading = false
}).catch(res => {
this.$message.error(res.message)
this.loading = false
})
},
pageChange(page) {
this.tableFrom.page = page
this.getList()

View File

@@ -1,49 +0,0 @@
// Inspired by https://github.com/Inndy/vue-clipboard2
const Clipboard = require('clipboard')
if (!Clipboard) {
throw new Error('you should npm install `clipboard` --save at first ')
}
export default {
bind(el, binding) {
if (binding.arg === 'success') {
el._v_clipboard_success = binding.value
} else if (binding.arg === 'error') {
el._v_clipboard_error = binding.value
} else {
const clipboard = new Clipboard(el, {
text() { return binding.value },
action() { return binding.arg === 'cut' ? 'cut' : 'copy' }
})
clipboard.on('success', e => {
const callback = el._v_clipboard_success
callback && callback(e) // eslint-disable-line
})
clipboard.on('error', e => {
const callback = el._v_clipboard_error
callback && callback(e) // eslint-disable-line
})
el._v_clipboard = clipboard
}
},
update(el, binding) {
if (binding.arg === 'success') {
el._v_clipboard_success = binding.value
} else if (binding.arg === 'error') {
el._v_clipboard_error = binding.value
} else {
el._v_clipboard.text = function() { return binding.value }
el._v_clipboard.action = function() { return binding.arg === 'cut' ? 'cut' : 'copy' }
}
},
unbind(el, binding) {
if (binding.arg === 'success') {
delete el._v_clipboard_success
} else if (binding.arg === 'error') {
delete el._v_clipboard_error
} else {
el._v_clipboard.destroy()
delete el._v_clipboard
}
}
}

View File

@@ -1,13 +0,0 @@
import Clipboard from './clipboard'
const install = function(Vue) {
Vue.directive('Clipboard', Clipboard)
}
if (window.Vue) {
window.clipboard = Clipboard
Vue.use(install); // eslint-disable-line
}
Clipboard.install = install
export default Clipboard

View File

@@ -0,0 +1,74 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import { Message } from 'element-ui';
const vCopy = { // 名字爱取啥取啥
/*
bind 钩子函数,第一次绑定时调用,可以在这里做初始化设置
el: 作用的 dom 对象
value: 传给指令的值,也就是我们要 copy 的值
*/
bind(el, { value }) {
el.$value = value; // 用一个全局属性来存传进来的值,因为这个值在别的钩子函数里还会用到
el.handler = () => {
if (!el.$value) {
// 值为空的时候,给出提示,我这里的提示是用的 element-ui 的提示,你们随意
Message.warning('无复制内容');
return;
}
// 动态创建 textarea 标签
const textarea = document.createElement('textarea');
// 将该 textarea 设为只读,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly';
textarea.style.position = 'absolute';
textarea.style.left = '-9999px';
// 将要 copy 的值赋给 textarea 标签的 value 属性
textarea.value = el.$value;
// 将 textarea 插入到 body 中
document.body.appendChild(textarea);
// 选中值并复制
textarea.select();
textarea.setSelectionRange(0, textarea.value.length);
//就是可以通过设置起始于终止位置,来选中一段文本中的一部分,这里其实就是全选
const result = document.execCommand('Copy');
//html原生的复制功能
/**
* 拓展
* :document.execCommand(”selectAll”) 全选
* :document.execCommand(open) 打开
* :document.execCommand(saveAs) 另存为
*/
if (result) {
Message.success('复制成功');
}
document.body.removeChild(textarea);
//复制成功然后删除textarea标签
};
// 绑定点击事件,就是所谓的一键 copy 啦
el.addEventListener('click', el.handler);
},
// 当传进来的值更新的时候触发
componentUpdated(el, { value }) {
el.$value = value;
},
// 指令与元素解绑的时候,移除事件绑定
unbind(el) {
el.removeEventListener('click', el.handler);
},
};
//使用示例 <el-button v-copy="info">复制</el-button>
//data() {
// return {
// info:'要复制的内容'
// }
export default vCopy;

View File

@@ -0,0 +1,64 @@
/**
* v-dialogDrag 弹窗拖拽
* Copyright (c) 2019 ruoyi
*/
export default {
bind(el, binding, vnode, oldVnode) {
const value = binding.value
if (value == false) return
// 获取拖拽内容头部
const dialogHeaderEl = el.querySelector('.el-dialog__header');
const dragDom = el.querySelector('.el-dialog');
dialogHeaderEl.style.cursor = 'move';
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
dragDom.style.position = 'absolute';
dragDom.style.marginTop = 0;
let width = dragDom.style.width;
if (width.includes('%')) {
width = +document.body.clientWidth * (+width.replace(/\%/g, '') / 100);
} else {
width = +width.replace(/\px/g, '');
}
dragDom.style.left = `${(document.body.clientWidth - width) / 2}px`;
// 鼠标按下事件
dialogHeaderEl.onmousedown = (e) => {
// 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
const disX = e.clientX - dialogHeaderEl.offsetLeft;
const disY = e.clientY - dialogHeaderEl.offsetTop;
// 获取到的值带px 正则匹配替换
let styL, styT;
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
if (sty.left.includes('%')) {
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100);
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100);
} else {
styL = +sty.left.replace(/\px/g, '');
styT = +sty.top.replace(/\px/g, '');
};
// 鼠标拖拽事件
document.onmousemove = function (e) {
// 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
const l = e.clientX - disX;
const t = e.clientY - disY;
let finallyL = l + styL
let finallyT = t + styT
// 移动当前元素
dragDom.style.left = `${finallyL}px`;
dragDom.style.top = `${finallyT}px`;
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
}
}
};

View File

@@ -0,0 +1,34 @@
/**
* v-dialogDragWidth 可拖动弹窗高度(右下角)
* Copyright (c) 2019 ruoyi
*/
export default {
bind(el) {
const dragDom = el.querySelector('.el-dialog');
const lineEl = document.createElement('div');
lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
lineEl.addEventListener('mousedown',
function(e) {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - el.offsetLeft;
const disY = e.clientY - el.offsetTop;
// 当前宽度 高度
const curWidth = dragDom.offsetWidth;
const curHeight = dragDom.offsetHeight;
document.onmousemove = function(e) {
e.preventDefault(); // 移动时禁用默认事件
// 通过事件委托,计算移动的距离
const xl = e.clientX - disX;
const yl = e.clientY - disY
dragDom.style.width = `${curWidth + xl}px`;
dragDom.style.height = `${curHeight + yl}px`;
};
document.onmouseup = function(e) {
document.onmousemove = null;
document.onmouseup = null;
};
}, false);
dragDom.appendChild(lineEl);
}
}

View File

@@ -0,0 +1,30 @@
/**
* v-dialogDragWidth 可拖动弹窗宽度(右侧边)
* Copyright (c) 2019 ruoyi
*/
export default {
bind(el) {
const dragDom = el.querySelector('.el-dialog');
const lineEl = document.createElement('div');
lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
lineEl.addEventListener('mousedown',
function (e) {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - el.offsetLeft;
// 当前宽度
const curWidth = dragDom.offsetWidth;
document.onmousemove = function (e) {
e.preventDefault(); // 移动时禁用默认事件
// 通过事件委托,计算移动的距离
const l = e.clientX - disX;
dragDom.style.width = `${curWidth + l}px`;
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
}, false);
dragDom.appendChild(lineEl);
}
}

View File

@@ -1,77 +0,0 @@
export default {
bind(el, binding, vnode) {
const dialogHeaderEl = el.querySelector('.el-dialog__header')
const dragDom = el.querySelector('.el-dialog')
dialogHeaderEl.style.cssText += ';cursor:move;'
dragDom.style.cssText += ';top:0px;'
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const getStyle = (function() {
if (window.document.currentStyle) {
return (dom, attr) => dom.currentStyle[attr]
} else {
return (dom, attr) => getComputedStyle(dom, false)[attr]
}
})()
dialogHeaderEl.onmousedown = (e) => {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - dialogHeaderEl.offsetLeft
const disY = e.clientY - dialogHeaderEl.offsetTop
const dragDomWidth = dragDom.offsetWidth
const dragDomHeight = dragDom.offsetHeight
const screenWidth = document.body.clientWidth
const screenHeight = document.body.clientHeight
const minDragDomLeft = dragDom.offsetLeft
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth
const minDragDomTop = dragDom.offsetTop
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight
// 获取到的值带px 正则匹配替换
let styL = getStyle(dragDom, 'left')
let styT = getStyle(dragDom, 'top')
if (styL.includes('%')) {
styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100)
styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100)
} else {
styL = +styL.replace(/\px/g, '')
styT = +styT.replace(/\px/g, '')
}
document.onmousemove = function(e) {
// 通过事件委托,计算移动的距离
let left = e.clientX - disX
let top = e.clientY - disY
// 边界处理
if (-(left) > minDragDomLeft) {
left = -minDragDomLeft
} else if (left > maxDragDomLeft) {
left = maxDragDomLeft
}
if (-(top) > minDragDomTop) {
top = -minDragDomTop
} else if (top > maxDragDomTop) {
top = maxDragDomTop
}
// 移动当前元素
dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`
// emit onDrag event
vnode.child.$emit('dragDialog')
}
document.onmouseup = function(e) {
document.onmousemove = null
document.onmouseup = null
}
}
}
}

View File

@@ -1,13 +0,0 @@
import drag from './drag'
const install = function(Vue) {
Vue.directive('el-drag-dialog', drag)
}
if (window.Vue) {
window['el-drag-dialog'] = drag
Vue.use(install); // eslint-disable-line
}
drag.install = install
export default drag

View File

@@ -1,41 +0,0 @@
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event'
/**
* How to use
* <el-table height="100px" v-el-height-adaptive-table="{bottomOffset: 30}">...</el-table>
* el-table height is must be set
* bottomOffset: 30(default) // The height of the table from the bottom of the page.
*/
const doResize = (el, binding, vnode) => {
const { componentInstance: $table } = vnode
const { value } = binding
if (!$table.height) {
throw new Error(`el-$table must set the height. Such as height='100px'`)
}
const bottomOffset = (value && value.bottomOffset) || 30
if (!$table) return
const height = window.innerHeight - el.getBoundingClientRect().top - bottomOffset
$table.layout.setHeight(height)
$table.doLayout()
}
export default {
bind(el, binding, vnode) {
el.resizeListener = () => {
doResize(el, binding, vnode)
}
// parameter 1 is must be "Element" type
addResizeListener(window.document.body, el.resizeListener)
},
inserted(el, binding, vnode) {
doResize(el, binding, vnode)
},
unbind(el) {
removeResizeListener(window.document.body, el.resizeListener)
}
}

View File

@@ -1,13 +0,0 @@
import adaptive from './adaptive'
const install = function(Vue) {
Vue.directive('el-height-adaptive-table', adaptive)
}
if (window.Vue) {
window['el-height-adaptive-table'] = adaptive
Vue.use(install); // eslint-disable-line
}
adaptive.install = install
export default adaptive

View File

@@ -0,0 +1,33 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import hasRole from './permission/hasRole'
import hasPermi from './permission/hasPermi'
import dialogDrag from './dialog/drag'
import dialogDragWidth from './dialog/dragWidth'
import dialogDragHeight from './dialog/dragHeight'
import copy from './copy/copy'
const install = function(Vue) {
Vue.directive('hasRole', hasRole)
Vue.directive('hasPermi', hasPermi)
Vue.directive('dialogDrag', dialogDrag)
Vue.directive('dialogDragWidth', dialogDragWidth)
Vue.directive('dialogDragHeight', dialogDragHeight)
Vue.directive('copy', copy)
}
if (window.Vue) {
window['hasRole'] = hasRole
window['hasPermi'] = hasPermi
Vue.use(install); // eslint-disable-line
}
export default install

View File

@@ -0,0 +1,41 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import store from '@/store'
export default {
inserted(el, binding, vnode) {
// 当被绑定的元素插入到 DOM 中时……
const { value } = binding
const all_permission = "*:*:*";
//超管标识
const permissions = store.getters && store.getters.permissions
//从getters中取出从接口请求到的权限标识数组
if (value && value instanceof Array && value.length > 0) {
//value为指令的绑定值并且要求是一个非空数组
const permissionFlag = value
const hasPermissions = permissions.some(permission => {
//some() 方法用于检测数组中的元素是否满足指定条件(函数提供)
//如果是超管或者其他管理员有对应的权限标识
return all_permission === permission || permissionFlag.includes(permission)
//检测数组 permissionFlag 是否包含 permission
})
if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el)
//否则就删除该节点,体现在页面上就是没有按钮对应的权限标识就不显示该按钮
}
} else {
throw new Error(`请设置操作权限标签值`)
//页面上使用v-hasPermi没有传值的情况下给的提示
}
}
}

View File

@@ -0,0 +1,33 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import store from '@/store'
export default {
inserted(el, binding, vnode) {
const { value } = binding
const super_admin = "admin";
const roles = store.state.user.name
if (value && value instanceof Array && value.length > 0) {
const roleFlag = value
const hasRole = roles.some(role => {
return super_admin === role || roleFlag.includes(role)
})
if (!hasRole) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`请设置角色权限标签值"`)
}
}
}

View File

@@ -1,13 +0,0 @@
import permission from './permission'
const install = function(Vue) {
Vue.directive('permission', permission)
}
if (window.Vue) {
window['permission'] = permission
Vue.use(install); // eslint-disable-line
}
permission.install = install
export default permission

View File

@@ -1,22 +0,0 @@
import store from '@/store'
export default {
inserted(el, binding, vnode) {
const { value } = binding
const roles = store.getters && store.getters.roles
if (value && value instanceof Array && value.length > 0) {
const permissionRoles = value
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`need roles! Like v-permission="['admin','editor']"`)
}
}
}

View File

@@ -1,91 +0,0 @@
const vueSticky = {}
let listenAction
vueSticky.install = Vue => {
Vue.directive('sticky', {
inserted(el, binding) {
const params = binding.value || {}
const stickyTop = params.stickyTop || 0
const zIndex = params.zIndex || 1000
const elStyle = el.style
elStyle.position = '-webkit-sticky'
elStyle.position = 'sticky'
// if the browser support css stickyCurrently Safari, Firefox and Chrome Canary
// if (~elStyle.position.indexOf('sticky')) {
// elStyle.top = `${stickyTop}px`;
// elStyle.zIndex = zIndex;
// return
// }
const elHeight = el.getBoundingClientRect().height
const elWidth = el.getBoundingClientRect().width
elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`
const parentElm = el.parentNode || document.documentElement
const placeholder = document.createElement('div')
placeholder.style.display = 'none'
placeholder.style.width = `${elWidth}px`
placeholder.style.height = `${elHeight}px`
parentElm.insertBefore(placeholder, el)
let active = false
const getScroll = (target, top) => {
const prop = top ? 'pageYOffset' : 'pageXOffset'
const method = top ? 'scrollTop' : 'scrollLeft'
let ret = target[prop]
if (typeof ret !== 'number') {
ret = window.document.documentElement[method]
}
return ret
}
const sticky = () => {
if (active) {
return
}
if (!elStyle.height) {
elStyle.height = `${el.offsetHeight}px`
}
elStyle.position = 'fixed'
elStyle.width = `${elWidth}px`
placeholder.style.display = 'inline-block'
active = true
}
const reset = () => {
if (!active) {
return
}
elStyle.position = ''
placeholder.style.display = 'none'
active = false
}
const check = () => {
const scrollTop = getScroll(window, true)
const offsetTop = el.getBoundingClientRect().top
if (offsetTop < stickyTop) {
sticky()
} else {
if (scrollTop < elHeight + stickyTop) {
reset()
}
}
}
listenAction = () => {
check()
}
window.addEventListener('scroll', listenAction)
},
unbind() {
window.removeEventListener('scroll', listenAction)
}
})
}
export default vueSticky

View File

@@ -1,13 +0,0 @@
import waves from './waves'
const install = function(Vue) {
Vue.directive('waves', waves)
}
if (window.Vue) {
window.waves = waves
Vue.use(install); // eslint-disable-line
}
waves.install = install
export default waves

View File

@@ -1,26 +0,0 @@
.waves-ripple {
position: absolute;
border-radius: 100%;
background-color: rgba(0, 0, 0, 0.15);
background-clip: padding-box;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
opacity: 1;
}
.waves-ripple.z-active {
opacity: 0;
-webkit-transform: scale(2);
-ms-transform: scale(2);
transform: scale(2);
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
}

View File

@@ -1,72 +0,0 @@
import './waves.css'
const context = '@@wavesContext'
function handleClick(el, binding) {
function handle(e) {
const customOpts = Object.assign({}, binding.value)
const opts = Object.assign({
ele: el, // 波纹作用元素
type: 'hit', // hit 点击位置扩散 center中心点扩展
color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
},
customOpts
)
const target = opts.ele
if (target) {
target.style.position = 'relative'
target.style.overflow = 'hidden'
const rect = target.getBoundingClientRect()
let ripple = target.querySelector('.waves-ripple')
if (!ripple) {
ripple = document.createElement('span')
ripple.className = 'waves-ripple'
ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'
target.appendChild(ripple)
} else {
ripple.className = 'waves-ripple'
}
switch (opts.type) {
case 'center':
ripple.style.top = rect.height / 2 - ripple.offsetHeight / 2 + 'px'
ripple.style.left = rect.width / 2 - ripple.offsetWidth / 2 + 'px'
break
default:
ripple.style.top =
(e.pageY - rect.top - ripple.offsetHeight / 2 - document.documentElement.scrollTop ||
document.body.scrollTop) + 'px'
ripple.style.left =
(e.pageX - rect.left - ripple.offsetWidth / 2 - document.documentElement.scrollLeft ||
document.body.scrollLeft) + 'px'
}
ripple.style.backgroundColor = opts.color
ripple.className = 'waves-ripple z-active'
return false
}
}
if (!el[context]) {
el[context] = {
removeHandle: handle
}
} else {
el[context].removeHandle = handle
}
return handle
}
export default {
bind(el, binding) {
el.addEventListener('click', handleClick(el, binding), false)
},
update(el, binding) {
el.removeEventListener('click', el[context].removeHandle, false)
el.addEventListener('click', handleClick(el, binding), false)
},
unbind(el) {
el.removeEventListener('click', el[context].removeHandle, false)
el[context] = null
delete el[context]
}
}

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import * as constants from '@/utils/constants.js'
import { formatDates } from '@/utils/index';

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
// import parseTime, formatTime and set to filter
export { parseTime, formatTime } from '@/utils'

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
//订单过滤器
/**

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
//会员过滤器
/**

View File

@@ -1,3 +1,13 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
//小程序 微信过滤器
import Cookies from 'js-cookie'
/**

View File

@@ -27,13 +27,13 @@ export default {
{
title: '社区',
key: '2',
href: 'http://bbs.crmeb.net',
href: 'https://q.crmeb.net/?categoryId=122&sequence=0',
blankTarget: true
},
{
title: '文档',
key: '3',
href: 'https://help.crmeb.net',
href: 'https://help.crmeb.net/crmeb_java/1748037',
blankTarget: true
}
],
@@ -70,7 +70,7 @@ export default {
}
.fixed-header+.app-main {
padding-top: 95px;
padding-top: 50px;
}
.hasTagsView {
@@ -82,7 +82,7 @@ export default {
}
.fixed-header+.app-main {
padding-top: 95px;
padding-top: 80px;
}
}
.el-popup-parent--hidden {

View File

@@ -1,44 +1,31 @@
<template>
<div class="navbar">
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
<hamburger
id="hamburger-container"
:is-active="sidebar.opened"
class="hamburger-container"
@toggleClick="toggleSideBar"
/>
<breadcrumb id="breadcrumb-container" class="breadcrumb-container"/>
<div class="right-menu">
<template v-if="device!=='mobile'">
<template v-if="device !== 'mobile'">
<search id="header-search" class="right-menu-item" />
<error-log class="errLog-container right-menu-item hover-effect" />
<screenfull id="screenfull" class="right-menu-item hover-effect" />
</template>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<el-dropdown
class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper">
{{JavaInfo.account}}<i class="el-icon-arrow-down el-icon--right"></i>
<!--<img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">-->
<!--<i class="el-icon-caret-bottom" />-->
{{ JavaInfo.realName}}<i class="el-icon-arrow-down el-icon--right"></i>
</div>
<el-dropdown-menu slot="dropdown">
<!-- <router-link to="/profile/index">-->
<!-- <el-dropdown-item>Profile</el-dropdown-item>-->
<!-- </router-link>-->
<router-link to="/">
<el-dropdown-item>主页</el-dropdown-item>
</router-link>
<router-link :to=" { path: '/maintain/user' } " v-if="!isPhone">
<router-link :to="{ path: '/maintain/user' }" v-if="!isPhone">
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link>
<!--<el-dropdown-item @click.native="onUnbundling">解绑账号</el-dropdown-item>-->
<!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">-->
<!-- <el-dropdown-item>Github</el-dropdown-item>-->
<!-- </a>-->
<!-- <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">-->
<!-- <el-dropdown-item>Docs</el-dropdown-item>-->
<!-- </a>-->
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">退出</span>
<el-dropdown-item @click.native="logout">
<span>退出</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
@@ -47,52 +34,51 @@
</template>
<script>
import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger'
import ErrorLog from '@/components/ErrorLog'
import Screenfull from '@/components/Screenfull'
import Search from '@/components/HeaderSearch'
import { unbindApi } from '@/api/wxApi'
import Cookies from 'js-cookie'
import { mapGetters } from "vuex";
import Breadcrumb from "@/components/Breadcrumb";
import Hamburger from "@/components/Hamburger";
import Screenfull from "@/components/Screenfull";
import Search from "@/components/HeaderSearch";
import { unbindApi } from "@/api/wxApi";
import Cookies from "js-cookie";
export default {
components: {
Breadcrumb,
Hamburger,
ErrorLog,
Screenfull,
Search
Search,
},
data() {
return {
isPhone: this.$wechat.isPhone(),
JavaInfo: JSON.parse(Cookies.get('JavaInfo')),
JavaInfo: JSON.parse(Cookies.get("JavaInfo")),
};
},
watch: {
show(value) {
if (value && !this.clickNotClose) {
this.addEventClick()
}
if (value) {
addClass(document.body, 'showRightPanel')
} else {
removeClass(document.body, 'showRightPanel')
}
}
},
computed: {
...mapGetters([
'sidebar',
'avatar',
'device'
])
...mapGetters(["sidebar", "avatar", "device"]),
},
methods: {
onUnbundling() {
this.$modalSure('解绑微信吗').then(() => {
unbindApi().then(() => {
this.$message.success('解绑成功')
})
})
},
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
this.$store.dispatch("app/toggleSideBar");
},
async logout() {
await this.$store.dispatch('user/logout')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
}
}
}
await this.$store.dispatch("user/logout");
this.$router.push(`/login?redirect=${this.$route.fullPath}`);
},
},
};
</script>
<style lang="scss" scoped>
@@ -101,18 +87,18 @@ export default {
overflow: hidden;
position: relative;
background: #fff;
box-shadow: 0 1px 4px rgba(0,21,41,.08);
// box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container {
line-height: 46px;
height: 100%;
float: left;
cursor: pointer;
transition: background .3s;
-webkit-tap-highlight-color:transparent;
transition: background 0.3s;
-webkit-tap-highlight-color: transparent;
&:hover {
background: rgba(0, 0, 0, .025)
background: rgba(0, 0, 0, 0.025);
}
}
@@ -120,6 +106,11 @@ export default {
float: left;
}
.topmenu-container {
position: absolute;
left: 50px;
}
.errLog-container {
display: inline-block;
vertical-align: top;
@@ -144,10 +135,10 @@ export default {
&.hover-effect {
cursor: pointer;
transition: background .3s;
transition: background 0.3s;
&:hover {
background: rgba(0, 0, 0, .025)
background: rgba(0, 0, 0, 0.025);
}
}
}

View File

@@ -1,28 +1,35 @@
<template>
<div class="drawer-container">
<div>
<h3 class="drawer-title">Page style setting</h3>
<h3 class="drawer-title">主题风格设置</h3>
<div class="drawer-item">
<span>Theme Color</span>
<span>主题颜色</span>
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
<div class="drawer-item" v-if="topNav">
<span>开启 Icon</span>
<el-switch v-model="navIcon" class="drawer-switch" />
</div>
<div class="drawer-item">
<span>Open Tags-View</span>
<span>开启 Tags-Views</span>
<el-switch v-model="tagsView" class="drawer-switch" />
</div>
<div class="drawer-item">
<span>Fixed Header</span>
<span>固定 Header</span>
<el-switch v-model="fixedHeader" class="drawer-switch" />
</div>
<div class="drawer-item">
<span>Sidebar Logo</span>
<span>显示 Logo</span>
<el-switch v-model="sidebarLogo" class="drawer-switch" />
</div>
<el-divider/>
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button>
<el-button size="small" plain icon="el-icon-refresh" @click="resetSetting">重置配置</el-button>
</div>
</div>
</div>
</template>
@@ -33,9 +40,17 @@ import ThemePicker from '@/components/ThemePicker'
export default {
components: { ThemePicker },
data() {
return {}
return {
sideTheme: this.$store.state.settings.sideTheme,
routers:this.$store.state.permission.routes,
}
},
computed: {
theme:{
get(){
return this.$store.state.settings.theme
}
},
fixedHeader: {
get() {
return this.$store.state.settings.fixedHeader
@@ -76,12 +91,44 @@ export default {
key: 'theme',
value: val
})
},
handleTheme(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'sideTheme',
value: val
})
this.sideTheme = val;
},
saveSetting() {
this.$modal.loading("正在保存到本地,请稍候...");
//将设置写入缓存
this.$cache.local.setJSON(
'layout-setting',{
"topNav":this.topNav,
"tagsView":this.tagsView,
"fixedHeader":this.fixedHeader,
"sidebarLogo":this.sidebarLogo,
"dynamicTitle":this.dynamicTitle,
"sideTheme":this.sideTheme,
"theme":this.theme,
"navIcon":this.navIcon
}
);
setTimeout(this.$modal.closeLoading(), 1000)
},
resetSetting() {
this.$modal.loading("正在清除设置缓存并刷新,请稍候...");
this.$cache.local.remove("layout-setting")
setTimeout("window.location.reload()", 1000)
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .el-switch{
width: 40px;
}
.drawer-container {
padding: 24px;
font-size: 14px;
@@ -104,5 +151,38 @@ export default {
.drawer-switch {
float: right
}
.setting-drawer-block-checbox {
display: flex;
justify-content: flex-start;
align-items: center;
margin-top: 10px;
margin-bottom: 20px;
.setting-drawer-block-checbox-item {
position: relative;
margin-right: 16px;
border-radius: 2px;
cursor: pointer;
img {
width: 48px;
height: 48px;
}
.setting-drawer-block-checbox-selectIcon {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
padding-top: 15px;
padding-left: 24px;
color: #1890ff;
font-weight: 700;
font-size: 14px;
}
}
}
}
</style>

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