import Vue from 'vue'
import utils from '@/hotent-ui-util.js'
import FormMath from '@/math.js'
import dialog from '@/api/dialogApi.js'
import CustomQuery from '@/components/eipControl/bus/CustomQuery.js'
import _ from 'lodash'
import req from '@/request.js'
import app from '@/main.js'
// 表单tr中根据隐藏字段动态合并单元格的指令
Vue.directive('pinyin', {
// 指令的定义
componentUpdated: function(el, binding, vnode) {
let context = vnode.context
// 防抖
let debounceGetPinyin = _.debounce(newVal => {
// disabled 或者 readonly 时 不需要请求
if (el.__vue__.disabled || el.__vue__.readonly) return
req
.request({
url: `${window.context.uc}/base/tools/v1/getPinyin`,
method: 'GET',
params: {chinese: newVal, type: `${binding.modifiers.full ? 1 : 0}`}
})
.then(res => {
if (res.data.state) {
let modelExp = vnode.data.model.expression.replace(
/\[\w+.?\$\w+\]/g,
'[' + binding.arg + ']'
)
utils.setValueByPath(context, modelExp, res.data.value)
app.$nextTick(() => {
app.$validator.validate()
})
}
})
.finally(() => {})
}, 300)
if (binding.value && binding.value != binding.oldValue) {
debounceGetPinyin(binding.value)
}
// context.$watch(watchExp(), function (newVal, oldVal) {
// if (newVal && newVal != oldVal) {
// debounceGetPinyin(newVal);
// }
// }, {
// deep: true,
// immediate: false
// });
}
})
Vue.directive('permit', {
componentUpdated: function(el, binding) {
if (el.tagName !== 'TR') {
throw 'v-permit指令只能用在tr元素上.'
}
if (!binding.value || binding.value.constructor !== Number) {
throw 'v-permit指令的值只能是大于0的数字.'
}
el.removeAttribute('hidden')
// tr中没有子元素时,删除tr自身
if (el.cells.length == 0) {
el.setAttribute('hidden', 'hidden')
} else if (el.cells.length < binding.value) {
let colspan = binding.value - el.cells.length + 1
// 设置colspan实现单元格合并
el.cells[el.cells.length - 1].setAttribute('colspan', colspan)
} else if (el.cells.length === binding.value) {
for (var i = 0, c; (c = el.cells[i++]); ) {
c.removeAttribute('colspan')
}
}
}
})
// 表单指令,会在表单的vue实例上添加一个map,用以存放数学运算的表达式
Vue.directive('form', {
bind: function(el, binding, vnode) {
const inst = vnode.context
if (inst && !inst.hasOwnProperty('watchMap')) {
inst['watchMap'] = new Map()
}
}
})
// 判断输入框是否作为计算字段,是则添加监听
Vue.directive('express', {
componentUpdated: function(el, binding, vnode) {
const inst = vnode.context
if (!inst.$vnode.data.model) {
return
}
const elAttr = inst.$vnode.componentOptions.propsData.modelExpression
if (elAttr && !inst._expressInit) {
inst._expressInit = true
// 子表每一行数据作用域所在的dom元素
let {subScopeEl} = utils.getSubScopeElAndIndex(el)
let subname = null
let aliasElAttr = null
// 子表数据,需要找到配置了data-subname的元素
if (subScopeEl) {
subname = subScopeEl.dataset['subname']
if (!subname) {
throw '无法获取到当前子表前缀'
}
const elAttrAry = elAttr.split('.'),
elAttrArySize = elAttrAry.length
if (elAttrArySize < 1) {
throw `子表中的数据绑定表达式${elAttr}错误`
}
aliasElAttr = `${subname}.${elAttrAry[elAttrArySize - 1]}`
}
const p = utils.getOnlineFormInstance(inst)
if (
p.watchMap &&
(p.watchMap.has(elAttr) || p.watchMap.has(aliasElAttr))
) {
if (
!inst._watchers.some(m => {
return m.expression === 'inputVal'
})
) {
inst.$watch(
'inputVal',
function(newVal, oldVal, farewell) {
if (newVal !== oldVal) {
const expList =
p.watchMap.get(elAttr) || p.watchMap.get(aliasElAttr)
expList.forEach(item => {
let result = 0
const t = item.target
// 当在子表单行中时,而且不是对子表进行列运算时,判定为子表当前行内运算
if (subScopeEl && !/.*?\[\{.*?\}\].*?/.test(item.exp)) {
// 组件销毁时,不再计算子表单行的公式
if (farewell) {
return
}
const index = subScopeEl.dataset['index']
if (index === undefined) {
throw '获取不到当前子表行的索引,无法完成计算.'
}
result = FormMath.calcSubExpValue(
item.exp,
p,
subname,
index
)
p.$emit(t, {result, index})
} else {
result = FormMath.calcExpValue(item.exp, p)
p.$emit(t, {result})
}
})
}
},
{immediate: true}
)
}
}
}
}
})
// 自定义对话框 v-auth-set-event
Vue.directive('auth-set-event', {
bind: function(el, bindings, vnode) {
const htAuthSetEvent = el.getAttribute('attr')
if (!htAuthSetEvent) return
var defaultPermissionList = []
dialog.getPermissionList(result => {
defaultPermissionList = result
})
/**
* 设置设置权限。
* ownerNameJson 格式。
* [{type:"everyone",title:"所有人"},{type:"user",title:"用户",id:"1,2",name:"ray,tom"}]
*/
const setAuth = function() {
var conf = {
right: ownerNameJson,
permissionList: defaultPermissionList
}
//授权选择器
vnode.child.AuthSettingShow(conf)
}
var ownerNameJson = []
var initData = bindings.value
if (initData) {
ownerNameJson = JSON.parse(initData)
// showLable(ownerNameJson);
}
//对话框初始化监听
el.childNodes[2].onclick = function() {
setAuth()
}
}
})
Vue.directive('parseTemplete', {
bind: function(el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' +
s(binding.name) +
'
' +
'value: ' +
s(binding.value) +
'
' +
'expression: ' +
s(binding.expression) +
'
' +
'argument: ' +
s(binding.arg) +
'
' +
'modifiers: ' +
s(binding.modifiers) +
'
' +
'vnode keys: ' +
Object.keys(vnode).join(', ')
}
})
Vue.directive('alsCharts', {
inserted(el, binding, vnode) {
const inst = binding.context
function init(data) {
if (
!(
data.value &&
data.value !== true &&
data.value.constructor == Array &&
data.value[0].legend
)
) {
return
}
var options = data.value[0]
var height = getDivHeight(el) - 35
var wrap = $('
').css({
width: '100%',
height: height
})
$(el).css({
display: 'block',
width: '100%',
height: height
})
// const echarts = require('echarts');
// var myChart = echarts.init(el);
// inst.$root.$on("resize", () => {
// myChart.resize();//监测图表自适应
// });
var option = {
title: {
text: options.name,
subtext: options.subtext,
top: 12
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
calculable: true,
legend: {
x: 'right',
data: options.legend
},
toolbox: {
show: true,
orient: 'vertical',
y: 'center',
right: 20,
itemGap: 13,
feature: {
mark: {show: true},
dataView: {show: true, readOnly: false},
magicType: {show: true, type: ['line', 'bar', 'stack', 'tiled']},
restore: {show: true},
saveAsImage: {show: true},
dataZoom: {
yAxisIndex: 'none'
},
dataView: {
show: true,
readOnly: true,
optionToContent: function(opt) {
//console.info(opt);
var axisData = opt.xAxis[0].data
var series = opt.series
var tdHeaders = ' | ' //表头
series.forEach(function(item) {
tdHeaders +=
'' +
item.name +
' | ' //组装表头
})
var table =
'' +
tdHeaders +
'
'
var tdBodys = '' //数据
var colors = ['#FFFFFF', '#F5F5F5']
for (let i = 0, l = axisData.length; i < l; i++) {
for (let j = 0; j < series.length; j++) {
tdBodys += '' + series[j].data[i] + ' | ' //组装表数据
}
var curColor = colors[i % 2]
table +=
'' +
axisData[i] +
' | ' +
tdBodys +
'
'
tdBodys = ''
}
table += '
'
return table
}
}
}
},
calculable: true,
grid: {
y: 80,
y2: 40,
x2: 40
},
xAxis: [
{
type: 'category',
data: options.xAxis
}
],
yAxis: [
{
type: 'value'
}
],
//x轴数据区域缩放组件--暂时不添加
/*dataZoom: [
{
type: 'slider',
show: true,
xAxisIndex: [0],
start: 1,
end: 35
},
{
type: 'inside',
xAxisIndex: [0],
start: 1,
end: 35
},
],*/
series: options.series
}
// myChart.setOption(option, true);
}
//获取当前栏目的高度
function getDivHeight(el) {
if (el) {
var pHeight = $(el)
.parent()
.height()
if (pHeight < 1) {
return getDivHeight($(el).parent())
}
} else {
return 340
}
return pHeight
}
init(binding)
}
})
Vue.directive('opinion', {
bind: function(el, binding, vnode) {
if (binding.value) {
while (binding.value.indexOf('\n') != -1) {
binding.value = binding.value.replace('\n', '
')
}
el.innerHTML = binding.value
}
}
})
Vue.directive('iframetrigger', {
bind: function(el, binding, vnode) {
el.onload = function() {
$('body').trigger('formLoaded')
}
$('body').bind('formLoaded', function(e) {
var frm = $('#frmFrame')[0]
window.addEventListener('message', function(e) {
if (e.data && e.data.constructor == Object && e.data.type == 'height') {
frm.style.visibility = 'hidden'
// 提前还原高度
frm.setAttribute('height', 'auto')
setTimeout(function() {
frm.setAttribute('height', e.data.height)
frm.style.visibility = 'visible'
$(frm).trigger('mouseover')
}, 0)
}
})
})
}
})
Vue.directive('methodauth', {
bind: function(el, binding, vnode) {
let allMethod = window.sessionStorage.allMethod
let methodAuth = window.sessionStorage.methodAuth
let elAuth = binding.expression
let allMethodArray = allMethod.split(',')
let methodAuthArray = methodAuth.split(',')
// 无权限则隐藏按钮
if (
$.inArray(elAuth, methodAuthArray) == -1 &&
$.inArray(elAuth, allMethodArray)
) {
$(el).css('display', 'none')
}
}
})
// 注册全局公式计算组件
Vue.directive('formula', {
bind(el, binding, vnode) {
let propsData = vnode.context.$options.propsData
//初始化的时候,如果没有值,则用公式的计算结果来赋值给当前字段
let oldVal = utils.getValueByPath(propsData, binding.value.bindPath)
if (propsData && !oldVal) {
utils.setValueByPath(
propsData,
binding.value.bindPath,
binding.value.value
)
vnode.context.$forceUpdate()
}
},
update(el, binding, vnode, oldVnode) {
if (binding.oldValue.value instanceof Date) {
if (binding.oldValue.value.getTime() !== binding.value.value.getTime()) {
utils.setValueByPath(
vnode.context.$options.propsData,
binding.value.bindPath,
binding.value.value
)
vnode.context.$forceUpdate()
}
} else {
if (binding.oldValue.value != binding.value.value) {
utils.setValueByPath(
vnode.context.$options.propsData,
binding.value.bindPath,
binding.value.value
)
vnode.context.$forceUpdate()
}
}
}
})
Vue.directive('mapping', {
update(el, binding, vnode, oldVnode) {
if (binding.oldValue !== binding.value) {
Vue.set(el.__vue__, 'inputVal', binding.value)
}
}
})
Vue.directive('dynamic-options', {
bind(el, binding, vnode) {
let exp = null
if (binding.expression) {
exp = utils.parseToJson(binding.expression)
}
const inst = vnode.context
if (inst) {
// 上一次动态选项查询条件
inst.preDynamicLoadParams = null
inst.$on('dynamic-options:load', (alias, params) => {
params = params || {}
// 是否执行查询
let doLoad = true
if (exp && exp.cache) {
// 相比上一次,查询参数是否有变化
const changed = !utils.objectEquals(inst.preDynamicLoadParams, params)
if (changed) {
doLoad = true
inst.preDynamicLoadParams = params
} else {
doLoad = false
}
}
doLoad &&
CustomQuery.load(alias, params).then(data => {
inst.$emit('dynamic-options:update', alias, data)
})
})
}
}
})
//用于上级值变化后,下级内容需要清空
Vue.directive('watch-parent', {
update(el, binding, vnode) {
if (binding.value && binding.value.pid) {
for (var key in binding.value.pid) {
const inst = vnode.context
const instParent = utils.getOnlineFormInstance(inst)
instParent.$watch(
() => {
return utils.getValueByPath(
instParent,
binding.value.pid[key],
binding.value.index
)
},
function(newVal, oldVal, farewell) {
if (newVal !== oldVal) {
inst.inputVal = ''
}
}
)
}
}
}
})
Vue.directive('related-query', {
bind(el, binding, vnode) {
const inst = vnode.context
let exp = null
if (binding.expression) {
exp = utils.parseToJson(binding.expression)
}
if (inst) {
// 上一次关联查询条件(一个组件可以绑定多个关联查询,)
inst.preRelatedQueryParams = {}
inst.$on('related-query:load', (alias, params, resultBind) => {
params = params || {}
// 是否执行查询
let doLoad = true
if (exp && exp.cache) {
// 相比上一次,查询参数是否有变化
const changed = !utils.objectEquals(
inst.preRelatedQueryParams[alias],
params
)
if (changed) {
doLoad = true
inst.preRelatedQueryParams[alias] = params
} else {
doLoad = false
}
}
doLoad &&
CustomQuery.load(alias, params).then(data => {
if (
data &&
data.constructor == Array &&
data.length > 0 &&
resultBind &&
resultBind.constructor == Object
) {
// 获取当前控件是否在子表某行中
let {index} = utils.getSubScopeElAndIndex(el)
const pInst = utils.getOnlineFormInstance(inst)
// 关联查询值回绑时,默认获取返回的第一条记录
const singleData = data[0]
Object.keys(resultBind).forEach(k => {
const path = resultBind[k]
// 主表
if (index == null) {
utils.setValueByPath(pInst, path, singleData[k])
}
// 子表
else {
utils.setValueByPath(pInst, path, singleData[k], index)
}
})
}
})
})
}
}
})
//表格横向拖拽
Vue.directive('tableDrag', {
inserted: function(el) {
const currentElement =
el.getElementsByClassName('el-table__body-wrapper')[0] || el
const tagNames = ['span', 'input', 'textarea', 'aside']
if (currentElement) {
currentElement.onmousedown = function(event) {
const currentTagNames = event.target.tagName.toLowerCase()
if (tagNames.includes(currentTagNames)) return
currentElement.style.cursor = 'grab'
let gapX = event.clientX
let startX = el.scrollLeft
document.onmousemove = function(e) {
let x = e.clientX - gapX
currentElement.scrollLeft = startX - x
return false
}
document.onmouseup = function(e) {
document.onmousemove = null
document.onmouseup = null
}
}
}
}
})
//用于控制子表或孙表单行permission
Vue.directive('permission-line', {
bind(el, binding, vnode) {
if (binding.value) {
const inst = vnode.context
let idxObj = utils.getSubScopeElAndIndex(el)
let paths = binding.value.split('_')
let boType = paths[0]
let idStr = binding.value + '_' + idxObj.index
//孙表时,获取孙表所属子表序号
if (boType == 'sun' && idxObj.subScopeEl) {
const subIdxObj = utils.getSubScopeElAndIndex(
idxObj.subScopeEl.parentElement
)
idStr = binding.value + '_' + subIdxObj.index + '_' + idxObj.index
}
if (
inst.permission &&
inst.permission['subFields'] &&
inst.permission['subFields'][idStr]
) {
setTimeout(function() {
if (el.__vue__) {
el.__vue__.permission_sub = inst.permission['subFields'][idStr]
el.__vue__.sub_work = true
}
}, 0)
}
}
},
update(el, binding, vnode) {
if (binding.value) {
const inst = vnode.context
let idxObj = utils.getSubScopeElAndIndex(el)
let paths = binding.value.split('_')
let boType = paths[0]
let idStr = binding.value + '_' + idxObj.index
//孙表时,获取孙表所属子表序号
if (boType == 'sun' && idxObj.subScopeEl) {
const subIdxObj = utils.getSubScopeElAndIndex(
idxObj.subScopeEl.parentElement
)
idStr = binding.value + '_' + subIdxObj.index + '_' + idxObj.index
}
if (
inst.permission &&
inst.permission['subFields'] &&
inst.permission['subFields'][idStr]
) {
setTimeout(function() {
if (el.__vue__) {
el.__vue__.permission_sub = inst.permission['subFields'][idStr]
}
}, 0)
}
}
}
})
//用于控制子表或孙表单行permission lable标签
Vue.directive('permission-line-lable', {
bind(el, binding, vnode) {
if (binding.value) {
const inst = vnode.context
let idxObj = utils.getSubScopeElAndIndex(el)
let paths = binding.value.split('_')
let boType = paths[0]
let idStr = binding.value + '_' + idxObj.index
//孙表时,获取孙表所属子表序号
if (boType == 'sun' && idxObj.subScopeEl) {
const subIdxObj = utils.getSubScopeElAndIndex(
idxObj.subScopeEl.parentElement
)
idStr = binding.value + '_' + subIdxObj.index + '_' + idxObj.index
}
if (
inst.permission &&
inst.permission['subFields'] &&
inst.permission['subFields'][idStr]
) {
setTimeout(function() {
el.parentElement.hidden =
inst.permission['subFields'][idStr] == 'n' ? true : false
}, 0)
}
}
},
update(el, binding, vnode) {
if (binding.value) {
const inst = vnode.context
let idxObj = utils.getSubScopeElAndIndex(el)
let paths = binding.value.split('_')
let boType = paths[0]
let idStr = binding.value + '_' + idxObj.index
//孙表时,获取孙表所属子表序号
if (boType == 'sun' && idxObj.subScopeEl) {
const subIdxObj = utils.getSubScopeElAndIndex(
idxObj.subScopeEl.parentElement
)
idStr = binding.value + '_' + subIdxObj.index + '_' + idxObj.index
}
if (
inst.permission &&
inst.permission['subFields'] &&
inst.permission['subFields'][idStr]
) {
setTimeout(function() {
el.parentElement.hidden =
inst.permission['subFields'][idStr] == 'n' ? true : false
}, 0)
}
}
}
})
// 用于点击指定区域外执行某功能
Vue.directive('click-outside', {
bind(el, bindings, vnode) {
el.handler = function(e) {
if (!el.contains(e.target)) {
let method = bindings.expression
vnode.context[method]()
}
}
document.addEventListener('click', el.handler)
},
unbind(el) {
// 可用于解除事件绑定
document.removeEventListener('click', el.handler)
}
})
// 指令定义
Vue.directive('charge', {
bind(el, binding, vnode) {
const vm = vnode.context
const toggleDisplay = value => {
el.style.display = value === 1 ? '' : 'none'
}
toggleDisplay(vm.$store.state.user.currentUserDetail?.user.isCharge || 0)
// 保存函数,以便在指令解绑时调用
el.__vueUnWatch__ = vm.$store.watch(
state => state.user.currentUserDetail?.user.isCharge,
isCharge => toggleDisplay(isCharge)
)
},
unbind(el) {
// 清理监听器,防止内存泄漏
if (el.__vueUnWatch__) {
el.__vueUnWatch__()
delete el.__vueUnWatch__
}
}
})
var directive = {}
export default directive