Commit dfcb83c1 authored by smallwei's avatar smallwei

搞定

parent c0221ff6
......@@ -10,10 +10,11 @@
"test:e2e": "vue-cli-service test:e2e"
},
"dependencies": {
"@smallwei/avue": "^1.1.19",
"@smallwei/avue": "^1.1.20-beta1",
"avue-plugin-transfer": "^0.0.2",
"avue-plugin-ueditor": "^0.0.1",
"axios": "^0.18.0",
"babel-loader": "^8.0.2",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "^6.26.0",
"classlist-polyfill": "^1.2.0",
......@@ -58,4 +59,4 @@
"git add"
]
}
}
\ No newline at end of file
}
import CrudCascader from '../crud/src/crud-cascader';
CrudCascader.install = function(Vue) {
Vue.component(CrudCascader.name, CrudCascader);
};
export default CrudCascader;
import CrudCheckBox from '../crud/src/crud-checkbox';
CrudCheckBox.install = function(Vue) {
Vue.component(CrudCheckBox.name, CrudCheckBox);
};
export default CrudCheckBox;
import CrudData from '../crud/src/crud-date';
CrudData.install = function(Vue) {
Vue.component(CrudData.name, CrudData);
};
export default CrudData;
import CrudInputNumber from '../crud/src/crud-input-number';
CrudInputNumber.install = function(Vue) {
Vue.component(CrudInputNumber.name, CrudInputNumber);
};
export default CrudInputNumber;
import CrudInput from '../crud/src/crud-input';
CrudInput.install = function(Vue) {
Vue.component(CrudInput.name, CrudInput);
};
export default CrudInput;
import CrudRadio from '../crud/src/crud-radio';
CrudRadio.install = function(Vue) {
Vue.component(CrudRadio.name, CrudRadio);
};
export default CrudRadio;
import CrudRate from '../crud/src/crud-rate';
CrudRate.install = function(Vue) {
Vue.component(CrudRate.name, CrudRate);
};
export default CrudRate;
import CrudSelect from '../crud/src/crud-select';
CrudSelect.install = function(Vue) {
Vue.component(CrudSelect.name, CrudSelect);
};
export default CrudSelect;
import CrudSilder from '../crud/src/crud-silder';
CrudSilder.install = function(Vue) {
Vue.component(CrudSilder.name, CrudSilder);
};
export default CrudSilder;
import CrudSwitch from '../crud/src/crud-switch';
CrudSwitch.install = function(Vue) {
Vue.component(CrudSwitch.name, CrudSwitch);
};
export default CrudSwitch;
import CrudTime from '../crud/src/crud-time';
CrudTime.install = function(Vue) {
Vue.component(CrudTime.name, CrudTime);
};
export default CrudTime;
import CrudUpload from '../crud/src/crud-upload.vue';
CrudUpload.install = function(Vue) {
Vue.component(CrudUpload.name, CrudUpload);
};
export default CrudUpload;
import Crud from './src/main';
Crud.install = function(Vue) {
Vue.component(Crud.name, Crud);
};
export default Crud;
//crud配置文件
export default {
//标题
editTitle: '编 辑',
addTitle: '新 增',
viewTitle: '查 看',
menuTitle: '操作',
tipStartTitle: '当前表格已选择',
tipEndTitle: '项',
//尺寸
menuWidth: 240,
cellBtnSize: 'small',
viewBtnSize: 'small',
delBtnSize: 'small',
editBtnSize: 'small',
addBtnSize: 'small',
searchBtnSize: 'small',
emptyBtnSize: 'small',
searchComponentSize: 'small',
columnBtnSize: 'small',
refreshBtnSize: 'small',
searchboxBtnSize: 'small',
menuBtnSize: 'small',
dateBtnSize: 'small',
//文字
viewBtnTitle: '查 看',
editBtnTitle: '编 辑',
addBtnTitle: '新 增',
delBtnTitle: '删 除',
updateBtnTitle: '修 改',
saveBtnTitle: '新 增',
cancelBtnTitle: '取 消',
columnBtnTitle: '多 选',
searchBtnTitle: '搜 索',
emptyBtnTitle: '清 空',
tipBtnTitle: '清空',
menuBtnTitle: '菜 单',
cellEditBtnTitle: '修改',
cellSaveBtnTitle: '保存',
//图标
viewBtnIcon: 'el-icon-view',
editBtnIcon: 'el-icon-edit',
addBtnIcon: 'el-icon-plus',
delBtnIcon: 'el-icon-delete',
searchBtnIcon: 'el-icon-search',
emptyBtnIcon: 'el-icon-delete',
cellEditBtnIcon: 'el-icon-edit',
cellSaveBtnIcon: 'el-icon-check',
columnBtnIcon: 'el-icon-menu',
refreshBtnIcon: 'el-icon-refresh',
searchboxBtnIcon: 'el-icon-search',
//显隐
viewBtn: false,
editBtn: true,
addBtn: true,
delBtn: true,
cellBtn: false,
dateBtn: false,
refreshBtn: true,
columnBtn: true,
searchBtn: true,
menuBtn: false,
selectClearBtn: true,
searchShow: true,
tip: true,
formWidth: '50%',
formFullscreen: false,
customClass: '',
pageBackground: true,
page: true,
menu: true,
indexLabel: '#',
filterMultiple: true,
calcHeight: 300,
title: '表格标题',
width: '100%',
dateDefault: false,
//搜索参数
searchMultiple: ['checkbox', 'tree', 'select']
}
\ No newline at end of file
<template>
<el-cascader :options="dic"
v-model="text"
:placeholder="placeholder?placeholder:`请选择${label}`"
:props="props"
:readonly="readonly"
:change-on-select="changeoOnSelect"
:clearable="clearable"
:expand-trigger="expandTrigger"
:show-all-levels="showAllLevels"
:filterable="filterable"
:separator="separator"
:disabled="disabled"
@click.native="handleClick"
@change="handleChange">
</el-cascader>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-cascader',
mixins: [crudCompoents()],
props: {
value: {
type: Array,
default: () => []
},
changeoOnSelect: {
type: Boolean,
default: false
},
expandTrigger: {
type: String,
default: 'hover'
},
showAllLevels: {
type: Boolean,
default: true
},
filterable: {
type: Boolean,
default: false
},
separator: {
type: String,
default: '/'
}
},
data () {
return {};
},
watch: {},
created () { },
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
}
}
});
</script>
<template>
<el-checkbox-group v-model="text"
@change="handleChange"
@click.native="handleClick">
<el-checkbox v-for="(item,index) in dic"
:label="item[valueKey]"
:border="border"
:min="min"
:readonly="readonly"
:max="max"
:disabled="item[disabledKey]"
:key="index">{{item[labelKey]}}</el-checkbox>
</el-checkbox-group>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-checkbox',
mixins: [crudCompoents()],
data () {
return {};
},
props: {
value: {
type: Array,
default: () => []
}
},
watch: {},
created () { },
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
}
}
});
</script>
<template>
<div>
<el-table-column v-if="columnIndex.indexOf(column.prop)!=-1"
v-for="(column,index) in columnOption"
:prop="column.prop"
:key="index"
filter-placement="bottom-end"
:filters="column.filters"
:filter-method="column.filterMethod"
:filter-multiple="vaildData(column.filterMultiple,true)"
:show-overflow-tooltip="column.overHidden"
:min-width="column.minWidth"
:sortable="column.sortable"
:align="vaildData(column.align,tableOption.align)"
:header-align="vaildData(column.headerAlign,tableOption.headerAlign)"
:width="column.width"
:label="column.label"
:fixed="column.fixed">
<crud-components v-if="column.children"
:columnOption="column.children"
:tableOption="tableOption"
:tableForm="tableForm"
:columnIndex="columnIndex"
:DIC="DIC">
<template slot-scope="scope"
v-for="item in column.children"
:slot="item.prop">
<slot :row="scope.row"
:dic="scope.dic"
:label="scope.label"
:name="item.prop"
v-if="item.solt"></slot>
</template>
</crud-components>
<template slot-scope="scope">
<template v-if="cellEditFlag(scope.row,column)">
<component size="small"
:is="getSearchType(column.type)"
v-model="tableForm[column.prop]"
:type="getType(column)"
clearable
:placeholder="column.label"
:dic="setDic(column.dicData,DIC[column.dicData])"></component>
</template>
<slot :row="scope.row"
:dic="setDic(column.dicData,DIC[column.dicData])"
:label="detail(scope.row,column)"
:name="column.prop"
v-else-if="column.solt"></slot>
<template v-else>
<span v-html="detail(scope.row,column)"></span>
</template>
</template>
</el-table-column>
</div>
</template>
<script>
import column from '../../mixins/column'
import crudInput from './crud-input';
import crudSelect from './crud-select';
export default {
name: 'crud-components',
mixins: [column()],
props: [
'columnIndex',
'columnOption',
'tableOption',
'DIC',
'tableForm'
],
components: {
crudInput,
crudSelect,
},
created () {
this.initFun();
},
methods: {
}
}
</script>
<style>
</style>
<template>
<el-date-picker :type="type"
v-model="text"
:size="size"
:readonly="readonly"
range-separator="至"
:start-placeholder="startPlaceholder"
:end-placeholder="endPlaceholder"
:format="format"
:picker-options="pickerOptions"
:value-format="valueFormat"
:default-time="defaultTime"
:placeholder="placeholder?placeholder:`请输入${label}`"
@change="handleChange"
@click.native="handleClick"
:disabled="disabled"> </el-date-picker>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-date',
mixins: [crudCompoents()],
data () {
return {
text: ''
};
},
props: {
value: {
},
startPlaceholder: {
type: String,
default: '开始日期'
},
endPlaceholder: {
type: String,
default: '结束日期'
},
defaultTime: {
type: String
},
pickerOptions: {
type: Object,
default: () => { }
},
type: {
default: 'date'
},
valueFormat: {
},
format: {
}
},
watch: {},
created () { },
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
}
}
});
</script>
<template>
<el-input-number v-model="text"
class="avue-input-number"
@change="handleChange"
@click.native="handleClick"
:precision="precision"
:size="size"
:min="minRows"
:max="maxRows"
:readonly="readonly"
:controls-position="controlsPosition"
:label="placeholder?placeholder:`请输入${label}`"
:disabled="disabled"></el-input-number>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-input-number',
mixins: [crudCompoents()],
data () {
return {};
},
props: {
value: {
type: Number
},
step: {
type: Number,
default: 1
},
controlsPosition: {
type: String,
default: 'right'
},
precision: {
type: Number,
default: 0
},
minRows: {
type: Number,
default: -Infinity
},
maxRows: {
type: Number,
default: Infinity
}
},
watch: {},
created () { },
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
}
}
});
</script>
\ No newline at end of file
<template>
<div>
<el-input v-if="type==='tree'"
:size="size"
v-model="labelShow"
:type="typeParam"
:autosize="{ minRows: minRows, maxRows: maxRows}"
:prefix-icon="prefixIcon"
:suffix-icon="suffixIcon"
:placeholder="placeholder?placeholder:`请选择${label}`"
@change="handleChange"
:disabled="disabled"
:readonly="true"
@click.native="disabled?'':open()" />
<el-input v-else-if="type==='phone'"
:size="size"
:clearable="clearable"
v-model="text"
@click.native="handleClick"
:type="typeParam"
:maxlength="maxlength"
:autosize="{ minRows: minRows, maxRows: maxRows}"
:prefix-icon="prefixIcon"
:suffix-icon="suffixIcon"
:readonly="readonly"
:placeholder="placeholder?placeholder:`请输入${label}`"
@change="handleChange"
:disabled="disabled" />
<el-input v-else
:size="size"
:clearable="clearable"
v-model="text"
@click.native="handleClick"
:type="typeParam"
:maxlength="maxlength"
:minlength="minlength"
:autosize="{ minRows: minRows, maxRows: maxRows}"
:prefix-icon="prefixIcon"
:suffix-icon="suffixIcon"
:readonly="readonly"
:placeholder="placeholder?placeholder:`请输入${label}`"
@change="handleChange"
:disabled="disabled" />
<el-dialog :visible.sync="box"
append-to-body
:title="`请选择${label}`"
width="50%">
<el-input style="margin-bottom:15px;"
placeholder="输入关键字进行过滤"
v-model="filterText"
v-if="filter">
</el-input>
<div class="avue-dialog">
<el-tree :data="dic"
:node-key="valueKey"
:show-checkbox="multiple"
:props="props"
ref="tree"
@check="checkChange"
:filter-node-method="filterNode"
:default-expanded-keys="multiple?text:[]"
:default-checked-keys="multiple?text:[]"
:default-expand-all="defaultExpandAll"
@node-click="handleNodeClick"></el-tree>
</div>
</el-dialog>
</div>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
import { validatenull } from '../../utils/validate';
export default create({
name: 'crud-input',
mixins: [crudCompoents()],
data () {
return {
filterText: '',
box: false,
labelText: this.multiple ? [] : ''
};
},
props: {
nodeClick: Function,
value: {
},
filter: {
type: Boolean,
default: true
},
multiple: {
type: Boolean,
default: false
},
parent: {
type: Boolean,
default: true
},
defaultExpandAll: {
type: Boolean,
default: true
},
prefixIcon: {
type: String
},
suffixIcon: {
type: String
},
minlength: {
type: Number
},
maxlength: {
type: Number,
default: function () {
if (this.type === 'phone') return 11;
}
},
minRows: {
type: Number,
default: 3
},
maxRows: {
type: Number,
default: 4
}
},
watch: {
value () {
this.init();
},
filterText (val) {
this.$refs.tree.filter(val);
}
},
computed: {
labelShow () {
return this.multiple ? this.labelText.join('/').toString() : this.labelText;
},
textShow () {
if (this.textLen === 11) return `${this.text.substr(0, 3)} ${this.text.substr(3, 4)} ${this.text.substr(7, 4)}`
return this.text;
},
textLen () {
return this.text.length;
},
typeParam: function () {
if (this.type === 'textarea') {
return 'textarea';
} else if (this.type === 'password') {
return 'password';
} else {
return 'text';
}
}
},
created () { },
mounted () {
this.init();
},
methods: {
filterNode (value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
checkChange (checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys) {
console.log(checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys);
this.text = [];
this.labelText = [];
checkedKeys.checkedNodes.forEach(node => {
if (validatenull(node[this.childrenKey])) {
this.text.push(node[this.valueKey]);
this.labelText.push(node[this.labelKey]);
}
});
this.$emit('input', this.text);
this.$emit('change', this.text);
},
open () {
this.box = true;
this.handleClick();
},
init () {
if (this.type === 'tree') {
if (this.multiple) {
this.labelText = ['获取字典中...'];
} else {
this.labelText = '获取字典中...';
}
const check = setInterval(() => {
if (!validatenull(this.dic)) {
if (this.multiple) {
this.labelText = [];
this.text.forEach(ele => {
this.findLabelNode(this.dic, ele, this.props);
});
} else {
this.labelText = this.text;
this.findLabelNode(this.dic, this.text, this.props);
}
if (!this.parent) this.disabledParentNode(this.dic);
clearInterval(check);
} else {
this.labelText = '';
}
}, 500);
} else if (this.type === 'phone') {
if (!validatenull(this.text) && this.textLen == 11) {
this.text = this.textShow;
}
}
},
findLabelNode (dic, value, props) {
const labelKey = props.label || 'label';
const valueKey = props.value || 'value';
const childrenKey = props.children || 'children';
dic.forEach(ele => {
const children = ele[childrenKey];
if (ele[valueKey] === value) {
const label = ele[labelKey];
this.multiple ? this.labelText.push(label) : this.labelText = label;
} else if (!validatenull(children)) {
this.findLabelNode(children, value, props);
}
});
},
disabledParentNode (dic) {
dic.forEach(ele => {
const children = ele[this.childrenKey];
if (!validatenull(children)) {
ele.disabled = true;
this.disabledParentNode(children);
}
});
},
handleNodeClick (data) {
const callback = () => {
this.box = false;
}
if (validatenull(data[this.childrenKey]) && !this.multiple || this.parent) {
const value = data[this.valueKey];
const label = data[this.labelKey];
this.text = value;
this.labelText = label;
this.$emit('input', value);
this.$emit('change', value);
if (typeof this.nodeClick === 'function') this.nodeClick(data, callback);
else callback();
}
},
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
let text = this.text;
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
if (this.type === 'phone') {
this.text = text.replace(/[^0-9.]/g, '');
this.text = this.textShow;
text = this.text.replace(/\s/g, "");
}
this.$emit('input', text);
this.$emit('change', text);
}
}
});
</script>
<template>
<el-radio-group v-model="text"
@change="handleChange"
@click.native="handleClick"
:disabled="disabled">
<el-radio v-for="(item,index) in dic"
:label="item[valueKey]"
:border="border"
:readonly="readonly"
:disabled="item[disabledKey]"
:key="index">{{item[labelKey]}}</el-radio>
</el-radio-group>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-radio',
mixins: [crudCompoents()],
data () {
return {};
},
props: {
value: {}
},
watch: {},
created () { },
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
}
}
});
</script>
\ No newline at end of file
<template>
<el-rate v-model="text"
style="margin-top:10px"
@change="handleChange"
@click.native="handleClick"
:max="max"
:readonly="readonly"
:show-text="showText"
:icon-classes="iconClasses"
:void-icon-class="voidIconClass"
:disabled="disabled"
:colors="colors"></el-rate>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-rate',
mixins: [crudCompoents()],
props: {
value: {
type: Number,
default: 0
},
colors: {
type: Array
},
max: {
type: Number,
default: 5
},
iconClasses: {
type: Array
},
texts: {
type: Array
},
showText: {
type: Boolean,
default: false
},
voidIconClass: {
type: String
}
},
data () {
return {};
},
watch: {},
created () { },
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
}
}
});
</script>
<template>
<el-select v-model="text"
:size="size"
:multiple="multiple"
:filterable="filterable"
:readonly="readonly"
:clearable="clearable"
:placeholder="placeholder?placeholder:`请选择${label}`"
@change="handleChange"
@click.native="handleClick"
:disabled="disabled">
<el-option v-for="(item,index) in dic"
:key="index"
:disabled="item[disabledKey]"
:label="item[labelKey]"
:value="item[valueKey]">
</el-option>
</el-select>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-select',
mixins: [crudCompoents()],
data () {
return {};
},
props: {
value: {
},
multiple: {
type: Boolean,
default: false
},
filterable: {
type: Boolean,
default: false
},
},
watch: {
},
created () { },
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
}
}
});
</script>
\ No newline at end of file
<template>
<el-slider v-model="text"
:disabled="disabled"
:step="step"
:min="min"
:max="max"
:range="range"
:show-stops="showStops"
:show-input="showInput"
:format-tooltip="formatTooltip"
@click.native="handleClick"
@change="handleChange"></el-slider>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-silder',
mixins: [crudCompoents()],
props: {
value: {
},
step: {
type: Number
},
min: {
type: Number
},
max: {
type: Number
},
range: {
type: Boolean,
default: false
},
showInput: {
type: Boolean,
default: false
},
showStops: {
type: Boolean,
default: false
},
formatTooltip: Function
},
data () {
return {};
},
watch: {},
created () { },
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
},
getDic (index) {
return this.dic[index] ? this.dic[index] : {};
}
}
});
</script>
<template>
<div>
<el-switch v-model="text"
@change="handleChange"
@click.native="handleClick"
:active-text="getDic(0)[labelKey]"
:active-value="getDic(0)[valueKey] || ''"
:inactive-value="getDic(1)[valueKey] || ''"
:inactive-text="getDic(1)[labelKey]"
:disabled="disabled"
:readonly="readonly"
:size="size">
</el-switch>
</div>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-switch',
mixins: [crudCompoents()],
props: {
value: {
}
},
data () {
return {};
},
watch: {},
created () { },
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
},
getDic (index) {
return this.dic[index] ? this.dic[index] : {};
}
}
});
</script>
<template>
<el-time-picker v-model="text"
:is-range="isRange"
:size="size"
range-separator="至"
:start-placeholder="startPlaceholder"
:end-placeholder="endPlaceholder"
:format="format"
:readonly="readonly"
:value-format="valueFormat"
:placeholder="placeholder?placeholder:`请输入${label}`"
@change="handleChange"
@click.native="handleClick"
:disabled="disabled"> </el-time-picker>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-time',
mixins: [crudCompoents()],
data () {
return {};
},
props: {
startPlaceholder: {
type: String,
default: '开始时间'
},
endPlaceholder: {
type: String,
default: '结束时间'
},
value: {
required: true
},
valueFormat: {
default: ''
},
type: {
default: ''
},
format: {
default: ''
}
},
watch: {},
created () { },
mounted () { },
computed: {
isRange () {
return this.type === 'timerange'
}
},
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (value) {
if (typeof this.change === 'function') this.change({ value: value, column: this.column });
this.$emit('input', value);
this.$emit('change', value);
}
}
});
</script>
<template>
<div :class="b()">
<el-upload :class="b({'list':listType=='picture-img'})"
@click.native="handleClick"
:action="action"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:multiple="multiple"
:on-preview="handlePictureCardPreview"
:limit="limit"
:http-request="httpRequest"
:drag="drag"
:readonly="readonly"
:show-file-list="showFileList"
:list-type="listType"
:on-change="handleChange"
:on-exceed="handleExceed"
:disabled="disabled"
:file-list="fileList">
<template v-if="listType=='picture-card'">
<i class="el-icon-plus"></i>
</template>
<template v-else-if="listType=='picture-img'">
<img v-if="imageUrl"
:src="imageUrl"
:class="b('avatar')">
<i v-else
class="el-icon-plus"
:class="b('icon')"></i>
</template>
<template v-else-if="drag">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或
<em>点击上传</em>
</div>
</template>
<template v-else>
<el-button size="small"
type="primary">点击上传</el-button>
</template>
<div slot="tip"
class="el-upload__tip">{{tip}}</div>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<div class="avue-dialog">
<img width="100%"
:src="dialogImageUrl"
alt="">
</div>
</el-dialog>
</div>
</template>
<script>
import create from '../../utils/create';
import crudCompoents from '../../mixins/crud-compoents.js';
export default create({
name: 'crud-upload',
mixins: [crudCompoents()],
data () {
return {
loading: false,
dialogImageUrl: '',
dialogVisible: false,
text: this.status ? '' : [],
fileList: [],
file: {}
};
},
props: {
value: {
},
showFileList: {
type: Boolean,
default: true
},
limit: {
type: Number,
default: 3
},
listType: {
type: String
},
drag: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: true
},
loadText: {
type: String,
default: '文件上传中,请稍等'
},
action: {
type: String,
default: ''
},
uploadBefore: Function,
uploadAfter: Function
},
computed: {
status () {
return this.listType === 'picture-img';
},
imageUrl () {
return this.status ? this.text : '';
}
},
created () {
},
watch: {
text () {
this.fileList = this.text || [];
}
},
mounted () { },
methods: {
handleClick () {
if (typeof this.click === 'function') this.click({ value: this.text, column: this.column });
},
handleChange (file, fileList) {
if (typeof this.change === 'function') this.change({ value: this.value, column: this.column });
this.loading = this.$loading({
lock: true,
text: this.loadText,
spinner: 'el-icon-loading',
});
const len = fileList.length;
this.fileList = this.fileList.splice(len, 1);
},
handleSuccess (file) {
{
this.fileList.push({
name: file.label,
url: file.value
});
this.$message.success('上传成功');
this.setVal();
}
},
handleRemove (file, fileList) {
this.fileList = fileList;
this.$message.success('删除成功');
this.setVal();
},
handleError () {
this.$message.error('上传失败');
},
show (res) {
const data = res.data;
this.loading.close();
this.handleSuccess({
label: data[this.labelKey],
value: data[this.valueKey]
});
},
hide () {
this.loading.close();
this.handleError();
},
httpRequest (config) {
const file = config.file;
this.file = config.file;
const headers = { 'Content-Type': 'multipart/form-data' }
let param = new FormData()
param.append('file', file, file.name)
const callack = () => {
this.$http.post(this.action, param, { headers }).then(res => {
if (typeof this.uploadAfter === 'function') this.uploadAfter(res, () => {
this.show(res)
})
else this.show(res);
}).catch((error) => {
if (typeof this.uploadAfter === 'function') this.uploadAfter(error, this.hide);
else this.hide(error);
});
};
if (typeof this.uploadBefore === 'function') this.uploadBefore(this.file, callack);
else callack();
},
setVal () {
let value;
if (this.status) {
value = this.text;
} else {
value = this.fileList;
}
this.$emit('input', value);
this.$emit('change', value);
},
handleExceed (files, fileList) {
this.$message.warning(`当前限制选择 ${this.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
handlePictureCardPreview (file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
beforeRemove (file) {
return this.$confirm(`确定移除 ${file.name}?`);
}
}
});
</script>
\ No newline at end of file
This diff is collapsed.
import DataBox from './src/data-box.vue';
DataBox.install = function(Vue) {
Vue.component(DataBox.name, DataBox);
};
export default DataBox;
<template>
<div class="data-box">
<el-row :span="24">
<el-col :md="span"
:xs="24"
:sm="12"
v-for="(item,index) in data"
:key="index">
<div class="item">
<div class="item-icon"
:style="{backgroundColor:item.color}">
<i :class="item.icon"></i>
</div>
<div class="item-info">
<div :style="{color:item.color}"
class="title">{{item.count}}</div>
<div class="info">{{item.title}}</div>
</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import create from '../../utils/create';
export default create({
name: 'data-box',
data () {
return {
};
},
props: {
option: {
type: Object,
default: () => { }
}
},
computed: {
span () { return this.option.span || 8; },
data () { return this.option.data || []; }
},
created () { },
mounted () { },
watch: {},
methods: {}
});
</script>
\ No newline at end of file
import DataCard from './src/data-card.vue';
DataCard.install = function(Vue) {
Vue.component(DataCard.name, DataCard);
};
export default DataCard;
<template>
<div class="data-card">
<el-row :span="24">
<el-col :md="span"
:xs="24"
:sm="12"
v-for="(item,index) in data"
:key="index">
<div class="item">
<img :src="item.src"
class="item-img" />
<div class="item-text"
:style="{backgroundColor:bgText}">
<h3 :style="{color:colorText}">{{item.name}}</h3>
<p :style="{color:colorText}">{{item.text}}</p>
</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import create from '../../utils/create';
export default create({
name: 'data-card',
data () {
return {
};
},
props: {
option: {
type: Object,
default: () => { }
}
},
computed: {
span () {
return this.option.span || 6;
},
data () {
return this.option.data || [];
},
colorText () {
return this.option.colorText || '#fff';
},
bgText () {
return this.option.bgText || '#2e323f';
},
borderColor () {
return this.option.borderColor || '#2e323f';
}
},
created () { },
mounted () { },
watch: {},
methods: {}
});
</script>
\ No newline at end of file
import DataDisplay from './src/data-display.vue';
DataDisplay.install = function(Vue) {
Vue.component(DataDisplay.name, DataDisplay);
};
export default DataDisplay;
<template>
<div class="avue-data-display">
<el-row :span="24">
<el-col v-for="(item,index) in data"
:key="index"
:md="span"
:xs="12"
:sm="12">
<div class="item"
:style="{color:color}">
<h5 class="count">{{item.count}}</h5>
<span class="splitLine" />
<p class="title">{{item.title}}</p>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import create from '../../utils/create';
export default create({
name: 'data-display',
data () {
return {
};
},
computed: {
span () {
return this.option.span || 6;
},
data () {
return this.option.data || [];
},
color () {
return this.option.color || 'rgb(63, 161, 255)';
}
},
props: {
option: {
type: Object,
default: () => { }
}
},
created () { },
methods: {}
});
</script>
import DataIcons from './src/data-icons.vue';
DataIcons.install = function(Vue) {
Vue.component(DataIcons.name, DataIcons);
};
export default DataIcons;
<template>
<div class="data-icons">
<el-row :span="24">
<template v-for="(item,index) in data">
<el-col :xs="12"
:sm="6"
:md="span"
:key="index">
<div class="item"
:class="[{'item--easy':discount}]">
<div class="item-icon"
:style="{color:color}">
<i :class="item.icon"></i>
</div>
<div class="item-info">
<span>{{item.title}}</span>
<div class="count"
:style="{color:color}">{{item.count}}</div>
</div>
</div>
</el-col>
</template>
</el-row>
</div>
</template>
<script>
import create from '../../utils/create';
export default create({
name: 'data-icons',
data () {
return {
};
},
computed: {
span () { return this.option.span || 4; },
data () { return this.option.data; },
color () { return this.option.color || 'rgb(63, 161, 255)'; },
discount () { return this.option.discount || false; }
},
props: {
option: {
type: Object,
default: () => { }
}
}
});
</script>
\ No newline at end of file
import DataTabs from './src/data-tabs.vue';
DataTabs.install = function(Vue) {
Vue.component(DataTabs.name, DataTabs);
};
export default DataTabs;
<template>
<div class="data-tabs">
<el-row :span="24">
<el-col :md="span"
:xs="24"
:sm="12"
v-for="(item,index) in data"
:key="index">
<div class="item"
:style="{background:item.color}">
<div class="item-header">
<p>{{item.title}}</p>
<span>{{item.subtitle}}</span>
</div>
<div class="item-body">
<h2>{{item.count}}</h2>
</div>
<div class="item-footer">
<span>{{item.allcount}}</span>
<p>{{item.text}}</p>
</div>
<p class="item-tip">{{item.key}}</p>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import create from '../../utils/create';
export default create({
name: 'data-tabs',
data () {
return {
};
},
computed: {
span () {
return this.option.span || 8;
},
data () {
return this.option.data || [];
}
},
props: {
option: {
type: Object,
default: () => { }
}
}
});
</script>
import DateSelect from './src/main';
DateSelect.install = function(Vue) {
Vue.component(DateSelect.name, DateSelect);
};
export default DateSelect;
\ No newline at end of file
<template>
<div :class="b()">
<div :class="b('radio')">
<el-radio-group :size="size"
@change="handleChange"
v-model="text">
<el-radio-button :label="item.value"
v-for="(item,index) in menu"
:key="index">{{item.label}}</el-radio-button>
</el-radio-group>
</div>
<div :class="b('date')">
<el-date-picker v-model="datetime"
type="daterange"
:size="size"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</div>
</div>
</template>
<script>
import create from '../../utils/create';
import { GetDateStr } from '../../utils/dateUtil.js';
export default create({
name: 'date-select',
data () {
return {
menu: [],
text: '',
datetime: [GetDateStr(0), GetDateStr(30)]
};
},
watch: {
datetime () {
this.text = '';
this.setCurrent(this.datetime.join(','));
},
},
computed: {
},
props: {
default: {
type: Boolean,
default: false
},
size: {
type: String,
default: 'medium'
}
},
created () {
this.init();
},
methods: {
handleChange (val) {
this.setCurrent(val);
},
setCurrent (val) {
this.$emit('input', val);
this.$emit('change', val);
},
init () {
this.menu = [
{
label: '今天',
value: GetDateStr(0)
}, {
label: '昨天',
value: GetDateStr(-1)
}, {
label: '近7天',
value: GetDateStr(-7)
}, {
label: '全部',
value: '-1'
}
];
if (this.default) {
this.text = GetDateStr(0);
this.setCurrent(this.text);
}
}
}
});
</script>
\ No newline at end of file
import FormDetail from './src/main';
FormDetail.install = function(Vue) {
Vue.component(FormDetail.name, FormDetail);
};
export default FormDetail;
<template>
<div :class="b()">
<el-row span="24"
:class="b('item')"
v-for="(item,index) in columnOption"
:key="index">
<div :class="b('header')">
<i :class="[item.icon,b('icon')]"></i>
<h1 :class="b('title')">{{item.label}}</h1>
</div>
<slot :name="item.prop"
:form="form"
:column="item"
v-if="item.slot"></slot>
<el-col :md="column.span||8"
:xs="24"
v-else
v-for="(column,cindex) in item.column"
:key="cindex">
<div :class="b('box')">
<span :class="b('label',[labelPostion])"
:style="{width:`${item.labelWidth}px`}">{{column.label}}:</span>
<slot :name="column.prop+'Form'"
:column="column"
:form="form"
v-if="column.slot"></slot>
<span v-else
:class="b('content')">{{detail(form,column)}}</span>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import create from '../../utils/create';
import crud from '../../mixins/crud.js';
import column from '../../mixins/column.js';
import { validatenull } from '../../utils/validate.js';
export default create({
name: 'form-detail',
mixins: [crud(), column()],
props: {
option: {
type: Object,
default: () => { }
},
value: {}
},
computed: {
labelPostion: function () {
if (this.option.labelPostion) {
return this.option.labelPostion;
}
return 'left';
},
columnOption () {
return this.option.option || [];
}
},
watch: {
value: {
handler (n) {
this.form = n;
},
deep: true
}
},
data () {
return {
tableOption: {},
form: {}
};
},
created () {
this.formInit();
},
methods: {
dicInit () {
let locaDic = this.tableOption.dicData || {};
this.columnOption.forEach(child => {
child.column.forEach(ele => {
if (this.vaildData(ele.dicFlag, true)) {
if (!validatenull(ele.dicUrl)) {
this.dicCascaderList.push({
dicUrl: ele.dicUrl,
dicData: ele.dicData
});
} else if (!validatenull(this.tableOption.dicUrl) && typeof ele.dicData === 'string') {
this.dicCascaderList.push({
dicUrl: this.tableOption.dicUrl,
dicData: ele.dicData
});
}
}
})
});
this.GetDic().then(data => {
this.DIC = Object.assign({}, locaDic, data);
});
},
rulesInit () {
},
formInit () {
this.form = this.value;
}
}
});
</script>
\ No newline at end of file
import FormSteps from './src/main';
FormSteps.install = function(Vue) {
Vue.component(FormSteps.name, FormSteps);
};
export default FormSteps;
<template>
<div :class="b()">
<el-steps :active="formIndex"
:space="option.space"
:simple="option.simple"
:process-status="option.processStatus"
:align-center='vaildData(option.alignCenter,true)'
:direction="option.direction"
:class="b({'steps':option.direction})">
<el-step :title="item.label"
:icon="item.icon"
:status="vaildData(item.status,status[index])"
:description="item.description"
v-for="(item,index) in columnOption"
:key="index"
@click.native="option.switchBtn?switchs(index):''"></el-step>
</el-steps>
<div :class="b('contail')">
<slot name="before"></slot>
<avue-form :option="formOption"
:class="b('form')"
:style="{width:vaildData(formOption.width,'40%')}"
@submit="submit"
v-model="text">
<template slot-scope="scope"
v-for="item in formOption.column"
:slot="item.prop">
<slot :value="scope.value"
:column="scope.column"
:dic="scope.dic"
:name="item.prop"
v-if="item.formsolt"></slot>
</template>
<template slot="menuForm">
<el-button @click="breaks"
v-if="formIndex!=1&&formIndex!=columnLen&&vaildData(option.breakBtn,true)">返回</el-button>
<slot name="menuForm"></slot>
</template>
</avue-form>
<slot name="after"></slot>
</div>
</div>
</template>
<script>
import create from '../../utils/create';
import { formInitVal } from '../../utils/util';
export default create({
name: 'form-steps',
props: {
value: {
type: Object,
default: () => { }
},
option: {
type: Object,
required: true
}
},
computed: {
columnOption () {
return this.option.column || [];
},
columnLen () {
return this.columnOption.length;
},
formOption () {
return this.objectOption.option;
},
objectOption () {
return this.columnOption[this.formIndex - 1];
},
status () {
let status = [];
const leng = this.step - 1;
for (let i = 0; i < leng; i++) {
status.push(this.vaildData(this.option.finishStatus, 'success'));
}
return status;
}
},
watch: {
formOption () {
this.formInit();
this.$emit('change', this.objectOption);
},
text: {
handler () {
for (let o in this.tableForm) {
this.tableForm[o] = this.text[o];
}
},
deep: true
},
value: {
handler () {
this.formVal();
},
deep: true
}
},
data () {
return {
step: 1,
tableForm: {},
text: {},
formIndex: 1
};
},
created () {
this.formInit();
},
methods: {
reset () {
this.formIndex = 1;
this.step = 1;
},
switchs (index) {
if (index < this.step) { this.formIndex = index + 1; }
},
next () {
if (this.step <= this.formIndex) {
this.step++;
}
this.formIndex++;
},
breaks () {
this.formIndex--;
},
formInit () {
const column = this.formOption.column;
this.tableForm = formInitVal(column).tableForm;
this.formVal();
},
formVal () {
for (let o in this.value) {
this.text[o] = this.value[o];
}
for (let o in this.tableForm) {
this.tableForm[o] = this.text[o];
}
this.$emit('input', this.tableForm);
},
submit () {
this.$emit('submit', this.tableForm, this.next);
}
}
});
</script>
import FormTabs from './src/main';
FormTabs.install = function(Vue) {
Vue.component(FormTabs.name, FormTabs);
};
export default FormTabs;
<template>
<div class="b()">
<el-tabs v-model="formIndex"
:type="option.type"
:tab-position="option.tabPosition">
<el-tab-pane v-for="(item,index) in columnOption"
:key="index"
:disabled="item.disabled"
:name="index+''">
<span slot="label">
<i :class="item.icon"></i> {{item.label}}</span>
</el-tab-pane>
</el-tabs>
<div>
<slot name="before"></slot>
<avue-form :option="formOption"
@submit="submit"
v-model="text">
<template slot-scope="scope"
v-for="item in formColumnOption"
:slot="item.prop">
<slot :value="scope.value"
:column="scope.column"
:dic="scope.dic"
:name="item.prop"
v-if="item.formsolt"></slot>
</template>
<template slot="menuForm">
<slot name="menuForm"></slot>
</template>
</avue-form>
<slot name="after"></slot>
</div>
</div>
</template>
<script>
import create from '../../utils/create';
import { formInitVal } from '../../utils/util';
export default create({
name: 'form-tabs',
props: {
value: {
type: Object,
default: () => { }
},
option: {
type: Object,
required: true
}
},
computed: {
columnOption () {
return this.option.column || [];
},
columnLen () {
return this.columnOption.length;
},
formOption () {
return this.objectOption.option;
},
formColumnOption () {
return this.formOption.column || [];
},
objectOption () {
return this.columnOption[this.formIndex];
}
},
watch: {
formOption () {
this.formInit();
this.$emit('change', this.columnOption[this.formIndex]);
},
text: {
handler () {
for (let o in this.tableForm) {
this.tableForm[o] = this.text[o];
}
},
deep: true
},
value: {
handler () {
this.formVal();
},
deep: true
}
},
data () {
return {
tableForm: {},
text: {},
formIndex: '0'
};
},
created () {
this.formInit();
},
methods: {
formInit () {
const column = this.formOption.column;
this.tableForm = formInitVal(column).tableForm;
this.formVal();
},
formVal () {
for (let o in this.value) {
this.text[o] = this.value[o];
}
for (let o in this.tableForm) {
this.tableForm[o] = this.text[o];
}
this.$emit('input', this.tableForm);
},
submit () {
this.$emit('submit', this.tableForm);
}
}
});
</script>
\ No newline at end of file
import Form from './src/main';
Form.install = function(Vue) {
Vue.component(Form.name, Form);
};
export default Form;
This diff is collapsed.
import Crud from './crud/index.js';
import CrudCheckbox from './crud-checkbox/index.js';
import CrudDate from './crud-date/index.js';
import CrudTime from './crud-time/index.js';
import CrudInput from './crud-input/index.js';
import CrudRadio from './crud-radio/index.js';
import CrudSelect from './crud-select/index.js';
import CrudCascader from './crud-cascader/index.js';
import CrudNumberInput from './crud-input-number/index.js';
import CrudSwitch from './crud-switch/index.js';
import CrudRate from './crud-rate/index.js';
import CrudUpload from './crud-upload/index.js';
import CrudSilder from './crud-silder/index.js';
import DataDisplay from './data-display/index.js';
import DataCard from './data-card/index.js';
import DataTabs from './data-tabs/index.js';
import DataIcons from './data-icons/index.js';
import DataBox from './data-box/index.js';
import Form from './form/index.js';
import FormTabs from './form-tabs/index.js';
import FormSteps from './form-steps/index.js';
import FormDetail from './form-detail/index.js';
import TableTree from './table-tree/index.js';
import DateSelect from './date-select/index.js';
const components = [
Crud,
Form,
FormTabs,
FormSteps,
FormDetail,
CrudCheckbox,
CrudDate,
CrudTime,
CrudInput,
CrudRadio,
CrudSelect,
CrudCascader,
CrudNumberInput,
CrudSwitch,
CrudRate,
CrudUpload,
CrudSilder,
DataDisplay,
DataCard,
DataIcons,
DataTabs,
DataBox,
TableTree,
DateSelect
];
function install(Vue, axios) {
Vue.prototype.$http = axios;
const AVUE = {};
components.map(component => {
Vue.component(component.name, component);
});
Vue.prototype.$AVUE = AVUE;
}
if (window.Vue) {
install(window.Vue, window.axios);
}
export default install;
\ No newline at end of file
/**
* bem helper
* b() // 'button'
* b('text') // 'button__text'
* b({ disabled }) // 'button button--disabled'
* b('text', { disabled }) // 'button__text button__text--disabled'
* b(['disabled', 'primary']) // 'button button--disabled button--primary'
*/
const ELEMENT = '__';
const MODS = '--';
const join = (name, el, symbol) => el ? name + symbol + el : name;
const prefix = (name, mods) => {
if (typeof mods === 'string') {
return join(name, mods, MODS);
}
if (Array.isArray(mods)) {
return mods.map(item => prefix(name, item));
}
const ret = {};
Object.keys(mods).forEach(key => {
ret[name + MODS + key] = mods[key];
});
return ret;
};
export default {
methods: {
b(el, mods) {
const { name } = this.$options;
if (el && typeof el !== 'string') {
mods = el;
el = '';
}
el = join(name, el, ELEMENT);
return mods ? [el, prefix(el, mods)] : el;
}
}
};
\ No newline at end of file
import * as utils from '../utils/util.js';
import dayjs from 'dayjs';
export default function() {
return {
methods: {
initFun() {
Object.keys(utils).forEach(key => {
this[key] = utils[key];
});
},
cellEditFlag(row, column) {
return row.$cellEdit && [undefined, 'select', 'input'].includes(column.type) && column.solt !== true && column.cell;
},
// 处理数据
detail(row, column) {
let result = row[column.prop || column.value] || '';
if (column.type) {
if (['date', 'time', 'datetime'].includes(column.type) && column.format) {
const format = column.format
.replace('dd', 'DD')
.replace('yyyy', 'YYYY');
result = dayjs(result).format(format);
}
if (column.dicData) {
result = this.findByvalue(
typeof column.dicData === 'string' ? this.DIC[column.dicData] : column.dicData,
result,
(column.props || this.tableOption.props)
);
}
}
if (column.formatter && typeof column.formatter === 'function') {
result = column.formatter(row, row[column.prop], result, column);
}
return result;
},
}
}
}
\ No newline at end of file
export default function() {
//props配置
const propsDefault = {
id: 'id',
label: 'label',
value: 'value',
children: 'children',
disabled: 'disabled'
}
return {
data() {
return {
text: undefined,
propsDefault: propsDefault
}
},
props: {
change: Function,
click: Function,
column: {
type: Object,
default: () => {}
},
label: {
type: String,
default: ''
},
readonly: {
type: Boolean,
default: false
},
size: {
type: String,
default: ''
},
tip: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
type: {
type: String,
default: ''
},
dic: {
type: Array,
default: () => []
},
placeholder: {
type: String,
default: ''
},
min: {
type: Number
},
max: {
type: Number
},
border: {
type: Boolean,
default: false
},
props: {
type: Object,
default: () => propsDefault
}
},
watch: {
value() {
this.text = this.value;
}
},
computed: {
valueKey: function() {
return this.props.value || this.propsDefault.value;
},
labelKey: function() {
return this.props.label || this.propsDefault.label;
},
childrenKey: function() {
return this.props.children || this.propsDefault.children;
},
disabledKey: function() {
return this.props.disabled || this.propsDefault.disabled;
},
idKey: function() {
return this.props.id || this.propsDefault.id;
}
},
created() {
this.text = this.value;
}
};
}
\ No newline at end of file
import * as utils from '../utils/util.js';
import { validatenull } from '../utils/validate.js';
import crudInput from '../crud/src/crud-input';
import crudSelect from '../crud/src/crud-select';
import crudRadio from '../crud/src/crud-radio';
import crudCheckbox from '../crud/src/crud-checkbox';
import crudCascader from '../crud/src/crud-cascader';
import crudDate from '../crud/src/crud-date';
import crudTime from '../crud/src/crud-time';
import crudInputNumber from '../crud/src/crud-input-number';
import crudSwitch from '../crud/src/crud-switch';
import crudRate from '../crud/src/crud-rate';
import crudUpload from '../crud/src/crud-upload';
import crudSilder from '../crud/src/crud-silder';
export default function() {
return {
props: {
option: {
type: Object,
required: true,
default: () => {
return {};
}
}
},
components: {
crudInput,
crudSelect,
crudRadio,
crudCheckbox,
crudDate,
crudTime,
crudCascader,
crudInputNumber,
crudSwitch,
crudRate,
crudUpload,
crudSilder
},
watch: {
tableForm: {
handler() {
this.$emit('input', this.tableForm);
},
deep: true
},
form: {
handler() {
this.$emit('input', this.form);
},
deep: true
},
value: {
handler() {
this.formVal();
},
deep: true
},
option: {
handler() {
this.init();
},
deep: true
}
},
data() {
return {
DIC: {},
dicCascaderList: []
};
},
created() {
this.init();
},
methods: {
init() {
// 初始化工具
this.initFun();
this.tableOption = this.deepClone(this.option);
const dicFlag = this.vaildData(this.tableOption.dicFlag, true);
// 规则初始化
this.rulesInit();
// 初始化字典
if (dicFlag) this.dicInit();
else this.DIC = this.tableOption.dicData;
// 初始化表单formInitVal
this.formInit();
},
dicInit() {
let locaDic = this.tableOption.dicData || {};
this.columnOption.forEach(ele => {
if (this.vaildData(ele.dicFlag, true)) {
if (!validatenull(ele.dicUrl)) {
this.dicCascaderList.push({
dicUrl: ele.dicUrl,
dicData: ele.dicData
});
} else if (!validatenull(this.tableOption.dicUrl) && typeof ele.dicData === 'string') {
this.dicCascaderList.push({
dicUrl: this.tableOption.dicUrl,
dicData: ele.dicData
});
}
}
});
this.GetDic().then(data => {
this.DIC = Object.assign({}, locaDic, data);
});
},
vaildData(val, dafult) {
if (typeof val === 'boolean') {
return val;
}
return !validatenull(val) ? val : dafult;
},
GetDicByType(href) {
return new Promise((resolve) => {
this.$http.get(href).then(function(res) {
// 降级处理
const list = res.data;
if (!validatenull(list.data)) {
resolve(list.data instanceof Array ? list.data : []);
} else if (!validatenull(list)) {
resolve(list instanceof Array ? list : []);
} else {
resolve([]);
}
});
});
},
GetDic() {
return new Promise((resolve) => {
let result = [];
let dicData = {};
let cascaderList = Object.assign([], this.dicCascaderList);
if (validatenull(cascaderList)) resolve({});
cascaderList.forEach(ele => {
result.push(new Promise((resolve) => {
this.GetDicByType(`${ele.dicUrl.replace('{{key}}', ele.dicData)}`).then(function(res) {
resolve(res);
});
}));
});
Promise.all(result).then(data => {
cascaderList.forEach((ele, index) => {
dicData[ele.dicData] = data[index];
});
resolve(dicData);
});
});
},
initFun() {
Object.keys(utils).forEach(key => {
this[key] = utils[key];
});
}
}
};
}
\ No newline at end of file
import TableTree from './src/main';
TableTree.install = function(Vue) {
Vue.component(TableTree.name, TableTree);
};
export default TableTree;
'use strict';
import Vue from 'vue';
export default function treeToArray(data, expandAll, parent = null, level = null) {
let tmp = [];
Array.from(data).forEach(function(record) {
if (record._expanded === undefined) {
Vue.set(record, '_expanded', expandAll);
}
let _level = 1;
if (level !== undefined && level !== null) {
_level = level + 1;
}
Vue.set(record, '_level', _level);
// 如果有父元素
if (parent) {
Vue.set(record, 'parent', parent);
}
tmp.push(record);
if (record.children && record.children.length > 0) {
const children = treeToArray(record.children, expandAll, record, _level);
tmp = tmp.concat(children);
}
});
return tmp;
}
<template>
<el-table :data="formatData"
:class="b()"
:stripe="option.stripe"
:row-style="showRow"
:row-class-name="rowClassName"
v-bind="$attrs"
:border="border">
<el-table-column v-if="columns.length===0"
width="150">
<template slot-scope="scope">
<span v-for="space in scope.row._level"
class="ms-tree-space"
:key="space"></span>
<span class="tree-ctrl"
v-if="iconShow(0,scope.row)"
@click="toggleExpanded(scope.$index)">
<i v-if="!scope.row._expanded"
class="el-icon-plus"></i>
<i v-else
class="el-icon-minus"></i>
</span>
{{scope.$index}}
</template>
</el-table-column>
<el-table-column v-else
v-for="(column, index) in columns"
:key="column.value"
:label="column.text"
:width="column.width">
<template slot-scope="scope">
<span v-if="index === 0"
v-for="space in scope.row._level"
class="ms-tree-space"
:key="space"></span>
<span class="tree-ctrl"
v-if="iconShow(index,scope.row)"
@click="toggleExpanded(scope.$index)">
<i v-if="!scope.row._expanded"
class="el-icon-plus"></i>
<i v-else
class="el-icon-minus"></i>
</span>
{{detail(scope.row,column)}}
</template>
</el-table-column>
<slot></slot>
</el-table>
</template>
<script>
import create from '../../utils/create';
import treeToArray from './eval';
import crud from '../../mixins/crud.js';
import column from '../../mixins/column.js';
export default create({
name: 'tree-table',
mixins: [crud(), column()],
props: {
option: {
type: Object,
required: true
},
rowClassName: Function,
evalFunc: Function,
evalArgs: Array
},
data () {
return {};
},
created () { },
computed: {
columnOption () {
return this.option.columns || [];
},
data: function () {
return this.option.data || [];
},
columns: function () {
return this.option.columns || [];
},
expandAll: function () {
return this.option.expandAll;
},
border: function () {
return this.option.border || true;
},
// 格式化数据源
formatData: function () {
let tmp;
if (!Array.isArray(this.data)) {
tmp = [this.data];
} else {
tmp = this.data;
}
const func = this.evalFunc || treeToArray;
const args = this.evalArgs
? Array.concat([tmp, this.expandAll], this.evalArgs)
: [tmp, this.expandAll];
return func.apply(null, args);
}
},
methods: {
rulesInit () {
},
formInit () {
},
showRow: function (row) {
const show = row.row.parent
? row.row.parent._expanded && row.row.parent._show
: true;
row.row._show = show;
return show
? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;'
: 'display:none;';
},
// 切换下级是否展开
toggleExpanded: function (trIndex) {
const record = this.formatData[trIndex];
record._expanded = !record._expanded;
},
// 图标显示
iconShow (index, record) {
return index === 0 && record.children && record.children.length > 0;
}
}
});
</script>
'use strict';
var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var cssmin = require('gulp-cssmin');
gulp.task('compile', function() {
return gulp.src('./src/**')
.pipe(sass.sync())
.pipe(autoprefixer({
browsers: ['ie > 9', 'last 2 versions'],
cascade: false
}))
.pipe(cssmin())
.pipe(gulp.dest('./lib'));
});
gulp.task('copyfont', function() {
return gulp.src('./src/fonts/**')
.pipe(cssmin())
.pipe(gulp.dest('./lib/fonts'));
});
gulp.task('build', ['compile', 'copyfont']);
.avue-dialog{max-height:400px;overflow-y:auto}.avue-ghost{opacity:.5;background:#c8ebfb}.avue-tip{position:relative;margin-bottom:12px;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.avue-tip__icon{margin-top:3px;margin-right:5px;font-size:14px}.avue-tip__name{font-size:12px;margin-right:15px;color:#515a6e}.avue-tip__name--bold{padding:0 6px;color:#409eff;font-weight:700;font-size:18px}.avue-tip__btn{margin-top:3px;cursor:pointer}
\ No newline at end of file
.avue-crud-upload--list .el-upload{border:1px dashed #d9d9d9;border-radius:6px;cursor:pointer;position:relative;overflow:hidden}.avue-crud-upload--list .el-upload:hover{border-color:#409eff}.avue-crud-upload__icon{font-size:28px;color:#8c939d;width:178px;height:178px;line-height:178px;text-align:center}.avue-crud-upload__avatar{width:178px;height:178px;display:block}
\ No newline at end of file
.avue-crud{margin:0 auto;width:99%}.avue-crud .el-table th{word-break:break-word;color:rgba(0,0,0,.85);background:#fafafa}.avue-crud .el-table td{padding:8px 0}.avue-crud__pagination{position:relative;height:25px;margin-top:15px;margin-bottom:10px;padding:10px 20px}.avue-crud__pagination .el-pagination{position:absolute;right:0}.avue-crud__form{padding:0 8px}.avue-crud__header{margin-bottom:10px}.avue-crud__header>.el-button{padding:12px 25px}.avue-crud__box{-webkit-box-shadow:none!important;box-shadow:none!important;border:none}.avue-crud__box .el-card__body,.avue-crud__box .el-card__header{padding:18px 0}.avue-crud__title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.avue-crud__menu{position:relative;width:100%;min-height:40px;height:auto;overflow:hidden;margin-bottom:12px}.avue-crud__left,.avue-crud__right{position:absolute;height:auto;overflow:hidden}.avue-crud__left{left:0}.avue-crud__left .el-button{margin-right:5px}.avue-crud__right{right:0}.avue-crud__right .el-button{margin-left:5px}.avue-crud__dialog .el-dialog__header{border-top-left-radius:5px;border-top-right-radius:5px;padding:12px 20px;background-color:#409eff}.avue-crud__dialog .el-dialog__close{color:#fff;font-size:18px}.avue-crud__dialog .el-dialog__close:hover{color:#fdf}.avue-crud__dialog .el-dialog__title{color:#fff;font-size:18px}.avue-crud__dialog .el-dialog__headerbtn{top:18px}.avue-crud__dialog--overflow{max-height:500px;overflow:hidden;overflow-y:auto}
\ No newline at end of file
.data-box .item{display:-webkit-box;display:-ms-flexbox;display:flex;position:relative;margin:0 auto 10px;width:96%;height:100px;overflow:hidden;border-radius:5px;-webkit-box-sizing:border-box;box-sizing:border-box}.data-box .item:hover .item-text{top:0}.data-box .item-icon{width:100px;height:100%;color:#fff;text-align:center;line-height:100px}.data-box .item-icon i{font-size:48px!important}.data-box .item-info{border:1px solid #eee;border-left:none;background-color:#fff;-webkit-box-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.data-box .item-info .title{font-size:30px;line-height:40px;text-align:center}.data-box .item-info .info{color:#999;font-size:14px;text-align:center}
\ No newline at end of file
.data-card .item{position:relative;margin:0 auto 50px;width:230px;height:340px;overflow:hidden;border-radius:5px;border-color:#fff;border-width:1px;border-style:solid}.data-card .item:hover .item-text{top:0}.data-card .item-img{width:100%;background:red;border-radius:5px 5px 0 0}.data-card .item-text{position:absolute;top:150px;padding:20px 15px;width:100%;height:340px;overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:0 0 5px 5px;opacity:.9;-webkit-transition:top .4s;transition:top .4s}.data-card .item-text>p{font-size:12px;line-height:25px;text-indent:2em}
\ No newline at end of file
.avue-data-display .item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:5px 0;text-align:center}.avue-data-display .count{margin:8px 0;font-weight:700;font-size:32px;color:#15A0FF}.avue-data-display .title{color:#999}.avue-data-display .splitLine{display:block;margin:0 auto;width:24px;height:1px;background:#9B9B9B}
\ No newline at end of file
.data-icons .item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:90%;margin:0 auto}.data-icons .item-icon{margin-top:3px;margin-right:8px}.data-icons .item-icon>i{font-size:46px!important}.data-icons .item-info{text-align:center}.data-icons .item-info>span{display:block;color:#999;font-size:12px}.data-icons .item-info .count{font-size:20px;line-height:25px}.data-icons .item--easy{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.data-icons .item--easy>.item-icon{margin:0}.data-icons .item--easy>.item-info{margin-top:-15px}.data-icons .item--easy>.item-info>span{font-size:14px}
\ No newline at end of file
.data-tabs .item,.data-tabs .item-header{position:relative}.data-tabs .item{margin:15px;padding:12px;height:160px;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;color:#fff}.data-tabs .item-header>p{color:#fff;margin:0;font-size:14px}.data-tabs .item-header>span{position:absolute;right:0;top:0;padding:2px 8px;border-radius:4px;font-size:12px;background:rgba(255,255,255,.3)}.data-tabs .item-body>h2{color:#fff;margin:0;font-size:32px;line-height:60px}.data-tabs .item-footer{padding-top:8px;line-height:20px}.data-tabs .item-footer>span{font-size:10px}.data-tabs .item-footer>p{color:#fff;margin:0;font-size:12px}.data-tabs .item-tip{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;position:absolute;width:80px;height:80px;bottom:10px;right:10px;border:2px solid #fff;border-radius:100%;font-size:48px;-webkit-transform:rotate(-40deg);transform:rotate(-40deg);opacity:.1}
\ No newline at end of file
.avue-date-select{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.avue-date-select__radio .el-radio-button:last-child .el-radio-button__inner{border-radius:0;border-right:0}.avue-date-select__date{width:300px}.avue-date-select__date .el-date-editor{border-top-left-radius:0;border-bottom-left-radius:0}
\ No newline at end of file
.avue-input-number,.el-cascader,.el-date-editor.el-input,.el-date-editor.el-input__inner,.el-select{width:100%!important}.el-input__inner{height:38px;line-height:38px}.el-tooltip__popper{max-width:60%}
\ No newline at end of file
.avue-form-detail__item{padding:20px 0;border-bottom:1px solid #eee}.avue-form-detail__item:last-child{border-bottom:none}.avue-form-detail__icon{margin-right:10px;font-size:20px}.avue-form-detail__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:15px}.avue-form-detail__title{font-size:16px;font-weight:500;color:rgba(0,0,0,.85)}.avue-form-detail__box{margin-bottom:20px;font-size:14px}.avue-form-detail__label{margin-right:10px;line-height:20px;color:rgba(0,0,0,.85)}.avue-form-detail__label--center{text-align:center}.avue-form-detail__label--left{text-align:left}.avue-form-detail__label--right{text-align:right}.avue-form-detail__content{line-height:22px;width:100%;color:rgba(0,0,0,.65)}
\ No newline at end of file
.avue-form-steps--vertical{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex}.avue-form-steps__steps{width:230px}.avue-form-steps__contail{-webkit-box-flex:1;-ms-flex:1;flex:1}.avue-form-steps__form{margin:0 auto}
\ No newline at end of file
.avue-form__menu,.avue-form__row--block{width:100%}.avue-form__group,.avue-form__row--block{height:auto;overflow:hidden}.avue-form{padding:8px 10px}.avue-form__menu--center{text-align:center}.avue-form__menu--left{text-align:left}.avue-form__menu--right{text-align:right}.avue-form__group .el-col{position:relative}.avue-form__row--cursor{cursor:pointer}.avue-form__option{position:absolute;right:0;top:-10px;z-index:999}.avue-form__option i{color:#666}.avue-form__option i+i{margin-left:10px}
\ No newline at end of file
.avue-data-display .item,.data-box .item-info,.data-icons .item--easy{-webkit-box-orient:vertical;-webkit-box-direction:normal}.avue-dialog{max-height:400px;overflow-y:auto}.avue-ghost{opacity:.5;background:#c8ebfb}.avue-tip{position:relative;margin-bottom:12px;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.avue-tip__icon{margin-top:3px;margin-right:5px;font-size:14px}.avue-tip__name{font-size:12px;margin-right:15px;color:#515a6e}.avue-tip__name--bold{padding:0 6px;color:#409eff;font-weight:700;font-size:18px}.avue-tip__btn{margin-top:3px;cursor:pointer}.avue-input-number,.el-cascader,.el-date-editor.el-input,.el-date-editor.el-input__inner,.el-select{width:100%!important}.el-input__inner{height:38px;line-height:38px}.el-tooltip__popper{max-width:60%}.avue-crud{margin:0 auto;width:99%}.avue-crud .el-table th{word-break:break-word;color:rgba(0,0,0,.85);background:#fafafa}.avue-crud .el-table td{padding:8px 0}.avue-crud__pagination{position:relative;height:25px;margin-top:15px;margin-bottom:10px;padding:10px 20px}.avue-crud__pagination .el-pagination{position:absolute;right:0}.avue-crud__form{padding:0 8px}.avue-crud__header{margin-bottom:10px}.avue-crud__header>.el-button{padding:12px 25px}.avue-crud__box{-webkit-box-shadow:none!important;box-shadow:none!important;border:none}.avue-crud__box .el-card__body,.avue-crud__box .el-card__header{padding:18px 0}.avue-crud__title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.avue-crud__menu{position:relative;width:100%;min-height:40px;height:auto;overflow:hidden;margin-bottom:12px}.avue-crud__left,.avue-crud__right{position:absolute;height:auto;overflow:hidden}.avue-crud__left{left:0}.avue-crud__left .el-button{margin-right:5px}.avue-crud__right{right:0}.avue-crud__right .el-button{margin-left:5px}.avue-crud__dialog .el-dialog__header{border-top-left-radius:5px;border-top-right-radius:5px;padding:12px 20px;background-color:#409eff}.avue-crud__dialog .el-dialog__close{color:#fff;font-size:18px}.avue-crud__dialog .el-dialog__close:hover{color:#fdf}.avue-crud__dialog .el-dialog__title{color:#fff;font-size:18px}.avue-crud__dialog .el-dialog__headerbtn{top:18px}.avue-crud__dialog--overflow{max-height:500px;overflow:hidden;overflow-y:auto}.avue-crud-upload--list .el-upload{border:1px dashed #d9d9d9;border-radius:6px;cursor:pointer;position:relative;overflow:hidden}.avue-crud-upload--list .el-upload:hover{border-color:#409eff}.avue-crud-upload__icon{font-size:28px;color:#8c939d;width:178px;height:178px;line-height:178px;text-align:center}.avue-crud-upload__avatar{width:178px;height:178px;display:block}.avue-tree-table .ms-tree-space{position:relative;top:1px;display:inline-block;font-style:normal;font-weight:400;line-height:1;width:18px;height:14px}.avue-tree-table .ms-tree-space::before{content:""}.avue-tree-table .processContainer{width:100%;height:100%}.avue-form__group,.avue-form__row--block{height:auto;overflow:hidden}.avue-tree-table table td{line-height:26px}.avue-tree-table .tree-ctrl{position:relative;cursor:pointer;color:#2196f3;margin-left:-18px}@keyframes treeTableShow{from{opacity:0}to{opacity:1}}@-webkit-keyframes treeTableShow{from{opacity:0}to{opacity:1}}.avue-form{padding:8px 10px}.avue-form__menu{width:100%}.avue-form__menu--center{text-align:center}.avue-form__menu--left{text-align:left}.avue-form__menu--right{text-align:right}.avue-form__group .el-col{position:relative}.avue-form__row--block{width:100%}.avue-form__row--cursor{cursor:pointer}.avue-form__option{position:absolute;right:0;top:-10px;z-index:999}.avue-form__option i{color:#666}.avue-form__option i+i{margin-left:10px}.avue-form-steps--vertical{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex}.avue-form-steps__steps{width:230px}.avue-form-steps__contail{-webkit-box-flex:1;-ms-flex:1;flex:1}.avue-form-steps__form{margin:0 auto}.avue-form-detail__item{padding:20px 0;border-bottom:1px solid #eee}.avue-form-detail__item:last-child{border-bottom:none}.avue-form-detail__icon{margin-right:10px;font-size:20px}.avue-form-detail__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:15px}.avue-data-display .item,.data-tabs .item-tip{display:-webkit-box;display:-ms-flexbox;-webkit-box-align:center}.avue-form-detail__title{font-size:16px;font-weight:500;color:rgba(0,0,0,.85)}.avue-form-detail__box{margin-bottom:20px;font-size:14px}.avue-form-detail__label{margin-right:10px;line-height:20px;color:rgba(0,0,0,.85)}.avue-form-detail__label--center{text-align:center}.avue-form-detail__label--left{text-align:left}.avue-form-detail__label--right{text-align:right}.avue-form-detail__content{line-height:22px;width:100%;color:rgba(0,0,0,.65)}.avue-data-display .item{display:flex;-ms-flex-align:center;align-items:center;-ms-flex-direction:column;flex-direction:column;margin:5px 0;text-align:center}.avue-data-display .count{margin:8px 0;font-weight:700;font-size:32px;color:#15A0FF}.avue-data-display .title{color:#999}.avue-data-display .splitLine{display:block;margin:0 auto;width:24px;height:1px;background:#9B9B9B}.data-card .item{position:relative;margin:0 auto 50px;width:230px;height:340px;overflow:hidden;border-radius:5px;border-color:#fff;border-width:1px;border-style:solid}.data-card .item:hover .item-text{top:0}.data-card .item-img{width:100%;background:red;border-radius:5px 5px 0 0}.data-card .item-text{position:absolute;top:150px;padding:20px 15px;width:100%;height:340px;overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:0 0 5px 5px;opacity:.9;-webkit-transition:top .4s;transition:top .4s}.data-tabs .item,.data-tabs .item-header{position:relative}.data-card .item-text>p{font-size:12px;line-height:25px;text-indent:2em}.data-tabs .item{margin:15px;padding:12px;height:160px;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;color:#fff}.data-tabs .item-header>p{color:#fff;margin:0;font-size:14px}.data-tabs .item-header>span{position:absolute;right:0;top:0;padding:2px 8px;border-radius:4px;font-size:12px;background:rgba(255,255,255,.3)}.data-tabs .item-body>h2{color:#fff;margin:0;font-size:32px;line-height:60px}.data-tabs .item-footer{padding-top:8px;line-height:20px}.data-tabs .item-footer>span{font-size:10px}.data-tabs .item-footer>p{color:#fff;margin:0;font-size:12px}.data-tabs .item-tip{display:flex;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;position:absolute;width:80px;height:80px;bottom:10px;right:10px;border:2px solid #fff;border-radius:100%;font-size:48px;-webkit-transform:rotate(-40deg);transform:rotate(-40deg);opacity:.1}.data-icons .item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:90%;margin:0 auto}.data-icons .item-icon{margin-top:3px;margin-right:8px}.data-icons .item-icon>i{font-size:46px!important}.data-icons .item-info{text-align:center}.data-icons .item-info>span{display:block;color:#999;font-size:12px}.data-box .item,.data-box .item-info{display:-webkit-box;display:-ms-flexbox}.data-icons .item-info .count{font-size:20px;line-height:25px}.data-icons .item--easy{-ms-flex-direction:column;flex-direction:column}.data-icons .item--easy>.item-icon{margin:0}.data-icons .item--easy>.item-info{margin-top:-15px}.data-icons .item--easy>.item-info>span{font-size:14px}.data-box .item{display:flex;position:relative;margin:0 auto 10px;width:96%;height:100px;overflow:hidden;border-radius:5px;-webkit-box-sizing:border-box;box-sizing:border-box}.data-box .item:hover .item-text{top:0}.data-box .item-icon{width:100px;height:100%;color:#fff;text-align:center;line-height:100px}.data-box .item-icon i{font-size:48px!important}.data-box .item-info{border:1px solid #eee;border-left:none;background-color:#fff;-webkit-box-flex:1;-ms-flex:1;flex:1;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-ms-flex-direction:column;flex-direction:column}.data-box .item-info .title{font-size:30px;line-height:40px;text-align:center}.data-box .item-info .info{color:#999;font-size:14px;text-align:center}.avue-date-select{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.avue-date-select__radio .el-radio-button:last-child .el-radio-button__inner{border-radius:0;border-right:0}.avue-date-select__date{width:300px}.avue-date-select__date .el-date-editor{border-top-left-radius:0;border-bottom-left-radius:0}
\ No newline at end of file
.avue-select-date{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.avue-select-date__radio .el-radio-button:last-child .el-radio-button__inner{border-radius:0;border-right:0}.avue-select-date__date{width:300px}.avue-select-date__date .el-date-editor{padding:0 10px;height:36px;border-top-left-radius:0;border-bottom-left-radius:0}
\ No newline at end of file
.avue-tree-table .ms-tree-space{position:relative;top:1px;display:inline-block;font-style:normal;font-weight:400;line-height:1;width:18px;height:14px}.avue-tree-table .ms-tree-space::before{content:""}.avue-tree-table .processContainer{width:100%;height:100%}.avue-tree-table table td{line-height:26px}.avue-tree-table .tree-ctrl{position:relative;cursor:pointer;color:#2196f3;margin-left:-18px}@keyframes treeTableShow{from{opacity:0}to{opacity:1}}@-webkit-keyframes treeTableShow{from{opacity:0}to{opacity:1}}
\ No newline at end of file
{
"name": "avue-theme-chalk",
"version": "2.0.0",
"main": "lib/index.css",
"style": "lib/index.css",
"files": [
"lib",
"src"
],
"scripts": {
"build": "gulp build"
},
"keywords": [],
"license": "MIT",
"bugs": {
"devDependencies": {
"gulp": "^3.9.1",
"gulp-cssmin": "^0.1.7",
"gulp-sass": "^3.1.0",
"gulp-autoprefixer": "^4.0.0"
},
"dependencies": {}
}
}
\ No newline at end of file
.avue-ghost {
opacity: 0.5;
background: #c8ebfb;
}
.avue-tip {
position: relative;
margin-bottom: 12px;
width: 100%;
display: flex;
align-items: center;
&__icon {
margin-top: 3px;
margin-right: 5px;
font-size: 14px;
}
&__name {
font-size: 12px;
margin-right: 15px;
color: #515a6e;
&--bold {
padding: 0 6px;
color: #409eff;
font-weight: bold;
font-size: 18px;
}
}
&__btn {
margin-top: 3px;
cursor: pointer;
}
}
\ No newline at end of file
.avue-crud-upload {
&--list {
.el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.el-upload:hover {
border-color: #409eff;
}
}
&__icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
&__avatar {
width: 178px;
height: 178px;
display: block;
}
}
\ No newline at end of file
.avue-crud {
margin: 0 auto;
width: 99%;
.el-table th {
word-break: break-word;
color: rgba(0, 0, 0, 0.85);
background: #fafafa;
}
.el-table td {
padding: 8px 0;
}
&__pagination {
position: relative;
height: 25px;
margin-top: 15px;
margin-bottom: 10px;
padding: 10px 20px;
.el-pagination {
position: absolute;
right: 0;
}
}
&__form {
padding: 0 8px;
}
&__header {
margin-bottom: 10px;
&>.el-button {
padding: 12px 25px;
}
}
&__box {
box-shadow: none !important;
border: none;
.el-card__body,
.el-card__header {
padding: 18px 0;
}
}
&__title {
display: flex;
align-items: center;
justify-content: space-between;
}
&__menu {
position: relative;
width: 100%;
min-height: 40px;
height: auto;
overflow: hidden;
margin-bottom: 12px;
}
&__left,
&__right {
position: absolute;
height: auto;
overflow: hidden;
}
&__left {
left: 0;
.el-button {
margin-right: 5px;
}
}
&__right {
right: 0;
.el-button {
margin-left: 5px;
}
}
&__dialog {
.el-dialog__header {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding: 12px 20px;
background-color: #409eff;
}
.el-dialog__close {
color: #fff;
font-size: 18px;
&:hover {
color: #ffddff;
}
}
.el-dialog__title {
color: #fff;
font-size: 18px;
}
.el-dialog__headerbtn {
top: 18px;
}
&--overflow {
max-height: 400px;
overflow: hidden;
overflow-y: auto;
}
}
}
\ No newline at end of file
.data-box {
$height: 100px;
$radius: 5px;
.item {
display: flex;
position: relative;
margin: 0 auto 10px auto;
width: 96%;
height: $height;
overflow: hidden;
border-radius: $radius;
box-sizing: border-box;
&:hover .item-text {
top: 0;
}
}
.item-icon {
width: 100px;
height: 100%;
color: #fff;
text-align: center;
line-height: 100px;
i {
font-size: 48px !important;
}
}
.item-info {
border: 1px solid #eee;
border-left: none;
background-color: #fff;
flex: 1;
display: flex;
justify-content: center;
flex-direction: column;
.title {
font-size: 30px;
line-height: 40px;
text-align: center;
}
.info {
color: #999;
font-size: 14px;
text-align: center;
}
}
}
\ No newline at end of file
.data-card {
$height: 340px;
.item {
position: relative;
margin: 0 auto;
margin-bottom: 50px;
width: 230px;
height: $height;
overflow: hidden;
border-radius: 5px;
border-color: #fff;
border-width: 1px;
border-style: solid;
&:hover .item-text {
top: 0;
}
}
.item-img {
width: 100%;
background: red;
border-radius: 5px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.item-text {
position: absolute;
top: 150px;
padding: 20px 15px;
width: 100%;
height: $height;
overflow: auto;
box-sizing: border-box;
border-radius: 5px;
border-top-left-radius: 0;
border-top-right-radius: 0;
opacity: 0.9;
transition: top 0.4s;
&>p {
font-size: 12px;
line-height: 25px;
text-indent: 2em;
}
}
}
\ No newline at end of file
.avue-data-display {
.item {
display: flex;
align-items: center;
flex-direction: column;
margin: 5px 0;
text-align: center;
}
.count {
margin: 8px 0;
font-weight: bold;
font-size: 32px;
color: #15A0FF;
}
.title {
color: #999;
}
.splitLine {
display: block;
margin: 0 auto;
width: 24px;
height: 1px;
background: #9B9B9B;
}
}
\ No newline at end of file
.data-icons {
.item {
display: flex;
align-items: center;
justify-content: center;
width: 90%;
margin: 0 auto;
}
.item-icon {
margin-top: 3px;
margin-right: 8px;
&>i {
font-size: 46px !important;
}
}
.item-info {
text-align: center;
&>span {
display: block;
color: #999;
font-size: 12px;
}
.count {
font-size: 20px;
line-height: 25px;
}
}
.item--easy {
flex-direction: column;
&>.item-icon {
margin: 0;
}
&>.item-info {
margin-top: -15px;
&>span {
font-size: 14px;
}
}
}
}
\ No newline at end of file
.data-tabs {
.item {
position: relative;
margin: 15px;
padding: 12px;
height: 160px;
border-radius: 4px;
box-sizing: border-box;
overflow: hidden;
color: #fff;
}
.item-header {
position: relative;
&>p {
color: #fff;
margin: 0px;
font-size: 14px;
}
&>span {
position: absolute;
right: 0px;
top: 0px;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
background: rgba(255, 255, 255, 0.3);
}
}
.item-body {
&>h2 {
color: #fff;
margin: 0;
font-size: 32px;
line-height: 60px;
}
}
.item-footer {
padding-top: 8px;
line-height: 20px;
&>span {
font-size: 10px;
}
&>p {
color: #fff;
margin: 0px;
font-size: 12px;
}
}
.item-tip {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
width: 80px;
height: 80px;
bottom: 10px;
right: 10px;
border: 2px solid #fff;
border-radius: 100%;
font-size: 48px;
transform: rotate(-40deg);
opacity: 0.1;
}
}
\ No newline at end of file
.avue-date-select {
display: flex;
align-items: center;
&__radio {
.el-radio-button:last-child .el-radio-button__inner {
border-radius: 0;
border-right: 0;
}
}
&__date {
width: 300px;
.el-date-editor {
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
}
}
}
\ No newline at end of file
.el-select,
.el-date-editor.el-input,
.el-date-editor.el-input__inner,
.el-cascader,
.avue-input-number {
width: 100% !important;
}
.el-input__inner {
height: 38px;
line-height: 38px;
}
.el-tooltip__popper {
max-width: 60%;
}
\ No newline at end of file
.avue-form-detail {
&__item {
padding: 20px 0 20px 0;
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: none;
}
}
&__icon {
margin-right: 10px;
font-size: 20px;
}
&__header {
display: flex;
align-items: center;
margin-bottom: 15px;
}
&__title {
font-size: 16px;
font-weight: 500;
color: rgba(0, 0, 0, 0.85);
}
&__box {
margin-bottom: 20px;
font-size: 14px;
}
&__label {
margin-right: 10px;
line-height: 20px;
color: rgba(0, 0, 0, 0.85);
&--center {
text-align: center;
}
&--left {
text-align: left;
}
&--right {
text-align: right;
}
}
&__content {
line-height: 22px;
width: 100%;
color: rgba(0, 0, 0, 0.65);
}
}
\ No newline at end of file
.avue-form-steps {
&--vertical {
width: 100%;
display: flex;
}
&__steps {
width: 230px;
}
&__contail {
flex: 1;
}
&__form {
margin: 0 auto;
}
}
\ No newline at end of file
.avue-form {
padding: 8px 10px;
&__menu {
width: 100%;
&--center {
text-align: center;
}
&--left {
text-align: left;
}
&--right {
text-align: right;
}
}
&__group {
height: auto;
overflow: hidden;
.el-col {
position: relative;
}
}
&__row {
&--block {
width: 100%;
height: auto;
overflow: hidden;
}
&--cursor {
cursor: pointer;
}
}
&__option {
position: absolute;
right: 0;
top: -10px;
z-index: 999;
i {
color: #666;
}
i+i {
margin-left: 10px;
}
}
}
\ No newline at end of file
@import './common.scss';
@import './element-ui.scss';
@import './crud.scss';
@import './crud-upload.scss';
@import './table-tree.scss';
@import './form.scss';
@import './form-steps.scss';
@import './form-detail.scss';
@import './data-display.scss';
@import './data-card.scss';
@import './data-tabs.scss';
@import './data-icons.scss';
@import './data-box.scss';
@import './date-select.scss';
\ No newline at end of file
$color-blue: #2196f3;
$space-width: 18px;
.avue-tree-table {
.ms-tree-space {
position: relative;
top: 1px;
display: inline-block;
font-style: normal;
font-weight: 400;
line-height: 1;
width: $space-width;
height: 14px;
&::before {
content: "";
}
}
.processContainer {
width: 100%;
height: 100%;
}
table td {
line-height: 26px;
}
.tree-ctrl {
position: relative;
cursor: pointer;
color: $color-blue;
margin-left: -$space-width;
}
@keyframes treeTableShow {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes treeTableShow {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
\ No newline at end of file
/**
* Create a basic component with common options
*/
import bem from '../mixins/bem';
const install = function(Vue) {
Vue.component(this.name, this);
};
export default function(sfc) {
sfc.name = 'avue-' + sfc.name;
sfc.install = sfc.install || install;
sfc.mixins = sfc.mixins || [];
sfc.mixins.push(bem);
return sfc;
}
\ No newline at end of file
/**
* Create a component with common options
*/
import createBasic from './create-basic';
export default function(sfc) {
return createBasic(sfc);
}
\ No newline at end of file
export const dateFtt = (fmt, date) => { // author: meizz
var o = {
'M+': date.getMonth() + 1, // 月份
'd+': date.getDate(), // 日
'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
'S': date.getMilliseconds() // 毫秒
};
if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); }
for (var k in o) {
if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))); }
}
return fmt;
};
export const GetDateStr = (AddDayCount) => {
var dd = new Date();
dd.setDate(dd.getDate() + AddDayCount); // 获取AddDayCount天后的日期
var y = dd.getFullYear();
var m = (dd.getMonth() + 1) < 10 ? '0' + (dd.getMonth() + 1) : (dd.getMonth() + 1); // 获取当前月份的日期,不足10补0
var d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate(); // 获取当前几号,不足10补0
return y + '-' + m + '-' + d;
};
import {
validatenull
} from './validate';
export const getObjType = obj => {
var toString = Object.prototype.toString;
var map = {
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regExp',
'[object Undefined]': 'undefined',
'[object Null]': 'null',
'[object Object]': 'object'
};
if (obj instanceof Element) {
return 'element';
}
return map[toString.call(obj)];
};
/**
* 对象深拷贝
*/
export const deepClone = data => {
var type = getObjType(data);
var obj;
if (type === 'array') {
obj = [];
} else if (type === 'object') {
obj = {};
} else {
//不再具有下一层次
return data;
}
if (type === 'array') {
for (var i = 0, len = data.length; i < len; i++) {
obj.push(deepClone(data[i]));
}
} else if (type === 'object') {
for (var key in data) {
obj[key] = deepClone(data[key]);
}
}
return obj;
};
/**
* 根据字典的value显示label
*/
export const findByvalue = (dic, value, props) => {
props = props || {};
const labelKey = props.label || 'label';
const valueKey = props.value || 'value';
const childrenKey = props.children || 'children';
let result = '';
if (validatenull(dic)) return value;
if (typeof(value) === 'string' || typeof(value) === 'number' || typeof(value) === 'boolean') {
let index = 0;
index = findArray(dic, value, valueKey);
if (index !== -1) {
result = (dic[index][labelKey]);
} else {
result = value;
}
} else if (value instanceof Array && dic[0][childrenKey]) {
let index = 0;
let count = 0;
while (count < value.length) {
index = findArray(dic, value[count]);
if (!validatenull(dic[index])) {
result = result + dic[index][labelKey] + '/';
dic = dic[index][childrenKey];
}
count++;
}
if (result.length > 0) {
result = result.substr(0, result.length - 1);
}
} else if (value instanceof Array) {
result = [];
let index = 0;
value.forEach(ele => {
index = findArray(dic, ele);
if (index !== -1) {
result.push(dic[index][labelKey]);
} else {
result.push(ele);
}
});
result = result.toString();
}
return result;
};
/**
* 根据字典的value查找对应的index
*/
export const findArray = (dic, value, valueKey) => {
valueKey = valueKey || 'value';
for (let i = 0; i < dic.length; i++) {
if (dic[i][valueKey] === value) {
return i;
}
}
return -1;
};
/**
* 获取字典
*/
export const setDic = (dicData, DIC) => {
return (typeof(dicData) === 'string') ? DIC : dicData;
};
/**
* 设置px
*/
export const setPx = (val, defval) => {
if (validatenull(val)) {
val = defval;
}
val = val + '';
if (val.indexOf('%') === -1) {
val = val + 'px';
}
return val;
};
/**
* 表格初始化值
*/
export const formInitVal = (list) => {
let tableForm = {};
let searchForm = {};
list.forEach(ele => {
if (
ele.type === 'checkbox' ||
ele.type === 'cascader' ||
ele.type === 'dates' ||
(ele.type === 'upload' && ele.listType !== 'picture-img') ||
ele.multiple ||
ele.range || ele.dataType === 'array'
) {
tableForm[ele.prop] = [];
if (ele.search) searchForm[ele.prop] = [];
} else if (['number', 'rate', 'silder'].includes(ele.type) || ele.dataType === 'number') {
tableForm[ele.prop] = 0;
if (ele.search) {
searchForm[ele.prop] = 0;
}
} else {
tableForm[ele.prop] = '';
if (ele.search) {
searchForm[ele.prop] = '';
}
}
//表单默认值设置
if (!validatenull(ele.valueDefault)) tableForm[ele.prop] = ele.valueDefault;
//搜索表单默认值设置
if (!validatenull(ele.searchDefault)) searchForm[ele.prop] = ele.searchDefault;
});
return {
tableForm,
searchForm
};
};
export const getType = (column) => {
const type = column.type
const more = column.more || false;
if (more) {
if (type === 'date') {
return 'daterange';
} else if (type === 'datetime') {
return 'datetimerange';
} else if (type === 'time') {
return 'timerange';
} else {
return type;
}
}
return type;
};
/**
* 搜索框获取动态组件
*/
export const getSearchType = (type) => {
if (['select', 'radio', 'checkbox'].includes(type)) {
return 'crudSelect';
} else if (['time', 'timerange'].includes(type)) {
return 'crudTime';
} else if (['dates', 'date', 'datetime', 'datetimerange', 'daterange', 'week', 'month', 'year'].includes(type)) {
return 'crudDate';
} else if (['cascader'].includes(type)) {
return 'crudCascader';
} else if (['number'].includes(type)) {
return 'crudInputNumber';
} else {
return 'crudInput';
}
};
/**
* 动态获取组件
*/
export const getComponent = ({ type, component }) => {
if (!validatenull(component)) {
return component;
} else if (type === 'select') {
return 'crudSelect';
} else if (type === 'radio') {
return 'crudRadio';
} else if (type === 'checkbox') {
return 'crudCheckbox';
} else if (['time', 'timerange'].includes(type)) {
return 'crudTime';
} else if (['dates', 'date', 'datetime', 'datetimerange', 'daterange', 'week', 'month', 'year'].includes(type)) {
return 'crudDate';
} else if (type === 'cascader') {
return 'crudCascader';
} else if (type === 'number') {
return 'crudInputNumber';
} else if (type === 'password') {
return 'crudInput';
} else if (type === 'switch') {
return 'crudSwitch';
} else if (type === 'rate') {
return 'crudRate';
} else if (type === 'upload') {
return 'crudUpload';
} else if (type === 'silder') {
return 'crudSilder';
} else {
return 'crudInput';
}
};
export const vaildData = (val, dafult) => {
if (typeof val === 'boolean') {
return val;
}
return !validatenull(val) ? val : dafult;
};
\ No newline at end of file
/**
* 判断是否为空
*/
export function validatenull(val) {
if (typeof val === 'boolean') {
return false;
}
if (typeof val === 'number') {
return false;
}
if (val instanceof Array) {
if (val.length === 0) return true;
} else if (val instanceof Object) {
if (JSON.stringify(val) === '{}') return true;
} else {
if (val === 'null' || val == null || val === 'undefined' || val === undefined || val === '') return true;
return false;
}
return false;
}
......@@ -5,6 +5,7 @@
*/
// 引入axios以及element ui中的loading和message组件
import axios from 'axios'
import router from '../router/router'
import store from '../store'
import { getToken } from '@/util/auth'
import NProgress from 'nprogress' // progress bar
......@@ -43,6 +44,9 @@ axios.interceptors.response.use(data => {
message: errorCode[code] || errorCode['default'],
type: 'error'
})
store.dispatch("LogOut").then(() => {
router.push({ path: "/login" });
});
return Promise.reject(new Error(error))
})
......
......@@ -100,6 +100,8 @@ import { fetchList, getObj, addObj, putObj, delObj } from "@/api/user";
import { deptRoleList, fetchDeptTree } from "@/api/role";
import { tableOption } from '@/const/crud/user';
import { mapGetters } from "vuex";
import { constants } from 'fs';
import { connect } from 'tls';
export default {
name: "table_user",
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment