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',
scale:true
}
],
//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)
}
});
var directive = {};
export default directive;